Trwała zmiana nazwy hosta w Linuksie: hostnamectl, /etc/hosts i cloud-init

Opublikowano 15 min czytania

hostnamectl, /etc/hostname i /etc/hosts we wzajemnym powiązaniu, przełącznik przeciwko przywracaniu starej nazwy przez cloud-init oraz skutki dla sudo, serwera pocztowego i certyfikatów.

Serwer, który nazywa się debian, localhost albo vm-01, działa bez zarzutu. Nieprzyjemnie robi się dopiero wtedy, gdy trzy takie maszyny pracują jednocześnie, gdy nie da się już odróżnić od siebie wierszy w logach albo gdy dochodzi pierwszy serwer pocztowy, a druga strona zaczyna sprawdzać nazwę. Ten poradnik zmienia nazwę hosta tak, żeby przetrwała najbliższy restart, żeby sudo nie wpadało w timeout i żeby znały ją również usługi, które wczytują ją przy starcie.

To rozwinięcie kroku 6 z listy kontrolnej dla nowego serwera root. Tam znajdziesz dwa polecenia, które w większości przypadków wystarczają. Tutaj opisane jest to, co dzieje się pod spodem, oraz to, co zrobić, kiedy nie wystarczą.

Wszystkie informacje dotyczą Debiana 13 (trixie), Debiana 12 (bookworm), Ubuntu 24.04 LTS oraz Ubuntu 22.04 LTS. Polecenia napisano pod pracę jako root. Jako zwykły użytkownik poprzedzasz każde z nich poleceniem sudo.

Serwer ma trzy nazwy, nie jedną

Najczęstszy powód nie do końca udanej zmiany nazwy jest taki, że Linux zna nie jedną nazwę hosta, tylko trzy. Leżą w różnych miejscach i są nadpisywane przez różne mechanizmy.

NazwaGdzie leżyOdczyt przezKto ją ustawia
statyczna/etc/hostnamehostnamectl --statichostnamectl set-hostname, cloud-init
ulotnatylko w kerneluhostnamectl --transient, uname -nhostname NAME, klient DHCP, systemd-networkd
opisowa/etc/machine-infohostnamectl --prettyhostnamectl set-hostname --pretty

Nazwę ulotną prowadzi kernel i to ją dostaje każdy program przez gethostname(). Nazwa statyczna jest wzorcem, z którego tamta zostaje ustawiona podczas rozruchu. Nazwa opisowa może zawierać spacje i znaki diakrytyczne, a pojawia się wyłącznie w interfejsach, nigdy w sieci.

Równie ważne jest drugie rozróżnienie: które polecenie skąd bierze swoją odpowiedź. Załóżmy, że w /etc/hostname stoi srv01, a w /etc/hosts wiersz 127.0.1.1 srv01.example.com srv01. Wtedy obraz wygląda tak.

PolecenieWynikŹródło
hostnamesrv01kernel
uname -nsrv01kernel
hostnamectl --staticsrv01/etc/hostname
hostname -ssrv01kernel, skrócone do pierwszej kropki
hostname -fsrv01.example.comrozwiązywanie nazw
hostname -dexample.comrozwiązywanie nazw
dnsdomainnameexample.comrozwiązywanie nazw
domainname(none)domena NIS, nie DNS

Kluczowy jest wiersz z hostname -f. To polecenie nie czyta /etc/hostname, tylko bierze nazwę z kernela i przepuszcza ją przez rozwiązywanie nazw. Pełna nazwa pochodzi więc z /etc/hosts albo z DNS, nigdy z pliku z nazwą hosta. Prawie wszystkie problemy opisane w tym artykule biorą się z tego nieporozumienia.

Zanim zmienisz cokolwiek: droga powrotna

Sama zmiana nazwy nie zrywa twojej sesji SSH. Niebezpieczny jest krok następny: edycja pliku /etc/hosts. Jeśli zniknie z niego wiersz dla localhost, dziesiątki programów zaczną czekać na timeouty, Postfix przestanie się uruchamiać, a sudo będzie potrzebowało kilku sekund na każde wywołanie. Wyjaśnij więc wcześniej trzy sprawy.

1. Druga sesja zostaje otwarta

Otwórz drugie okno terminala z aktywnym połączeniem i nie zamykaj go, dopóki nie sprawdzisz wszystkiego. Istniejąca sesja przeżyje każdą zmianę nazwy hosta i rozwiązywania nazw. Jeśli samo zestawienie połączenia jeszcze nie działa jak należy, pomoże Połączenie z serwerem przez SSH.

2. Droga z pominięciem SSH

Serwery root KVM oraz serwery dedykowane KernelHost nie mają IPMI ani iDRAC. Dostępem, który działa nawet wtedy, gdy w systemie gościa nie działa już nic, jest konsola VNC w panelu klienta. Jest podpięta do warstwy wirtualizacji, a przy serwerze dedykowanym do samego przyłącza, niezależnie od rozwiązywania nazw w systemie gościa. Zaloguj się tam raz zawczasu i upewnij się, że znasz hasło roota. Droga ratunkowa, którą wypróbowuje się po raz pierwszy w czasie awarii, nie jest żadną drogą ratunkową.

3. Dwie kopie i jedno wycofanie zmian

cp -a /etc/hostname /root/hostname.bak
cp -a /etc/hosts /root/hosts.bak
hostnamectl > /root/hostnamectl-przed.txt

Dzięki temu droga powrotna to dwa wiersze, które w razie potrzeby wklepiesz przez konsolę:

cp -a /root/hosts.bak /etc/hosts
hostnamectl set-hostname "$(cat /root/hostname.bak)"

Inwentaryzacja w pięciu poleceniach

Najpierw zobacz, co obowiązuje w tej chwili i kto ma w tym swój udział.

hostnamectl
cat /etc/hostname
cat /etc/hosts
grep '^hosts:' /etc/nsswitch.conf
command -v cloud-init >/dev/null && cloud-init status --long || echo "cloud-init nie jest zainstalowany"

Na wynik polecenia hostnamectl warto spojrzeć uważnie. Normalnie zaczyna się on od Static hostname:. Jeśli dodatkowo pojawia się wiersz Transient hostname:, nazwa statyczna i bieżąca różnią się od siebie, a coś aktywnie przestawia nazwę: prawie zawsze cloud-init albo klient DHCP. To trzeba wyłączyć w pierwszej kolejności, inaczej po najbliższym restarcie twojej zmiany znów nie będzie.

Wiersz hosts: z pliku /etc/nsswitch.conf ustala kolejność rozwiązywania nazw. Cztery wpisy, które się tam pojawiają, oznaczają:

  • files: czytany jest plik /etc/hosts.
  • dns: resolver pyta serwery nazw z pliku /etc/resolv.conf.
  • resolve: zapytanie trafia do systemd-resolved.
  • myhostname: moduł systemd, który odwzorowuje własną nazwę maszyny na skonfigurowane lokalnie adresy IP, także bez wpisu w /etc/hosts.

Ostatni punkt tłumaczy dalej w tekście, dlaczego ten sam błąd na części serwerów latami pozostaje niezauważony.

Wybór nazwy: FQDN czy krótka nazwa

Dozwolone są litery, cyfry i myślnik. Żadnego podkreślenia, żadnej kropki na początku ani na końcu, żadnego myślnika na początku etykiety. Pisz małymi literami: DNS porównuje bez względu na wielkość liter, wiele programów natomiast dosłownie. Etykieta (część między dwiema kropkami) może mieć 63 znaki, pełna nazwa w DNS 253. Kernel przyjmuje jednak dla nazwy hosta najwyżej 64 znaki, więc bardzo długi FQDN może się w niej po prostu nie zmieścić. Wybierz nazwę pod domeną, która należy do ciebie: .local jest zarezerwowana dla mDNS, a wymyślone końcówki w rodzaju .lan mogą w każdej chwili stać się prawdziwymi domenami najwyższego poziomu.

Pozostaje pytanie, co ma stać w /etc/hostname. Oba warianty działają, różnią się tym, co potem wszędzie zobaczysz.

Wariant/etc/hostnamehostnamehostname -f
krótka nazwa (konwencja Debiana)srv01srv01srv01.example.com, rozwiązane przez /etc/hosts albo DNS
FQDN (wiele obrazów chmurowych)srv01.example.comsrv01.example.comsrv01.example.com

Na Debianie i Ubuntu zalecany jest wariant pierwszy: krótka nazwa w /etc/hostname, pełna nazwa jako pierwszy wpis w /etc/hosts. Dzięki temu znak zachęty i wiersze logów pozostają krótkie, a FQDN mimo wszystko się zgadza. Drugi wariant jest równie czysty, dopóki trzymasz się go konsekwentnie. Prawdziwym błędem jest mieszanka: jeden FQDN w /etc/hostname i inny w /etc/hosts.

Wpis A (przy IPv6 wpis AAAA) dla nowej nazwy najlepiej załóż od razu. Nic nie kosztuje, sprawia, że hostname -f odpowiada poprawnie także bez /etc/hosts, i jest warunkiem uzyskania jakiegokolwiek certyfikatu na tę nazwę.

Okiełznanie cloud-init, zanim cokolwiek ustawisz

Na obrazach z cloud-init, a w Ubuntu są to praktycznie wszystkie, nazwa hosta jest podczas rozruchu ustawiana z metadanych instancji. Odpowiadają za to moduły set_hostnameupdate_hostname, a do tego update_etc_hosts dla pliku /etc/hosts. Wszystkie trzy działają wcześnie, jeszcze zanim wystartują twoje własne usługi. Sterują tym dwa przełączniki:

grep -rE '^(preserve_hostname|manage_etc_hosts)' /etc/cloud/cloud.cfg /etc/cloud/cloud.cfg.d/ 2>/dev/null

Na obrazach Ubuntu Server w pliku /etc/cloud/cloud.cfg stoi wiersz preserve_hostname: false, cloud-init może więc ruszać nazwę. Przełącznik przeciwny nie należy do tego pliku, bo aktualizacja pakietu go podmienia, tylko do katalogu /etc/cloud/cloud.cfg.d/. Pliki są tam czytane alfabetycznie, wygrywa późniejszy, stąd 99:

mkdir -p /etc/cloud/cloud.cfg.d
printf 'preserve_hostname: true\n' > /etc/cloud/cloud.cfg.d/99_hostname.cfg

Drugi przełącznik dotyczy /etc/hosts. Bywa chętnie przeoczony, choć narobi więcej szkód.

Wartość manage_etc_hostsDziałanie na /etc/hosts
nieustawiona albo falsecloud-init nie rusza pliku
localhostcloud-init dba przy każdym starcie o to, żeby własna nazwa się rozwiązywała, a resztę pliku zostawia bez zmian
truecloud-init tworzy plik przy każdym starcie na nowo z szablonu w /etc/cloud/templates/, własnych wierszy potem nie ma

Jeśli stoi tam true, a potrzebujesz własnych wpisów, ustaw wartość na localhost albo zamiast tego zadbaj o szablon (na Debianie i Ubuntu hosts.debian.tmpl). Ręczna zmiana pliku, który jest nadpisywany przy każdym starcie, tworzy dokładnie ten rodzaj błędu, który zauważa się dopiero po tygodniach.

To, co cloud-init ustawił ostatnio, zapamiętuje w /var/lib/cloud/data/. Ten stan kasuje cloud-init clean. Na skonfigurowanym serwerze lepiej tego nie rób: przy następnym starcie ruszą od nowa wszystkie moduły, tak jakby maszyna była świeża.

Drugi nadpisujący: DHCP

Jeśli serwer pobiera adres przez DHCP, klient może przejąć ulotną nazwę hosta z odpowiedzi (opcja 12). Nazwa statyczna pozostaje nietknięta, co utrudnia szukanie błędu: hostnamectl --static pokazuje twoją nazwę, a hostname inną. W netplanie wyłączasz to tak:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      dhcp4-overrides:
        use-hostname: false

Uaktywnij zmianę przez netplan try, a nie przez netplan apply: try samo cofa zmianę po 120 sekundach, jeśli jej nie potwierdzisz. Przy bezpośrednio skonfigurowanym systemd-networkd ustawienie nazywa się UseHostname=no w sekcji [DHCPv4].

Ustawienie nazwy hosta

hostnamectl set-hostname srv01

Bez dodatkowych przełączników hostnamectl ustawia nazwę statyczną i ulotną naraz. I dokładnie o to ci chodzi. Z przełącznikiem --static zmieniasz tylko /etc/hostname, a przy aktywnej nazwie ulotnej maszyna chodziłaby pod starą aż do restartu. Nowsze wersje systemd znają dodatkowo skróconą formę hostnamectl hostname srv01, natomiast set-hostname działa na wszystkich czterech systemach.

Kontrola powodzenia: obie nazwy muszą się zgadzać, a plik musi mieć nową zawartość.

hostnamectl --static
hostnamectl --transient
cat /etc/hostname

Dwie uwagi na marginesie. Po pierwsze, hostname srv01 bez ctl zmienia wyłącznie nazwę ulotną i po restarcie jej nie ma. Po drugie, twoja działająca powłoka nadal pokazuje w znaku zachęty starą nazwę, bo bash wczytuje nazwę hosta raz, przy starcie sesji. To nie jest niepowodzenie, tylko stara sesja. Zaloguj się na nowo.

Opcjonalnie zapisujesz nazwę opisową, która pojawia się w interfejsach i może zawierać spacje:

hostnamectl set-hostname --pretty "Serwer WWW Frankfurt"
cat /etc/machine-info

Poprawny zapis /etc/hosts

hostnamectl nie rusza pliku /etc/hosts. Ten plik pozostaje twoim zadaniem i to on jest powodem, dla którego zmiana nazwy tak często działa tylko w połowie.

Wiersz składa się z adresu IP, nazwy kanonicznej i dowolnej liczby aliasów. Pierwsza nazwa po adresie jest kanoniczna i dokładnie ją zwraca hostname -f. Dlatego pełna nazwa stoi z przodu, a krótka za nią, nigdy odwrotnie.

127.0.0.1       localhost
127.0.1.1       srv01.example.com srv01

::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters

Dlaczego 127.0.1.1, a nie 127.0.0.1: Debian i Ubuntu świadomie oddzielają własną nazwę maszyny od localhost. Jeśli dopiszesz nazwę serwera jako alias do wiersza z localhost, jego nazwą kanoniczną pozostanie localhost, a hostname -f odpowie localhost. Programy, które wyprowadzają z tego własną nazwę, wpiszą potem localhost do logów i nagłówków wiadomości e-mail.

Brakujący wpis dopisujesz, istniejący wiersz zmieniasz:

grep -n '^127\.0\.1\.1' /etc/hosts
printf '127.0.1.1\tsrv01.example.com\tsrv01\n' >> /etc/hosts

Jeśli pierwsze polecenie zwraca już jakiś wiersz, popraw właśnie ten wiersz, zamiast dopisywać drugi. Przy dwóch wierszach dla tego samego adresu wygrywa pierwszy, a ty zmieniasz potem wiersz, którego nikt już nie czyta.

Kontrola powodzenia:

getent hosts srv01
getent hosts srv01.example.com
hostname -f
hostname -s

Oba wywołania getent muszą zwrócić po jednym wierszu, hostname -f pełną nazwę, a hostname -s krótką. Jeśli nic nie wraca, wpis nie działa, na przykład dlatego, że wiersz ma z przodu znak komentarza.

Pozostaje jedna decyzja: 127.0.1.1 czy publiczny adres serwera. Część oprogramowania wiąże się z adresem, na który rozwiązuje się jego własna nazwa, albo wpisuje go na listę członków klastra. Wtedy FQDN należy do adresu publicznego. Przy stałym adresie to czystszy wariant, przy zmiennym lepszy jest 127.0.1.1, bo działa również bez połączenia sieciowego.

Dlaczego brakujący wpis spowalnia sudo

sudo przy każdym wywołaniu ustala własną nazwę maszyny i każe ją rozwiązać. Potrzebuje jej do wiersza w logu oraz do porównania z wpisami maszyn w /etc/sudoers.

Rozwiązywanie idzie wzdłuż wiersza hosts: z pliku /etc/nsswitch.conf. Jeśli nazwa stoi w /etc/hosts, sprawa kończy się po jednym dostępie do pliku, czyli poniżej milisekundy. Jeśli jej tam nie ma, zapytanie wędruje do kolejnego wpisu, z reguły dns, a resolver pyta serwery nazw z /etc/resolv.conf o nazwę, której w DNS nie ma. Domyślne ustawienia glibc to timeout pięciu sekund i dwie próby na każdy serwer nazw. Jeśli nikt nie odpowiada, wszystko to się sumuje, i to przy każdym pojedynczym wywołaniu.

Dochodzi do tego czynnik wzmacniający: krótka nazwa nie zawiera kropki i leży tym samym poniżej domyślnego ndots:1. Resolver dokleja więc najpierw każdą domenę wyszukiwania z /etc/resolv.conf, a dopiero potem pyta o samą nazwę. Dwie domeny wyszukiwania oznaczają trzy rundy zapytań zamiast jednej.

Widać to po tym ostrzeżeniu, które poprzedza każde wywołanie:

sudo: unable to resolve host srv01: Name or service not known

Mierz, zamiast zgadywać:

time getent hosts "$(hostname)"
time sudo -n true

Jedno i drugie powinno zostać daleko poniżej jednej dziesiątej sekundy. Wszystko powyżej to czas oczekiwania na serwer nazw.

A teraz powód, dla którego ten błąd nie wszędzie rzuca się w oczy: jeśli w wierszu hosts: stoi wpis myhostname, to ten moduł sam odpowiada na pytanie o własną nazwę, bez DNS i bez /etc/hosts. Tam ostrzeżenie się nie pojawia, mimo że plik jest niekompletny. Gdy tylko ta sama konstrukcja trafi na system bez tego wpisu, błąd wraca.

Drugi, rzadszy problem dotyczy nadawania uprawnień: w /etc/sudoers każda reguła może być ograniczona do konkretnych nazw maszyn. Reguły dostarczane przez Debiana i Ubuntu używają ALL i są bezpieczne. Własne reguły z nazwą maszyny tracą natomiast skuteczność, a objęty nimi użytkownik nie może potem już nic. Sprawdź to wcześniej:

grep -rhvE '^[[:space:]]*(#|$)' /etc/sudoers /etc/sudoers.d/

Usługi, które wczytują nazwę przy starcie

Wiele programów pyta o nazwę hosta dokładnie raz, przy starcie, a potem pracuje dalej ze starą nazwą. To wyjaśnia sporą część zamieszania po zmianie nazwy.

  • Działająca powłoka. Znak zachęty pokazuje starą nazwę. Otwórz nową sesję i gotowe.
  • rsyslog, tam gdzie jest zainstalowany. Wystarczy systemctl restart rsyslog. Debian 12 i 13 nie dokładają rsysloga w instalacjach minimalnych, tam pisze journald.
  • Już zapisane wpisy w logach zachowują starą nazwę i tak ma być. Jeśli natomiast stara nazwa stoi w nowych wpisach, zrestartuj usługę, która je zapisuje.
  • MariaDB i MySQL wyprowadzają z nazwy hosta domyślne nazwy plików, na przykład logu błędów i logu binarnego, o ile ścieżki nie są wprost podane w konfiguracji.
  • Aplikacje w Javie. InetAddress.getLocalHost() rzuca wyjątek java.net.UnknownHostException, gdy tylko własna nazwa się nie rozwiązuje. Dotyczy to zarówno serwerów aplikacji, jak i serwerów gier.
  • Agenci monitoringu mają nazwę często wpisaną we własnym pliku konfiguracyjnym. Inaczej ten sam serwer pojawi się po zmianie nazwy dwa razy.
systemctl list-units --type=service --state=running

Jeśli i tak zbliża się okno serwisowe, restart jest rozwiązaniem najpełniejszym. To, jak porządnie opisać własne programy jako unit, żeby przetrwały restart, znajdziesz w artykule Tworzenie usługi systemd.

Serwer pocztowy: nazwa, którą widzą inni

Przy wysyłce poczty nazwa hosta przestaje być kosmetyką. Druga strona widzi ją w EHLO i sprawdza. Trzy rzeczy muszą do siebie pasować:

  1. Nazwa, którą przedstawia się twój serwer pocztowy (w Postfiksie myhostname).
  2. Wpis PTR twojego adresu IP, czyli rozwiązywanie wsteczne.
  3. Wpis A (przy IPv6 wpis AAAA) dla dokładnie tej nazwy, wskazujący z powrotem na ten sam adres.

Jeśli łańcuch się nie domyka, wielu odbiorców obniża ocenę wiadomości albo ją odrzuca. Sprawdzenie bez dodatkowych pakietów:

hostname -f
getent hosts 203.0.113.10
getent hosts srv01.example.com

Dokładniej wychodzi to z dig z pakietu bind9-dnsutils:

apt install -y bind9-dnsutils
dig +short -x 203.0.113.10
dig +short srv01.example.com A

Wpis PTR nie należy do serwera. Wisi przy adresie IP i jest utrzymywany u operatora sieci, w KernelHost przez panel klienta. Żadne wywołanie hostnamectl tego nie zmieni i dokładnie w tym miejscu zmiany nazwy na serwerach pocztowych idą źle.

Postfix nie przejmuje zmiany nazwy sam z siebie. Na Debianie i Ubuntu pakiet zapisuje przy konfiguracji stałą wartość do /etc/postfix/main.cf, a obok leży /etc/mailname z nazwą, której Postfix używa jako domeny nadawcy dla poczty lokalnej. Oba pozostają niezmienione:

postconf myhostname mydomain myorigin
cat /etc/mailname

Dostosuj je i zrestartuj usługę, przy czym /etc/mailname to osobna decyzja i nie musi koniecznie mieć tej samej wartości co myhostname:

postconf -e "myhostname = srv01.example.com"
postfix check
systemctl restart postfix

SPF, DKIM i DMARC wiszą natomiast przy domenie nadawcy, a nie przy nazwie hosta. Zmiana nazwy nie naprawia więc problemów z dostarczalnością, których przyczyna leży właśnie tam.

Certyfikaty

Nazwa systemowa nie stoi w żadnym certyfikacie, bo certyfikat pokrywa te nazwy DNS, które były we wniosku. Mimo to zmiana nazwy odbija się w trzech miejscach.

Po pierwsze przy wniosku. Jeśli bierzesz certyfikat na samą nazwę serwera, na przykład dla serwera pocztowego, nazwa musi stać w DNS, zanim urząd certyfikacji tam zajrzy. Inaczej przebieg kończy się komunikatem w rodzaju DNS problem: NXDOMAIN looking up A for srv01.example.com. Wpis A należy założyć przed wnioskiem, a nie po nim.

Po drugie przy istniejących certyfikatach. Działają dalej na starą nazwę i są dalej odnawiane, dopóki ich nie usuniesz:

certbot certificates
certbot delete --cert-name stary.example.com

Usuwaj dopiero wtedy, gdy żadna usługa nie wskazuje już na tę ścieżkę, inaczej serwer WWW nie wystartuje przy najbliższym przeładowaniu.

Po trzecie przy serwerze pocztowym. Jeśli Postfix przedstawia się nową nazwą, ale prezentuje certyfikat na starą, zawiodą te serwery, które sprawdzają nazwę rygorystycznie. Certyfikat i myhostname należą do tej samej nazwy.

Nie ma natomiast żadnego związku między nazwą systemową a dyrektywą server_name w nginx. nginx decyduje na podstawie nagłówka Host z zapytania, a nie na podstawie nazwy maszyny. Kto po zmianie nazwy dostaje niewłaściwą stronę, szuka w konfiguracji serwera, a nie przy nazwie hosta. Podstawy znajdziesz w artykule Instalacja nginx na Debianie i Ubuntu.

Typowe błędy i ich rozwiązania

sudo: unable to resolve host srv01: Name or service not known
Nazwa maszyny nie stoi w /etc/hosts i jest nieznana w DNS. Dopisz wiersz 127.0.1.1 srv01.example.com srv01. Dopóki go brakuje, każde wywołanie czeka na timeout resolvera.

hostname: Name or service not known
Odpowiedź polecenia hostname -f, gdy nazwa z kernela nigdzie się nie rozwiązuje. Ta sama przyczyna, to samo rozwiązanie. Potem sprawdź przez getent hosts "$(hostname)", czy naprawdę coś wraca.

Could not set property: Access denied
hostnamectl zostało wywołane bez uprawnień roota albo wywołanie odbyło się w kontenerze, który nie może zmieniać nazwy w kernelu. Na własnym serwerze pomaga sudo. W kontenerze nieuprzywilejowanym ustawiasz nazwę w jego konfiguracji, a nie w jego wnętrzu.

fatal: unable to use my own hostname
Z logu Postfiksa. Wartość w myhostname się nie rozwiązuje. Dopisz wpis w /etc/hosts, potem systemctl restart postfix.

504 5.5.2 <srv01>: Helo command rejected: need fully-qualified hostname
Twój serwer pocztowy przedstawia się krótką nazwą, a druga strona wymaga nazwy pełnej. Ustaw myhostname na FQDN i zrestartuj Postfiksa.

450 4.7.1 Client host rejected: cannot find your reverse hostname
Do twojego adresu IP nie istnieje wpis PTR albo wskazuje on w pustkę. Tego nie da się naprawić na serwerze, tylko u operatora sieci IP.

java.net.UnknownHostException: srv01
Aplikacja w Javie chciała rozwiązać własną nazwę i jej się nie udało. Znów /etc/hosts. Po dodaniu wpisu aplikację trzeba zrestartować.

DNS problem: NXDOMAIN looking up A for srv01.example.com
Nowa nazwa jeszcze nie istnieje w DNS. Załóż wpis A, poczekaj na propagację, powtórz wniosek.

Po restarcie nazwa znów jest stara.
Sprawdź w tej kolejności: czy preserve_hostname: true jest ustawione w /etc/cloud/cloud.cfg.d/, czy klient DHCP nie dostarcza już nazwy, czy /etc/hostname rzeczywiście zawiera nową nazwę. Jeśli hostnamectl pokazuje po starcie wiersz Transient hostname:, jedno z tych źródeł nadal działa.

/etc/hosts jest po każdym restarcie znów wyczyszczony.
Ustawione jest manage_etc_hosts: true, cloud-init tworzy plik na nowo z szablonu. Przestaw wartość na localhost albo zadbaj o szablon.

Różnice między dystrybucjami

Systemcloud-init fabryczniersyslogCecha szczególna
Debian 13 (trixie)tylko na obrazach chmurowychbrak w instalacjach minimalnychlogi w journalu zamiast w /var/log/syslog
Debian 12 (bookworm)tylko na obrazach chmurowychzależnie od wariantu instalacjijak Debian 13
Ubuntu 24.04 LTStak, preserve_hostname: falseobecnysystemd-resolved aktywny, resolve stoi w wierszu hosts:
Ubuntu 22.04 LTStak, preserve_hostname: falseobecnyjak Ubuntu 24.04

Na wszystkich czterech systemach tak samo: hostnamectl nigdy nie zmienia /etc/hosts, a żadne narzędzie systemu operacyjnego nie zakłada wpisów DNS ani PTR. Te dwa kroki pozostają pracą ręczną.

Kontrola końcowa

Polecenie bez komunikatu o błędzie to jeszcze nie dowód. Jedynym wiarygodnym testem jest restart, a po nim te pięć wierszy:

hostnamectl --static
hostname -f
getent hosts "$(hostname)"
time sudo -n true
grep -c '^127\.0\.1\.1' /etc/hosts

Oczekiwane są: nowa krótka nazwa, nowa pełna nazwa, jeden wiersz z /etc/hosts, czas działania wyraźnie poniżej jednej dziesiątej sekundy oraz dokładnie jeden wiersz dla 127.0.1.1. Dopiero gdy wszystkie pięć się zgadza, zmiana nazwy jest zakończona, i dopiero wtedy możesz zamknąć drugie okno terminala.

Najczęstsze pytania

Dlaczego po restarcie moja nazwa hosta znów jest stara?
Bo podczas rozruchu ustawia ją coś innego, z reguły cloud-init albo klient DHCP. Załóż plik /etc/cloud/cloud.cfg.d/99_hostname.cfg z wierszem preserve_hostname: true, wtedy cloud-init zostawi nazwę w spokoju. Przy kliencie DHCP pomaga w netplanie ustawienie use-hostname: false w dhcp4-overrides, a przy systemd-networkd UseHostname=no w sekcji [DHCPv4]. Czy ktoś w ogóle się do tego wtrąca, zobaczysz w wyniku polecenia hostnamectl: jeśli obok Static hostname pojawia się jeszcze wiersz Transient hostname, nazwa zapisana i bieżąca różnią się od siebie.
Dlaczego sudo zgłasza „unable to resolve host” i nagle potrzebuje kilku sekund?
sudo przy każdym wywołaniu każe rozwiązać własną nazwę maszyny, potrzebuje jej do wiersza w logu i do porównania z wpisami maszyn w /etc/sudoers. Jeśli nazwa nie stoi w /etc/hosts, zapytanie idzie dalej do resolvera DNS, a ten przy domyślnych ustawieniach glibc czeka pięć sekund na próbę, przy dwóch próbach na każdy serwer nazw. Krótka nazwa bez kropki leży poza tym poniżej ndots:1, więc najpierw doklejana jest jeszcze każda domena wyszukiwania. Wiersz 127.0.1.1 srv01.example.com srv01 w /etc/hosts kończy to natychmiast.
Czy w /etc/hostname ma stać krótka nazwa czy nazwa pełna?
Działa jedno i drugie. Na Debianie i Ubuntu konwencją jest krótka nazwa, a nazwa pełna stoi wtedy jako pierwszy wpis w odpowiednim wierszu /etc/hosts. Dzięki temu znak zachęty i wiersze logów pozostają krótkie, a hostname -f mimo to zwraca FQDN. Wiele obrazów chmurowych zapisuje zamiast tego FQDN w /etc/hostname, co jest równie czyste. Prawdziwym błędem jest mieszanka: jedna pełna nazwa w /etc/hostname i inna w /etc/hosts.
Dlaczego 127.0.1.1 w /etc/hosts, a nie 127.0.0.1?
Debian i Ubuntu świadomie oddzielają własną nazwę maszyny od localhost. Pierwsza nazwa po adresie jest kanoniczna i dokładnie ją zwraca hostname -f. Jeśli dopiszesz nazwę serwera jako alias do wiersza z localhost, nazwą kanoniczną pozostanie localhost, a hostname -f odpowie localhost. Programy, które wyprowadzają z tego własną nazwę, wpisują ją potem do logów i nagłówków wiadomości e-mail. Osobny wiersz z 127.0.1.1 pozwala tego uniknąć. Przy stałym adresie publicznym możesz alternatywnie umieścić pełną nazwę bezpośrednio na tym adresie.
Czy hostnamectl zmienia także /etc/hosts?
Nie. hostnamectl zapisuje /etc/hostname, ustawia bieżącą nazwę w kernelu i na życzenie prowadzi /etc/machine-info. Pliku /etc/hosts nie rusza nigdy. Jedyne, co zmienia go automatycznie, to cloud-init z ustawieniem manage_etc_hosts: wartość true tworzy plik przy każdym starcie na nowo z szablonu, wartość localhost dba tylko o to, żeby własna nazwa się rozwiązywała, a bez tego ustawienia plik pozostaje nietknięty.
Czy polecenie hostname wystarczy do trwałej zmiany?
Nie. hostname srv01 ustawia tylko ulotną nazwę w kernelu, a tej po najbliższym restarcie już nie ma, bo zostaje wtedy wczytana z powrotem z /etc/hostname. Do trwałej zmiany bierzesz hostnamectl set-hostname srv01, które ustawia nazwę statyczną i ulotną naraz. Nowsze wersje systemd znają dodatkowo skróconą formę hostnamectl hostname srv01.
Co muszę dodatkowo dostosować przy swoim serwerze pocztowym?
Trzy rzeczy muszą do siebie pasować: nazwa w EHLO (w Postfiksie myhostname), wpis PTR twojego adresu IP oraz wpis A względnie AAAA dla dokładnie tej nazwy, wskazujący z powrotem na ten sam adres. Postfix nie przejmuje zmiany nazwy sam z siebie, bo pakiet na Debianie i Ubuntu zapisuje stałą wartość w /etc/postfix/main.cf, a obok leży /etc/mailname. Wpisu PTR nie ustawia się na serwerze, tylko u operatora sieci IP, w KernelHost przez panel klienta. Jeśli go brakuje, rygorystyczni odbiorcy odrzucają pocztę komunikatem 450 4.7.1 Client host rejected: cannot find your reverse hostname.

Nazwa hosta hostnamectl cloud-init Linux Debian Ubuntu DNS Serwer root