📜 ⬆️ ⬇️

Autoconfiguration of network interfaces in Debian GNU / Linux

I decided to talk about solutions to a fairly common problem for owners of mobile devices. The problem is that laptops are often connected to a fairly large number of different networks in which there is not always a DHCP server, or the DHCP server "gives" not all the necessary settings, or it gives the wrong ones.

Auto-raise interface


Auto-elevation of the interface is a fairly convenient thing, since it eliminates the need to manually raise and lower the interface each time (although I know people who prefer manual elevation of interfaces). In most cases, for these purposes you can use the wonderful program ifplugd.

Setting up ifplugd is not particularly difficult by itself, but at least Debian has the option to specify in the /etc/default/ifplugd . It is worth paying attention to the -d option - the time between determining the disconnection of the data transfer medium (cable) and interface deconfiguration, perhaps, it makes sense to increase it, since it is very unpleasant when the connections are broken due to a randomly pulled out cable. The option -u , on the contrary, can be set to a small value - raising the interface when a cable appears is almost never harmful.

Theoretically, ifplugd can work with disconnected adapters (parameter HOTPLUG_INTERFACES in the configuration file), but in practice I could not get it to work, because it was done via udev. In total, I used three Wi-Fi adapters, one of them was connected as a PC Card (PCMCIA), the other via USB, and later a built-in MiniPCI plug-in appeared. Accordingly, in /etc/udev/rules.d/80-LOCAL-wlan-start.rules rules were gradually added:
 # WLAN adapters SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="wlan*", RUN+="/etc/network/wlan-up $env{INTERFACE}" SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="1", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/etc/network/wlan-up wlan2" SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="0", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/sbin/ifdown wlan2" SUBSYSTEM=="rfkill", ACTION=="change", ENV{RFKILL_STATE}=="2", ENV{RFKILL_NAME}=="phy0", ENV{RFKILL_TYPE}=="wlan", RUN+="/sbin/ifdown wlan2" 

In this file, the first line after the comment is executed when an external adapter is connected. The rest of the lines work when the rfkill event is received, which means that the state of the on-board Wi-Fi switch changes. The parameter values ​​here are for the b43 driver, they may differ for other drivers. Unfortunately, it was not possible to figure out how not to specify the interface name manually.
Contents of the /etc/network/wlan-up file:
 #!/bin/sh export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" if=$1 logger -s -t wlan "Bringing up $if" ifconfig $if up poweroff=$(iwconfig $if|grep Tx-Power=off|wc -l) if [ $poweroff -ne 0 ] ; then ifconfig $if down exit fi ifup --force $if 2>&1 | logger -s -t wlan 

Setting the PATH variable is necessary, since this variable is not set when invoking a script from udev, so many things start to work completely differently.
')
The /etc/network/wlan-up was originally a rather complicated bash script that searched for networks and attempted to log in, but was greatly simplified after I accidentally stumbled upon a guessnet package, which will be discussed below .

Network autoconfiguration


After the interface is actually raised, two problems arise. The first is in the case of Wi-Fi to determine which of the networks we know is available. The second is to configure this network directly if for some reason DHCP cannot be configured.

Debian has a great guessnet package that makes it quite easy to solve both problems without resorting to kilometer-long quizzes on bash, grep, and sed, which I had to use before I found it.

guessnet takes advantage of the network configuration mechanism in Debian /etc/network/interfaces , such as logical interfaces and the mapping keyword. Logical interfaces, as their name suggests, are nothing more than network configuration profiles, which can be applied when raising an interface like this: ifup eth0=home . The mapping keyword represents the ability to write a script that maps a physical interface to a logical one.

All you need to connect guessnet to /etc/network/interfaces is to add a ( stanza ) mapping section for the corresponding interface:
 mapping eth1 script guessnet-ifupdown # map default: dhcp # map debug: true # map verbose: true map syslog: true 

The map keyword acquires a new meaning: it is used to pass parameters to guessnet (you can read about the original meaning on the interfaces (5) page or in the ifupdown documentation). But more about that later.

The profiles themselves are defined in exactly the same way as any other interfaces, with only one difference: the name of the logical interface does not coincide with the name of the physical (although it may contain it as a substring in itself):
 iface no-link inet manual test missing-cable pre-up echo No link present. pre-up false iface dhcp inet dhcp iface eth-home inet dhcp post-up route del default 2>&1 >/dev/null || true post-up pon dsl-eth-vpn post-up ifup ipv6-vps pre-down ifdown ipv6-vps pre-down poff dsl-eth-vpn test peer address 192.168.1.1 mac 00:19:CB:48:02:2A source 192.168.1.5 iface eth-lab inet static address 192.168.23.238 netmask 255.255.255.224 gateway 192.168.23.225 test peer address 192.168.23.225 

As you can see, the test keyword is present in the settings of each of these logical interfaces. The very flexible architecture of the ifupdown program allows third-party programs (such as guessnet) to intercept their processing or just ignore them (although guessnet specifically works differently - it simply reassembles the file again). The word test allows you to specify the condition by which a particular configuration will be selected.

It is recommended that no-link logical interface be created specifically so that guessnet does not attempt to run other tests in the absence of a cable.

The dhcp configuration accepts all DHCP settings without replacing anything. It can be useful to set it as the default configuration - most networks still have at least some DHCP server, listening to which instructions you can at least get a basic set of settings.

The eth-lab configuration is used on a network with a DHCP server that ignores requests from unfamiliar clients. Therefore, arping of the gateway on this network is done - such a request will work only if both nodes are in the same physical network segment.

Finally, the eth-home configuration simultaneously uses the settings from the DHCP server, but additionally raises the IPv6 tunnel and also removes the IPv4 default gateway, effectively turning the machine into an IPv6-only node. Another feature: in order to gain access to the “other end” of the IPv6 tunnel, an ADSL connection is used, which is kindly provided by the Zyxel P-660 series modem. Modems of this brand have one interesting whim: they ignore anonymous ARP requests (namely, guessnet sends such messages by default). To avoid this, an address is registered explicitly, which is recorded in the field “source” of the packet. In addition, the modem's MAC address is explicitly specified here.

In addition, as I mentioned, guessnet can detect Wi-Fi networks. For this, the test keyword supports the wireless option:
 iface wifi-MTS.BY inet dhcp test wireless essid MTS.BY wireless-essid MTS.BY wireless-key off 

It should be taken into account that quite often guessnet cannot correctly determine the “cable presence” for Wi-Fi (which is understandable), which is why you need to add the line map !no-link in the mapping for the Wi-Fi interface.

More details on guessnet capabilities can be found on the guessnet(8) page guessnet(8) . Also, the package is attached a good documentation with examples of use. In principle, nothing prevents the use of guessnet in other distributions - there is a mode of operation “untethered” from the Debian-specific ifupdown package.

Couple of strokes


One of the networks in which I quite often have to go has a DHCP server that is configured so that requests for updating the address are sent twice a minute. At the same time, the DNS settings that are not suitable for me are distributed through DHCP and overwrite my /etc/resolv.conf once every half a minute. The solution to this problem can be the following script (for dhclient3):
 case $reason in RENEW) make_resolv_conf () { true } ;; *) return ;; esac 

It should be /etc/dhcp3/dhclient-enter-hooks.d in /etc/dhcp3/dhclient-enter-hooks.d under any name.

Of course, such a solution is a rather rough "hack", so it is possible that installing the resolvconf package and "twisting" the priorities of the interfaces will be preferable.

In addition, it is recommended to install the ifupdown-extra package, it has several useful additions to the standard ifupdown features.

Here, perhaps, everything that I wanted to tell. Thanks for attention.

Source: https://habr.com/ru/post/121216/


All Articles