Morfitronik Security & Privacy

Konfiguracja interfejsów bond (bonding)

2016-01-02 14:07:13
Morfik

W artykule poświęconym konfiguracji sieci WiFi na debianie z wykorzystaniem narzędzia wpa_supplicant wspomniałem parę słów na temat interfejsu bond. Bonding umożliwia spięcie kilku interfejsów sieciowych, w tym przewodowych i bezprzewodowych, tak, że w przypadku awarii któregoś z nich, my nie tracimy połączenia z siecią. To rozwiązanie jest o tyle użyteczne, że w przypadku, gdy podepniemy przewód do gniazda RJ-45 w naszym laptopie, to komunikacja będzie odbywać się po kablu. Natomiast jeśli go odłączymy, to system automatycznie przejdzie na komunikację bezprzewodową. W tym wpisie spróbujemy zaprojektować sobie właśnie tego typu mechanizm.

Sterowniki i firmware do karty WiFi

By nasza karta WiFi działała bez problemów, musi być wspierana przez kernel linux’a. Dodatkowo, potrzebne nam będą odpowiednie pakiety z firmware. Na debianie, wszystko to co tyczy się firmware, jest ulokowane w pakietach zaczynających się od firmware- , przykładowo: firmware-atheros . Te pakiety możemy przejrzeć przy pomocy aptitude i doinstalować w zależności od posiadanej karty. Podobnie sprawa ma się w przypadku kart przewodowych.

Konfiguracja bonding’u w ifupdown

Sysvinit do konfiguracji sieci wykorzystuje pakiet ifupdown . Nie ma potrzeby jego instalacji, bo powinien już siedzieć w naszym systemie. Musimy jednak doinstalować inny pakiet: ifenslave . Bez niego nie będziemy w stanie skonfigurować interfejsu bond. Poza tymi pakietami, potrzebny nam będzie też moduł bonding , który musimy załadować wraz ze startem systemu. Dopisujemy zatem do pliku /etc/modules tę poniższą linijkę:

bonding

Konfiguracja interfejsu bond może być podana bezpośrednio przy ładowaniu modułu jako jego opcje. My jednak ten interfejs skonfigurujemy sobie przez plik /etc/network/interfaces . U mnie ten plik wygląda mniej więcej tak:

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

allow-bond0 wlp3s0b1
iface wlp3s0b1 inet manual
        bond-give-a-chance 5
        wpa-driver nl80211
        wpa-debug-level -1
        wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

auto bond0
iface bond0 inet dhcp
        bond-mode active-backup
        bond-miimon 100
        bond-downdelay 500
        bond-updelay 500
        bond-primary enp2s0
        bond-primary-reselect always
        bond-slaves enp2s0 wlp3s0b1
        bond-fail-over-mac none

Jak można wyżej zauważyć, nie mamy tam bloku odpowiedzialnego za konfigurację interfejsu przewodowego enp2s0 . A to z tego względu, że nie jest ona konieczna. Natomiast wymagany jest blok z konfiguracją interfejsu bezprzewodowego wlp3s0b1 . To w nim określamy kilka niezbędnych parametrów dla połączenia bezprzewodowego.

Wyjaśnienie opcji użytych w bloku iface wlp3s0b1 :

  • bond-give-a-chance – czeka określoną ilość sekund po podniesieniu interfejsu bezprzewodowego. Chodzi o opóźnienia związane z procesem logowania do sieci.
  • wpa-driver – sterownik dla karty WiFi
  • wpa-debug-level – obniża poziom logowania, tak by nie łapać komunikatów WPA: Group rekeying completed .
  • wpa-conf – plik konfiguracyjny z danymi do sieci WiFi.

Przydałoby się także kilka słów wyjaśnień dotyczących samego bloku iface bond0 . Każdy interfejs, nawet te wirtualne, muszą posiadać jakiś adres MAC. Jako, że pod interfejs bond są podpięte dwa fizyczne interfejsy, to każdy z nich ma inny adres MAC. Gdy opcja bond-fail-over-mac jest ustawiona na none , wszystkie zniewolone interfejsy oraz sam interfejs bond mają ustawiony dokładnie ten sam adres MAC. Adres MAC jest pobierany z pierwszego interfejsu określonego w bond-slaves . Zatem interfejs bond będzie miał taki sam MAC, co interfejs enp2s0. Każdy dodatkowy interfejs podczepiany pod interfejs bond, również będzie miał ten sam adres MAC. Chodzi generalnie to to, że standard IEEE 802.11 nie zezwala na transmisję pakietów o innym adresie MAC niż ten przypisany na sztywno bezprzewodowej karcie sieciowej. Dlatego też ten adres MAC musi pasować do tego, który jest ustawiony na interfejsie bond.

Opcje bond-downdelay oraz bond-updelay odpowiadają za czas (ms) podnoszenia i wyłączania interfejsów. Ważne jest, by ustawić je na wielokrotność wartości określonej przez parametr bond-miimon . Dalej mamy już tylko zdefiniowany główny interfejs na pozycji bond-primary oraz politykę jego wybierania w bond-primary-reselect . W przypadku, gdy bond-primary-reselect jest ustawiony na always , interfejs określony w bond-primary będzie ustawiany jako główny za każdym razem, gdy będzie dostępny. Takie zachowanie przydaje się w przypadku, gdy w bond-mode określimy active-backup . Ten tryb, jak nazwa sugeruje, ma na celu wykorzystanie tylko jednego interfejsu w tym samym czasie, ze wskazaniem na interfejs przewodowy enp2s0. Gdy zdarzy się taka sytuacja, że odłączymy przewód sieciowy, ten interfejs zostanie wyłączony i aktywowany będie ten bezprzewodowy. Natomiast w przypadku, gdy podłączymy kabel ponownie, pakiety znów będą lecieć przez ten interfejs przewodowy.

Jeśli chodzi zaś o konfigurację samej sieci WiFi, to została ona opisana w osobnym artykule (link we stepie) i nie będę poruszał tutaj tego tematu.

Konfiguracja bonding’u w systemd

Konfiguracja interfejsu bond w systemd przebiega nieco inaczej. Niemniej jednak, nic nie stoi na przeszkodzie, by wykorzystywać ten powyższy mechanizm. Jeśli jednak chcemy korzystać z rozwiązania natywnego dla systemd, to musimy poczynić szereg zmian.

Przede wszystkim musimy wyłączyć usługę networking.service i deaktywować ją, tak by nie była uruchamiana wraz ze startem systemu:

# systemctl stop networking.service
# systemctl disable networking.service

Jeśli mamy załadowany moduł bonding to musimy go wyładować:

# modprobe -r bonding

Odinstalowujemy także pakiet ifenslave oraz usuwamy linijkę z modułem z pliku /etc/modules . W ten sposób powrócimy do pozycji wyjściowej.

Włączamy szereg usług dostarczany z systemd:

# systemctl enable systemd-networkd.service systemd-resolved.service systemd-timesyncd.service systemd-networkd.socket

Dodajemy do pliku /etc/modprobe.d/modules.conf opcję dla modułu bonding , który będzie ładowany automatycznie za sprawą systemd:

options bonding max_bonds=0

Widoczny wyżej parametr max_bonds trzeba ustawić na 0 , a to z tego względu, że zapobiegnie to tworzeniu interfejsu bond tuż po załadowaniu modułu. Ten interfejs zostanie stworzony przez systemd. W przypadku, gdy nie dodamy tej opcji, będziemy mieć problem z konfiguracją interfejsu bond.

Tworzymy teraz kilka plików w katalogu /etc/systemd/network/ . Poniżej przykłady.

Plik konfiguracyjny dla urządzenia bond, 20-bond0.netdev :

[NetDev]
Description=Bonding interface bond0
Name=bond0
Kind=bond
MACAddress=3c:4a:92:00:4c:5b

[Bond]
Mode=balance-rr
MIIMonitorSec=1
UpDelaySec=3
DownDelaySec=3
PrimaryReselectPolicy=always
PacketsPerSlave=10

Plik konfiguracyjny dla interfejsu bond0, 40-bond.network :

[Match]
Name=bond0

[Network]
Description=Bonded network
DHCP=ipv4
LinkLocalAddressing=no
DNS=127.0.0.1
IPv6AcceptRouterAdvertisements=false

[DHCP]
UseDNS=false
UseNTP=false
UseMTU=false
SendHostname=true
UseHostname=false
UseDomains=true
UseRoutes=true
RequestBroadcast=true

Plik konfiguracyjny dla interfejsu przewodowego, 60-bonded.wired.network :

[Match]
Driver=r8169

[Network]
Description=Bonded wired interfaces
DHCP=no
IPv6AcceptRouterAdvertisements=false
Bond=bond0

Plik konfiguracyjny dla interfejsu bezprzewodowego, 60-bonded.wireless.network :

[Match]
Type=wlan

[Network]
Description=Bonded wireless interfaces
DHCP=no
IPv6AcceptRouterAdvertisements=false
Bond=bond0

Dopasowanie (sekcja [Match] ) można robić w oparciu o szereg parametrów. Powyżej mamy tylko kilka przykładów. Po pełną listę opcji odsyłam do dokumentacji systemd.

By całość nam jeszcze zadziałała, musimy napisać usługę, która uwierzytelni nas w sieci bezprzewodowej, do której mamy zamiar się podłączyć. Tworzymy zatem plik ` /etc/systemd/system/wpa_supplicant@.service` i dodajemy w nim tę poniższą treść:

[Unit]
Description=WPA supplicant (%i)
After=network.target systemd-networkd.service
Requires=systemd-networkd.service
Before=network-online.target multi-user.target
ConditionPathIsSymbolicLink=/sys/class/net/%i

[Service]
Type=forking
ExecStart=/sbin/wpa_supplicant -s -i %i -D nl80211,wext -q -c /etc/wpa_supplicant/wpa_supplicant.conf -B -P /run/wpa_supplicant.%i.pid
PIDFile=/run/wpa_supplicant.%i.pid

[Install]
WantedBy=multi-user.target

Dodajemy tę usługę do autostartu. Ważne jest by podać odpowiedni interfejs po @:

# systemctl enable wpa_supplicant@wlp3s0b1

Pozostało nam już tylko uruchomienie całego mechanizmu:

# systemctl start systemd-networkd
# systemctl start wpa_supplicant@wlp3s0b1

W logu zaś powinniśmy odnotować min. ten poniższy komunikat:

systemd-networkd[43223]: bond0: DHCPv4 address 192.168.1.150/24 via 192.168.1.1
systemd-networkd[43223]: bond0: Configured

Komentarze

Zawartość wpisu