Konfiguracja statycznego adresu IP w Debianie i Ubuntu

Opublikowano 11 min czytania

Stałe adresy IPv4 i IPv6 na Ubuntu 24.04, Ubuntu 22.04, Debianie 13 i Debianie 12: netplan, ifupdown oraz systemd-networkd w porównaniu, ze strategią wycofania zmian i dodatkowymi adresami IP.

Cztery dane, bez których nie warto zaczynać

Statyczny adres wpisuje się w kilkanaście sekund. Powód, dla którego mimo to tyle serwerów milczy po restarcie, prawie nigdy nie leży w składni. Leży w tym, że jedną z czterech podstawowych wartości ktoś zgadł, zamiast ją odczytać: nazwę interfejsu, adres wraz z długością prefiksu, bramę i serwery nazw. Odczytaj te wartości na działającej maszynie, dopóki jest jeszcze osiągalna.

ip -brief address show
ip -4 route show
ip -6 route show
cat /etc/resolv.conf

Pierwszy wiersz podaje nazwę interfejsu. Na serwerach wirtualnych nazywa się on, zależnie od platformy, ens3, enp1s0 albo eth0, na bare metalu często eno1. Nazwę przepisz, nie zgaduj jej. Literówka w tym miejscu tworzy konfigurację nienaganną pod względem składni, która po prostu nie pasuje do żadnej istniejącej karty sieciowej.

Szczególnie ważna jest długość prefiksu. Wielu dostawców kieruje na serwer pojedynczy adres IPv4 z maską /32, a brama leży wtedy poza własną podsiecią. Inni przydzielają klasyczne sieci /24. Który przypadek zachodzi, zdradzi faktycznie używana ścieżka:

ip route get 1.1.1.1

Potem wykonaj kopię zapasową. Kosztuje dziesięć sekund i stanowi różnicę między spokojnym wycofaniem zmian a zgłoszeniem do wsparcia.

cp -a /etc/netplan /root/netplan.bak
cp -a /etc/network/interfaces /root/interfaces.bak

Który system steruje teraz twoją siecią?

Debian i Ubuntu używają różnych narzędzi, a najczęstsza całkowita awaria bierze się stąd, że dwa z nich konfigurują tę samą kartę jednocześnie. Najpierw zrób sobie porządek w obrazie sytuacji:

ls -l /etc/netplan/
ls -l /etc/network/interfaces /etc/network/interfaces.d/
ls -l /etc/systemd/network/

Reguła kciuka dla czterech aktualnych wersji: Ubuntu 24.04 i Ubuntu 22.04 konfiguruje się przez netplan, który w tle steruje systemd-networkd. Debian 13 i Debian 12 po standardowej instalacji korzystają z ifupdown i pliku /etc/network/interfaces. systemd-networkd jest w Debianie obecny, ale nieaktywny, a netplan da się doinstalować, tylko że nie jest to tam droga przewidziana.

W obrazach chmurowych dochodzi kolejna warstwa: cloud-init przy pierwszym starcie zapisuje własny plik, zwykle /etc/netplan/50-cloud-init.yaml, a w Debianie blok w /etc/network/interfaces.d/. Kto edytuje ten plik, nie hamując wcześniej cloud-init, po następnym restarcie zastanie z powrotem starą konfigurację.

Ubuntu 24.04 i 22.04: statyczny adres w netplanie

netplan czyta wszystkie pliki w /etc/netplan/ w kolejności alfabetycznej i tłumaczy je na konfigurację dla systemd-networkd. Nie zakładaj drugiego pliku z tym samym interfejsem, tylko edytuj istniejący albo porządnie wyłącz stary. Kompletna konfiguracja z IPv4 i IPv6 wygląda tak:

network:
  version: 2
  renderer: networkd
  ethernets:
    ens3:
      dhcp4: false
      dhcp6: false
      accept-ra: false
      addresses:
        - 203.0.113.10/24
        - "2001:db8:1234::2/64"
      routes:
        - to: default
          via: 203.0.113.1
        - to: default
          via: "2001:db8:1234::1"
      nameservers:
        addresses: [9.9.9.9, 149.112.112.112, 2620:fe::fe]

Trzy rzeczy zasługują tu na osobne wyjaśnienie.

Po pierwsze, trasy domyślne stoją pod kluczem routes, a nie już pod gateway4 czy gateway6. Te dwa klucze są wycofane od netplana 0.103. Na Ubuntu 22.04 i 24.04 jeszcze działają, ale każde wywołanie kwitują komunikatem `gateway4` has been deprecated, use default routes instead. Kto pisze konfigurację od nowa, pisze trasy.

Po drugie, accept-ra: false wyłącza automatyczną konfigurację IPv6. Jeśli zostawisz ją włączoną, a równocześnie przydzielisz stały adres, karta dostanie dwa adresy i dwie trasy domyślne, a o tym, która wygra, zdecyduje metryka, nie twój zamiar.

Po trzecie, uprawnienia do pliku. Od netplana 0.106 każde wywołanie ostrzega, gdy plik YAML jest czytelny dla innych użytkowników: Permissions for /etc/netplan/01-static.yaml are too open. Netplan configuration should NOT be accessible by others. To nie kosmetyka, bo w takich plikach lądują też klucze WLAN i dane tuneli.

chmod 600 /etc/netplan/*.yaml

Gdy brama leży poza własną podsiecią

Przy pojedynczo routowanym adresie z maską /32 kernel nie zna bezpośredniej drogi do bramy i odrzuca trasę. W journalu widnieje wtedy Could not set route: Network is unreachable, a przy ręcznej próbie z ip route add odpowiedź brzmi RTNETLINK answers: Network is unreachable. Rozwiązanie nazywa się on-link:

      addresses:
        - 203.0.113.10/32
      routes:
        - to: default
          via: 192.0.2.1
          on-link: true

W IPv6 przypadek szczególny jest regułą: wiele sieci podaje jako bramę adres link-local fe80::1. Ponieważ netplan zawsze przypisuje trasy do konkretnego interfejsu, wystarczy via: "fe80::1" w bloku danej karty.

Wyciszenie cloud-init

Jeśli w katalogu leży plik 50-cloud-init.yaml, dołóż dodatkowo blokadę, inaczej twoja praca zostanie nadpisana przy następnym starcie:

echo 'network: {config: disabled}' > /etc/cloud/cloud.cfg.d/99-disable-network-config.cfg

netplan try: polecenie, które cię nie odetnie

Kolejność brzmi: sprawdź, przetestuj, utrwal. netplan generate tłumaczy pliki YAML, niczego nie aktywując, i natychmiast zgłasza błędy składni. Dopiero potem następuje właściwy test.

netplan generate
netplan try --timeout 120
netplan apply

netplan try stosuje nową konfigurację i automatycznie przywraca starą, jeśli w wyznaczonym czasie nie naciśniesz klawisza Enter. Wartość domyślna wynosi 120 sekund. Dokładnie dlatego na zdalnym serwerze nigdy nie zaczyna się od netplan apply: literówka w adresie bramy kończy sesję SSH, a bez warstwy awaryjnej sprawa kończy się przy konsoli albo reinstalacją.

Nie polegaj ślepo na tym wycofaniu. Udokumentowane są przypadki, w których netplan try po upływie czasu nie przywrócił połączenia, zwłaszcza przy edycji pliku wygenerowanego przez cloud-init. Po każdym wycofaniu sprawdzaj więc, czy plik na dysku faktycznie wrócił do poprzedniego stanu.

Na wszystko, czego netplan try nie obejmuje (a także dla Debiana z ifupdown, gdzie tego polecenia w ogóle nie ma), sprawdza się drugi pas bezpieczeństwa: zadanie ratunkowe, które odtworzy kopię zapasową, jeśli nie zgłosisz się na czas.

nohup sh -c 'sleep 300; cp -a /root/netplan.bak/. /etc/netplan/; netplan apply' >/dev/null 2>&1 &

Zapamiętaj numer procesu z wypisanej odpowiedzi. Jeśli wszystko działa, zakończ zadanie poleceniem kill. Jeśli już się nie zalogujesz, naprawi się ono samo w pięć minut. Pracuj dodatkowo w tmux albo screen, żeby zrywająca się sesja SSH nie pociągnęła za sobą twojego edytora w środku przełączania.

Na serwerach root KVM ostatnią instancją pozostaje konsola w panelu klienta, przez którą wejdziesz do systemu także bez działającej sieci. Przy maszynach dedykowanych droga powrotna jest wyraźnie bardziej pracochłonna, więc tam rutyna ostrożności liczy się podwójnie.

Debian 13 i 12 z plikiem /etc/network/interfaces

Po standardowej instalacji siecią steruje ifupdown. Konfiguracja jest zorientowana wierszowo i zna osobne bloki dla każdej rodziny adresów:

auto lo
iface lo inet loopback

auto ens3
iface ens3 inet static
    address 203.0.113.10/24
    gateway 203.0.113.1

iface ens3 inet6 static
    address 2001:db8:1234::2/64
    gateway 2001:db8:1234::1
    accept_ra 0

Wpis auto ens3 obowiązuje dla obu bloków, drugiego wiersza auto nie potrzebujesz. Jeśli brama leży poza podsiecią, pomaga ta sama idea co w netplanie, tylko sformułowana ręcznie:

iface ens3 inet static
    address 203.0.113.10/32
    post-up ip route add 192.0.2.1 dev ens3
    post-up ip route add default via 192.0.2.1
    pre-down ip route del default via 192.0.2.1

Największa pułapka w Debianie to nie składnia, tylko aktywacja. systemctl restart networking na chwilę wyłącza kartę, a jeśli nowa konfiguracja nie zadziała, sesji już nie ma. ifdown ens3 && ifup ens3 jest jeszcze bardziej ryzykowne, bo ifup nigdy się nie wykona, gdy połączenie zerwie się już przy ifdown. Załóż więc wcześniej opisane wyżej zadanie ratunkowe, a dopiero potem wywołaj:

systemctl restart networking
systemctl status networking

Dwa komunikaty spotkasz tu regularnie. ifup: interface ens3 already configured oznacza, że ifupdown wciąż księguje kartę jako aktywną, choć być może już taka nie jest; stan zapisany jest w /run/network/ifstate. Z kolei Job for networking.service failed because the control process exited with error code to tylko opakowanie, a właściwa przyczyna stoi w journalctl -xeu networking, najczęściej jest to podwójnie przydzielona trasa domyślna z RTNETLINK answers: File exists.

DNS w ifupdown

Nasuwający się wiersz dns-nameservers 9.9.9.9 w pliku zadziała tylko wtedy, gdy zainstalowany jest pośrednik, który przeniesie go do /etc/resolv.conf, klasycznie pakiet resolvconf. Bez tego pośrednika wpis pozostaje bez skutku, a wychodzi to na jaw dopiero wtedy, gdy nazwy przestają się rozwiązywać: Temporary failure in name resolution. Kto nie chce nic doinstalowywać, utrzymuje /etc/resolv.conf bezpośrednio i sprawdza poleceniem ls -l /etc/resolv.conf, czy plik jest dowiązaniem symbolicznym, czyli czy zarządza nim inna usługa.

Debian na systemd-networkd

Kto na serwerze z Debianem i tak korzysta z narzędzi systemd albo zarządza wieloma interfejsami i tunelami, wyjdzie spójniej na systemd-networkd. Przesiadka składa się z trzech kroków: załóż konfigurację, włącz nową usługę, wyłącz starą.

[Match]
Name=ens3

[Network]
Address=203.0.113.10/24
Address=2001:db8:1234::2/64
Gateway=203.0.113.1
Gateway=2001:db8:1234::1
DNS=9.9.9.9
DNS=2620:fe::fe
IPv6AcceptRA=no

Ten plik należy zapisać jako /etc/systemd/network/10-ens3.network. Dla bramy spoza podsieci dopisz osobny blok trasy:

[Route]
Gateway=192.0.2.1
GatewayOnLink=yes

Potem przełączenie, najlepiej znów z zadaniem ratunkowym w odwodzie:

systemctl enable --now systemd-networkd
systemctl disable networking
networkctl status ens3

Wyjście polecenia networkctl status to najuczciwsza informacja zwrotna, jaką ten temat ma do zaoferowania. Jeśli widnieje tam State: routable (configured), usługa przyjęła plik i go zrealizowała. Jeśli stoi tam configuring albo degraded, próbowała i jej się nie udało, niezależnie od tego, że polecenie startu wróciło bez błędu.

Część DNS jest w Debianie osobnym tematem: systemd-networkd wpisuje serwery nazw do rozwiązywania nazw tylko wtedy, gdy działa systemd-resolved, a /etc/resolv.conf wskazuje na jego plik.

apt-cache policy systemd-resolved

To zapytanie zależy od wersji i myli w niepozorny sposób. Samodzielny pakiet systemd-resolved istnieje dopiero od Debiana 12 i Ubuntu 24.04, tam polecenie poda wersję. Na Ubuntu 22.04 usługa tkwi natomiast jeszcze w samym pakiecie systemd i polecenie wprawdzie kończy się bez błędu, ale nie wypisuje zupełnie nic. Instalacja kończy się wtedy komunikatem Unable to locate package systemd-resolved. Pusta odpowiedź nie znaczy więc, że brakuje resolvera, tylko że w tej wersji nie ma takiego pakietu. Na starszych systemach, jak Debian 11, jest dokładnie tak samo. W tych wersjach sprawdzaj zamiast tego:

apt-cache policy systemd
systemctl status systemd-resolved

Usługę włącza się poleceniem systemctl enable --now systemd-resolved, po czym typowe dowiązanie symboliczne wskazuje na /run/systemd/resolve/stub-resolv.conf. Kto tego nie chce, rezygnuje z systemd-resolved i wpisuje serwery nazw statycznie do /etc/resolv.conf. Czego robić nie należy: obu rzeczy po połowie.

Podpinanie dodatkowych adresów IP

Dodatkowe adresy to nie przypadek szczególny, tylko po prostu kolejny wpis. W netplanie rośnie lista:

      addresses:
        - 203.0.113.10/24
        - 203.0.113.11/24
        - 203.0.113.12/24
        - "2001:db8:1234::2/64"
        - "2001:db8:1234::3/64"

W systemd-networkd piszesz kilka wierszy Address= jeden pod drugim. W ifupdown uzupełniasz istniejącą definicję, zamiast zakładać drugą:

iface ens3 inet static
    address 203.0.113.10/24
    gateway 203.0.113.1
    post-up ip addr add 203.0.113.11/24 dev ens3
    post-up ip addr add 203.0.113.12/24 dev ens3
    pre-down ip addr del 203.0.113.11/24 dev ens3
    pre-down ip addr del 203.0.113.12/24 dev ens3

Stary zapis z ens3:0 nadal działa, ale jest reliktem z czasów sprzed narzędzia ip. Nie tworzy prawdziwych dodatkowych urządzeń, tylko etykiety, a w regułach firewalla sieje więcej zamętu, niż przynosi pożytku.

Przy dodatkowych adresach psują się zwykle trzy rzeczy. Po pierwsze, adres nie jest przypisany po stronie serwera; żadna konfiguracja systemu operacyjnego na świecie nie uruchomi adresu IP, który nie jest routowany na twój serwer, dlatego zajrzenie do panelu klienta to krok pierwszy, a nie ostatni. Po drugie, do drugiego adresu z tej samej sieci nie należy druga trasa domyślna; drugi wpis bramy domyślnej zafunduje ci RTNETLINK answers: File exists albo, co gorsza, zmienne ścieżki odpowiedzi. Po trzecie, w IPv6 niemal zawsze całe /64 jest routowane na serwer, możesz więc dowolnie wybierać z tej puli, ale jako skonfigurowany adres interfejsu naprawdę potrzebny jest tylko ten wskazany przez dostawcę.

Czy dodatkowy adres naprawdę wychodzi na zewnątrz, sprawdzisz celowo przez adres źródłowy:

ping -c 3 -I 203.0.113.11 1.1.1.1

Po czym poznasz, że konfiguracja naprawdę siedzi

To, że polecenie przeszło bez komunikatu o błędzie, mówi o stanie sieci niewiele. Te pięć sprawdzeń mówi coś konkretnego:

  1. Adres wisi na właściwej karcie: ip -brief address show pokazuje dokładnie żądane adresy i żadnych resztek starej konfiguracji.
  2. Droga na zewnątrz się zgadza, łącznie z adresem źródłowym: ip route get 1.1.1.1 podaje oczekiwaną bramę i oczekiwany src.
  3. IPv6 ma własną trasę domyślną: ip -6 route show default nie może być puste, inaczej wszystko po cichu idzie przez IPv4.
  4. Rozwiązywanie nazw działa niezależnie od osiągalności: getent hosts deb.debian.org zwraca adres, a nie samą ciszę.
  5. Jedynym prawdziwym testem jest restart. Dopiero po nim wiesz, czy konfiguracja pochodzi z pliku, czy jeszcze z pamięci RAM.

Na Ubuntu netplan status --all wypisuje dodatkowo zwięzłe podsumowanie, a przy systemd-networkd to samo robi networkctl status. Oba w razie wątpliwości pokażą, że adres wprawdzie stoi w pliku, ale nigdy nie został przejęty.

Komunikaty błędów dosłownie

KomunikatPrzyczyna i rozwiązanie
Invalid YAML at /etc/netplan/01-static.yaml line 6 column 8: did not find expected keyTabulator zamiast spacji albo przesunięte wcięcie. YAML nie dopuszcza tabulatorów, używaj dwóch spacji na poziom.
Error in network definition: unknown key 'gateway'W netplanie ten klucz nie nazywa się gateway. Utwórz wpis pod routesto: default.
`gateway4` has been deprecated, use default routes insteadTo tylko ostrzeżenie, konfiguracja nadal obowiązuje. Mimo to przestaw ją na routes.
Permissions for /etc/netplan/… are too openZastosuj chmod 600 na pliku YAML.
RTNETLINK answers: Network is unreachableBrama leży poza skonfigurowaną podsiecią. Ustaw on-link: true lub GatewayOnLink=yes albo popraw długość prefiksu.
RTNETLINK answers: File existsAdres albo trasa już istnieje, zwykle dlatego, że dwa systemy konfiguracji pracują równocześnie.
Error: Cannot find device "eth0"Karta nazywa się inaczej. Odczytaj nazwę poleceniem ip -brief link show.
Temporary failure in name resolutionRouting stoi, DNS nie. Sprawdź /etc/resolv.conf i ustal, która usługa zapisuje ten plik.
ifup: interface ens3 already configuredifupdown uważa kartę za aktywną. Sprawdź stan w /run/network/ifstate.

Cztery dystrybucje w bezpośrednim porównaniu

Debian 12Debian 13Ubuntu 22.04Ubuntu 24.04
Narzędzie domyślneifupdownifupdownnetplannetplan
Plik główny/etc/network/interfaces/etc/network/interfaces/etc/netplan/*.yaml/etc/netplan/*.yaml
Alternatywasystemd-networkdsystemd-networkdsystemd-networkd bezpośredniosystemd-networkd bezpośrednio
Test bez odcięcia sięwłasne zadanie ratunkowewłasne zadanie ratunkowenetplan trynetplan try
systemd-resolvedwłasny pakiet, nieaktywnywłasny pakiet, nieaktywnyczęść pakietu systemdwłasny pakiet, aktywny
Ostrzeżenie o uprawnieniach w netplanienie dotyczynie dotyczyod 0.106tak

Jeśli zaraz po konfiguracji sieci uruchamiasz firewalla, zwróć uwagę, że reguły dla nowego adresu i dla IPv6 obowiązują osobno. Jak to porządnie ustawić, opisuje nasz poradnik o UFW na Debianie i Ubuntu, a jak potem zabezpieczyć dostęp, przeczytasz we wpisie Zabezpieczanie serwera SSH.

Skrót na następny serwer

Wartości odczytać zamiast zgadywać, założyć kopię zapasową, napisać konfigurację, przetestować przez netplan try albo własne zadanie ratunkowe, utrwalić, zrestartować i dopiero potem odhaczyć. Kto trzyma się tej kolejności, traci w najgorszym razie pięć minut. Kto ją skraca, traci w najgorszym razie serwer, dopóki ktoś nie usiądzie przy konsoli.

Najczęstsze pytania

Dlaczego mój serwer po netplan apply nie jest już osiągalny?
Prawie zawsze nie zgadza się brama albo długość prefiksu nie pasuje do sieci. Dlatego na zdalnych systemach używaj najpierw netplan try: przywraca poprzednią konfigurację automatycznie po 120 sekundach, jeśli nikt nie naciśnie klawisza Enter. Jeśli już się stało, na serwerach root KVM pomoże konsola w panelu klienta.
Czy Debian 13 używa netplana?
Nie. Debian 13 po standardowej instalacji nadal konfiguruje sieć przez ifupdown i plik /etc/network/interfaces. netplan da się doinstalować z repozytoriów, ale w Debianie nie jest to droga przewidziana i dokłada dodatkowy krok tłumaczenia konfiguracji. Jako alternatywa blisko systemu sprawdza się systemd-networkd.
Co zastępuje gateway4 w netplanie?
Wpis pod routes z to: default oraz via: adres bramy. gateway4 i gateway6 są wycofane od netplana 0.103 i generują ostrzeżenie, że zamiast nich należy używać tras domyślnych. Na Ubuntu 22.04 i 24.04 stare klucze jeszcze działają, ale przy każdej przeróbce konfiguracji warto je wymienić.
Dlaczego moja /etc/resolv.conf jest wciąż nadpisywana?
Bo zarządza nią jakaś usługa: systemd-resolved, resolvconf albo cloud-init. Sprawdź poleceniem ls -l /etc/resolv.conf, czy plik jest dowiązaniem symbolicznym. Albo wpisujesz serwery nazw tam, gdzie spodziewa się ich dana usługa, albo wyłączasz usługę i utrzymujesz plik statycznie. Obie rzeczy po połowie kończą się awarią po restarcie.
Jak podpiąć dodatkowy adres IP?
W netplanie jako kolejny wpis na liście addresses, w systemd-networkd jako dodatkowy wiersz Address, w ifupdown przez post-up ip addr add. Ważne, żeby nie powstała druga trasa domyślna i żeby adres w ogóle był routowany na serwer po stronie dostawcy. Sprawdzasz to w panelu klienta, zanim zaczniesz szukać w systemie operacyjnym.
Moja brama leży poza podsiecią, co zrobić?
To normalne przy pojedynczo routowanych adresach z maską /32. W netplanie ustawiasz on-link: true przy trasie domyślnej, w systemd-networkd GatewayOnLink=yes w bloku trasy, a w ifupdown zakładasz najpierw przez post-up trasę do hosta bramy. Bez tego kroku kernel zgłasza Network is unreachable.

Debian Ubuntu netplan systemd-networkd sieć IPv6 administracja Linuksa serwer root