Bezpieczna aktualizacja serwera Linux przez apt
Różnica między upgrade, full-upgrade i dist-upgrade, wstrzymane pakiety, pytania dpkg o pliki konfiguracyjne, restart kernela z needrestart oraz zmiana wersji dystrybucji jako osobna kategoria.
Na świeżo postawionym serwerze aktualizacja jest formalnością: nie ma tam nic, co mogłoby się zepsuć. Gdy tylko serwer zaczyna obsługiwać usługi, o wyniku decydują szczegóły. Albo aktualizacja przejdzie niezauważona, albo zostanie po niej nadpisany plik konfiguracyjny, usługa nadal będzie trzymała w pamięci starą bibliotekę, a działający kernel okaże się inny niż ten na dysku. Ten artykuł omawia je po kolei. Wersja skrócona dla świeżo dostarczonego systemu stoi w liście kontrolnej dla nowego serwera root.
Wszystkie informacje dotyczą Debiana 13 (trixie), Debiana 12 (bookworm), Ubuntu 24.04 LTS oraz Ubuntu 22.04 LTS. Polecenia napisano z myślą o pracy na koncie root. Jako zwykły użytkownik dopisz przed każdym poleceniem sudo.
Zanim wydasz pierwsze polecenie: droga powrotna
Aktualizacja może kosztować cię sporo na trzy sposoby: pytanie o plik konfiguracyjny nadpisze konfigurację SSH, nowy kernel nie wystartuje albo połączenie zerwie się w środku transakcji dpkg. Wszystkie trzy da się opanować, ale tylko wtedy, gdy przygotujesz się zawczasu.
Sesja, która przetrwa zerwanie połączenia
Jeśli połączenie SSH zerwie się podczas rozpakowywania, działający proces dostaje sygnał SIGHUP, a dpkg kończy pracę w środku transakcji. Efektem jest na wpół skonfigurowana baza pakietów. Dłuższe aktualizacje uruchamiaj więc w sesji, która działa dalej na serwerze, nawet gdy twój terminal zniknie:
apt install -y tmux
tmux new -s upgrade
Gdy połączenie padnie, zaloguj się ponownie i odzyskaj sesję poleceniem tmux attach -t upgrade. Operacja przez ten czas biegła dalej.
Droga na serwer, gdy SSH przestaje odpowiadać
W serwerach root KVM i serwerach dedykowanych od KernelHosta konsola VNC czeka w panelu klienta. Nie wisi ona na stosie sieciowym systemu gościa i działa również wtedy, gdy żadna usługa już nie nasłuchuje. Zaloguj się przez nią raz zawczasu i upewnij się, że znasz hasło roota.
Na wypadek kernela, który nie wystartuje, potrzebujesz dodatkowo widocznego menu startowego. Na serwerach bywa ono zwykle ukryte:
grep -E '^GRUB_TIMEOUT|^GRUB_TIMEOUT_STYLE' /etc/default/grub
Jeśli stoi tam GRUB_TIMEOUT_STYLE=hidden albo GRUB_TIMEOUT=0, ustaw GRUB_TIMEOUT_STYLE=menu oraz GRUB_TIMEOUT=5 i wywołaj update-grub. W razie awarii wybierzesz w konsoli VNC poprzedni kernel pod pozycją „Advanced options”.
Sprawdź stan i zapisz punkt wyjścia
Trzy kontrole na wstępie, które znajdują coś częściej, niż można by sądzić:
df -h / /boot /var
dpkg --audit
apt-get check
Kontrola skuteczności: dpkg --audit nic nie wypisuje, apt-get check przechodzi bez wiersza z błędem, a w /boot jest co najmniej 300 MB wolnego miejsca. Pełny /boot jest najczęstszą przyczyną przerwanej aktualizacji kernela, więcej o tym w artykule pełny dysk w Linuksie. Jeśli dpkg --audit coś zgłosi, napraw to najpierw poleceniem dpkg --configure -a.
Następnie zapisz stan bieżący, żeby mieć potem do czego porównywać:
dpkg --get-selections > /root/pakiety-przed-upgradem.txt
apt-mark showhold > /root/holds-przed-upgradem.txt
cp -a /etc/apt /root/apt-config-$(date +%F)
update, upgrade, full-upgrade i dist-upgrade
Te cztery słowa są nieustannie mylone. Różnica nie jest kosmetyczna: rozstrzyga o tym, czy zainstaluje się nowy kernel i czy pakiety mogą zniknąć.
| Polecenie | Nowe pakiety | Usuwa pakiety | Zastosowanie |
|---|---|---|---|
apt update | nie | nie | pobiera tylko listy pakietów, w systemie nic nie zmienia |
apt-get upgrade | nie | nie | najostrożniejszy wariant, wstrzymuje aktualizacje kernela |
apt upgrade | tak, jeśli wymaga tego zależność | nie | przypadek normalny na systemach produkcyjnych |
apt full-upgrade | tak | tak, jeśli trzeba | gdy świadomie dopuszczasz usuwanie |
apt-get dist-upgrade | tak | tak, jeśli trzeba | starsza nazwa tego samego |
Wynikają z tego dwa wnioski. Po pierwsze, dist-upgrade nie ma nic wspólnego z przejściem na nową wersję dystrybucji. Nazwa jest historyczna, a samo polecenie pozostaje w obrębie twojej bieżącej wersji.
Po drugie, różnica między apt upgrade a apt-get upgrade jest dokładnie tym powodem, dla którego część serwerów zostaje bez nowego kernela. Debian wciąga kernel przez metapakiet linux-image-amd64, Ubuntu przez linux-image-generic względnie linux-image-virtual. Przy każdej zmianie ABI ten metapakiet wskazuje na nowy pakiet, którego numer wersji siedzi w nazwie. apt-get upgrade z zasady nie instaluje nowych pakietów i dlatego zostawia kernel w spokoju, natomiast apt upgrade go instaluje, bo wymaga tego zależność. Kto używa apt-get upgrade w skrypcie konserwacyjnym, potrzebuje tam dodatkowo --with-new-pkgs.
Co do wyboru narzędzia: wywołany ze skryptu apt wypisuje wiersz WARNING: apt does not have a stable CLI interface. Use with caution in scripts. To nie jest komunikat o błędzie, tylko uzasadniona wskazówka. Do skryptów i ról Ansible należy apt-get, interaktywnie wygodniejszy jest apt.
Przebieg z kontrolą po każdym kroku
Krok 1: pobranie list pakietów.
apt update
Kontrola skuteczności: w wyjściu nie ma wiersza zaczynającego się od Err: albo W:. Na końcu stoi albo All packages are up to date., albo liczba, po której następuje packages can be upgraded. Każdy wiersz z błędem oznacza tutaj, że pracowałbyś dalej na niepełnym obrazie sytuacji.
Krok 2: obejrzyj, co miałoby przyjść. Tego kroku brakuje w większości poradników, a jest on najważniejszy w całym przebiegu.
apt list --upgradable
apt full-upgrade -s
Przełącznik -s tylko symuluje i niczego nie zmienia. Wiersze pod The following packages will be REMOVED: są jedynymi, które musisz naprawdę sprawdzić. Jeśli nie ma tam nic, full-upgrade jest równie nieszkodliwy jak upgrade. Jeśli stoi tam pakiet, którego potrzebujesz, weź apt upgrade, a przyczynę wyjaśnij osobno.
W Debianie opłaca się dodatkowo apt install apt-listchanges. Pakiet ten pokazuje przed wgraniem changelogi oraz, co ważniejsze, pliki NEWS od opiekunów pakietów. Stoi tam dokładnie to, co wymaga pracy ręcznej.
Krok 3: wgranie aktualizacji.
apt upgrade
Nie odchodź wtedy od terminala. Operacja zadaje pytania, a -y odpowiada tylko na pytanie samego apt, nie na pytania o pliki konfiguracyjne. Te pochodzą od dpkg i czekają cierpliwie, aż ktoś odpowie.
Kontrola skuteczności:
apt list --upgradable
dpkg --audit
systemctl --failed
journalctl -p 3 -b --no-pager | tail -n 20
Oczekiwany wynik: apt list --upgradable nie wypisuje nic poza Listing..., dpkg --audit milczy, systemctl --failed zgłasza 0 loaded units listed. To, co faktycznie się wydarzyło, zostaje na trwałe w /var/log/apt/history.log, a pełne wyjście dpkg w /var/log/apt/term.log.
Wstrzymane pakiety: dwie różne przyczyny
Gdy apt pomija pakiety, stoją za tym dwa całkowicie różne powody, które regularnie bywają mylone.
Po pierwsze, prawdziwa blokada. Ktoś świadomie przypiął pakiet:
apt-mark showhold
Jeśli polecenie coś wypisze, była to świadoma decyzja, najczęściej przy bazach danych albo modułach kernela. Zdejmiesz ją przez apt-mark unhold NAZWA_PAKIETU, założysz przez apt-mark hold NAZWA_PAKIETU. Blokadę na poziomie dpkg zobaczysz poleceniem dpkg --get-selections | grep -w hold.
Po drugie, komunikat The following packages have been kept back:. To nie jest blokada. Oznacza on, że apt musiałby na potrzeby tej aktualizacji doinstalować jakiś pakiet albo któryś usunąć, a użyte polecenie nie ma do tego prawa. Dowód w jednym wierszu, bez zmieniania czegokolwiek:
apt full-upgrade -s | head -n 20
Jeśli pakiet się tam pojawi, wyjaśnienie zostało znalezione, a apt full-upgrade sprawę rozwiązuje. W Debianie 13 nowsza generacja apt formatuje to wyjście inaczej, treściowo nic się nie zmienia.
Przypadek szczególny: Ubuntu. Ubuntu udostępnia aktualizacje stopniowo, nie wszystkie serwery dostają je tego samego dnia. Pakiet może więc zostać wstrzymany, choć nie ma ani blokady, ani zależności stojącej na drodze. Diagnoza idzie przez wykluczanie: apt-mark showhold jest puste, apt full-upgrade -s nie pokazuje żadnego usunięcia, a apt-cache policy NAZWA_PAKIETU mimo to podaje nowszego kandydata. Wtedy poczekaj kilka dni albo ściągnij aktualizację przed czasem:
apt -o APT::Get::Always-Include-Phased-Updates=true upgrade
W Debianie 13 i Debianie 12 stopniowego udostępniania nie ma, tam ta przyczyna odpada z góry.
Gdy apt pyta o plik konfiguracyjny
To pytanie pojawia się tylko wtedy, gdy jednocześnie zachodzą dwa warunki: plik został po instalacji zmieniony lokalnie, a pakiet przynosi ze sobą nową wersję. Wygląda ono tak:
Configuration file '/etc/ssh/sshd_config'
==> Modified (by you or by a script) since installation.
==> Package distributor has shipped an updated version.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.
*** sshd_config (Y/I/N/O/D/Z) [default=N] ?
Ustawieniem domyślnym jest N, czyli zachowanie twojej wersji. To odpowiedź bezpieczna, ale nie w każdym przypadku właściwa.
| Sytuacja | Odpowiedź |
|---|---|
| Nie pamiętasz już, co zostało zmienione | D, obejrzyj różnicę, potem zdecyduj |
| Twoje zmiany są świadome, pakiet zmienia tylko komentarze | N, potem porównaj plik .dpkg-dist |
| Plik pochodzi z narzędzia takiego jak cloud-init albo Ansible | N, potem uruchom to narzędzie ponownie |
| Nowe ustawienia dotyczą bezpieczeństwa, twoja zmiana jest zbędna | Y, potem ustaw swoje zmiany od nowa |
| Plik krytyczny, a ty nie masz pewności | Z, skopiuj plik na bok, wyjdź z shella, potem N |
Przy /etc/ssh/sshd_config wskazana jest szczególna ostrożność: Y potrafi przywrócić PermitRootLogin i PasswordAuthentication do wartości z pakietu, a właśnie na tym wisi twój dostęp. Dlatego własne ustawienia SSH należą do osobnego pliku w /etc/ssh/sshd_config.d/, tak jak opisuje to artykuł zabezpieczenie SSH i logowanie kluczem. Plik, którego w pakiecie w ogóle nie ma, nigdy nie wywoła pytania.
Niezależnie od tego, jak odpowiesz, dpkg niczego nie wyrzuca. Przy N nowa wersja ląduje obok jako .dpkg-dist, przy Y twoja stara jako .dpkg-old. Przejrzenie tych plików to właściwa praca do wykonania po aktualizacji:
find /etc -name '*.dpkg-dist' -o -name '*.dpkg-old' -o -name '*.dpkg-new' -o -name '*.ucf-dist'
diff -u /etc/ssh/sshd_config /etc/ssh/sshd_config.dpkg-dist
Przy przebiegach bez nadzoru, na przykład w skrypcie konserwacyjnym, ustal zachowanie zawczasu. Ta kombinacja zachowuje twoją wersję i o nic nie pyta:
DEBIAN_FRONTEND=noninteractive apt-get -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
upgrade
--force-confnew byłoby przeciwieństwem i bierze zawsze wersję z pakietu. Na serwerze z własną konfiguracją rzadko o to ci chodzi.
Aktualizacje kernela i pytanie o restart
Nowy kernel ląduje przy instalacji w /boot oraz w menu startowym. Działający kernel zostaje w pamięci bez zmian aż do restartu. Serwer może więc być jednocześnie w pełni zaktualizowany i podatny. Najprostszym dowodem jest porównanie:
uname -r
ls -1 /boot/vmlinuz-*
Jeśli w /boot stoi wyższa wersja, niż zgłasza uname -r, restart jest konieczny. W Ubuntu 24.04 i 22.04 istnieje dodatkowo plik znacznika, który uwzględnia także aktualizacje bibliotek:
test -f /var/run/reboot-required && cat /var/run/reboot-required.pkgs
Drugi plik wymienia pakiety, które zażądały restartu. W Debianie 13 i Debianie 12 ten znacznik nie powstaje niezawodnie, tam właściwą drogą jest needrestart.
needrestart: które usługi wciąż używają starej biblioteki
Aktualizacja OpenSSL albo glibc podmienia plik na dysku. Każdy proces, który wczytał go wcześniej, pracuje dalej ze starą wersją. needrestart znajduje dokładnie te procesy. W Ubuntu 24.04 i 22.04 jest preinstalowany i po każdej aktualizacji zgłasza się pełnoekranowym pytaniem, w Debianie doinstalujesz go sam:
apt install -y needrestart
needrestart -b
Tryb -b daje wyjście czytelne dla maszyny. Dwie informacje z niego są rozstrzygające: NEEDRESTART-KSTA o wartości 1 oznacza, że działający kernel jest tym oczekiwanym, każda inna wartość mówi, że nowszy już czeka. Każdy wiersz NEEDRESTART-SVC wymienia usługę, którą należy zrestartować.
Zachowaniem sterujesz zmienną środowiskową NEEDRESTART_MODE: a restartuje usługi automatycznie, l tylko je wypisuje, i pyta. Na stałe to samo stoi w /etc/needrestart/needrestart.conf. Do skryptów zmienna jest lepszym wyborem, bo niczego nie rusza w konfiguracji:
NEEDRESTART_MODE=a DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
Jedno ograniczenie warto znać: needrestart patrzy na procesy systemu gospodarza. Usług w kontenerach nie odnawia, tam potrzebujesz nowych obrazów.
Zmiana wersji dystrybucji to osobna kategoria
Przejście z Debiana 12 na Debiana 13 albo z Ubuntu 22.04 na 24.04 nie jest aktualizacją w powyższym sensie. Podmienia źródła pakietów i zastępuje praktycznie każdy pakiet. Zawsze obowiązują przy tym trzy zasady: jedna wersja na jeden przebieg, żadnych pominiętych wersji pośrednich oraz wcześniejsza kopia zapasowa, z której da się serwer odtworzyć.
W Debianie najpierw przestawiasz źródła. Debian 12 używa do tego /etc/apt/sources.list, Debian 13 pliku /etc/apt/sources.list.d/debian.sources w nowszym formacie. Potem następuje świadomie dwustopniowy przebieg, tak jak nakazują informacje o wydaniu:
apt update
apt-get upgrade --without-new-pkgs
apt full-upgrade
Środkowy krok aktualizuje najpierw te pakiety, które obchodzą się bez przebudowy. Utrzymuje to małą liczbę pakietów ruszanych naraz i sprawia, że przerwanie da się naprawić. Nie zapomnij o komponencie non-free-firmware: od Debiana 12 jest samodzielny i brakuje go w starych plikach źródeł. Jeśli twój apt zna polecenie apt modernize-sources (sprawdzisz to przez apt --version), przeniesie ono stary plik źródeł do nowego formatu.
W Ubuntu jest do tego osobne narzędzie i powinieneś używać wyłącznie jego:
apt install -y ubuntu-release-upgrader-core
do-release-upgrade -c
do-release-upgrade
Przełącznik -c tylko sprawdza i niczego nie zmienia. To, czy przejście w ogóle zostanie zaproponowane, zależy od Prompt w /etc/update-manager/release-upgrades: przy lts pojawia się wyłącznie skok do następnej wersji LTS, i to dopiero po jej pierwszym wydaniu poprawkowym. Droga z 20.04 na 24.04 prowadzi obowiązkowo przez 22.04.
Szczegół, który wielu zaskakuje: gdy do-release-upgrade pracuje przez SSH, uruchamia dodatkową usługę SSH na porcie 1022 jako wariant awaryjny i zwraca uwagę, że ten port trzeba w razie potrzeby otworzyć w firewallu. Skorzystaj z tego, ale się na tym nie opieraj. Sesja tmux oraz dostęp przez konsolę VNC są pewniejsze.
Sprzątanie po aktualizacji
Po większym przebiegu zostają trzy rodzaje pozostałości: pobrane pliki pakietów, osierocone pakiety oraz resztki konfiguracji po usuniętych pakietach.
apt autoremove --purge
apt autoclean
autoclean kasuje z /var/cache/apt/archives tylko te pliki, które i tak nie są już oferowane. apt clean opróżnia cały cache, daje więc więcej miejsca, ale za to każda ponowna instalacja staje się nowym pobieraniem.
Resztki konfiguracji rozpoznasz po statusie dpkg rc, czyli usunięty, ale konfiguracja nadal obecna:
dpkg -l | awk '/^rc/ {print $2}'
To, co tam stoi, usuniesz ostatecznie poleceniem apt purge NAZWA_PAKIETU. Przy starych kernelach wskazana jest większa staranność, bo pomyłka sprawi, że serwer się nie uruchomi:
uname -r
dpkg -l 'linux-image-*' | awk '/^ii/ {print $2}'
Nigdy nie usuwaj kernela, który wymienia pierwszy wiersz, i zachowaj dodatkowo jeden starszy, sprawny, żeby menu startowe miało wariant awaryjny. Najczęściej apt autoremove --purge i tak załatwia to poprawnie.
Typowe błędy i ich rozwiązania
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (unattended-upgr): druga operacja na pakietach już trwa, najczęściej automatyczna aktualizacja bezpieczeństwa. Nie przerywaj jej, tylko pozwól dobiec do końca. Pełny sposób postępowania wraz z naprawą stoi w artykule naprawa błędu apt „Could not get lock”.
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.: wcześniejszy przebieg został przerwany, typowo przez zerwanie połączenia. Wykonaj dokładnie to polecenie, a potem powtórz aktualizację.
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).: pakiet jest zainstalowany, a brakuje jego zależności. apt --fix-broken install je dociąga. Jeśli błąd wraca, prawie zawsze winne jest zewnętrzne repozytorium, które oferuje pakiety dla innej wersji dystrybucji.
E: Release file for http://deb.debian.org/debian/dists/trixie/InRelease is not valid yet (invalid for another 5h 3min 2s).: zegar serwera się spóźnia. Sprawdź przez timedatectl status, czy zgłaszane jest System clock synchronized: yes, popraw czas i powtórz apt update. Repozytorium nie ma z tym nic wspólnego.
W: GPG error: ... The following signatures couldn't be verified because the public key is not available: NO_PUBKEY ..., a po nim E: The repository '...' is not signed.: brakuje klucza podpisu zewnętrznego repozytorium albo klucz został wymieniony. Klucz należy dziś umieszczać w /etc/apt/keyrings/ i wskazywać go we wpisie źródła przez signed-by względnie przez pole Signed-By:. apt-key jest wycofany i nie powinno się go już używać.
E: Repository '... InRelease' changed its 'Suite' value from 'stable' to 'oldstable': to dzieje się normalnie, gdy ukazuje się nowa wersja Debiana, a twoje źródła wskazują na stable zamiast na nazwę kodową. Potwierdź jednorazowo przez apt update --allow-releaseinfo-change, a potem przestaw źródła na nazwę kodową. Serwer, który podąża za stable, w przeciwnym razie kiedyś niechcący zmieni wersję dystrybucji.
E: The repository 'http://... Release' does not have a Release file.: źródło nie oferuje niczego dla twojej wersji, najczęściej dlatego, że zewnętrzne repozytorium nie obsługuje jeszcze tej nazwy kodowej albo dystrybucja doszła do końca wsparcia. Wyłącz odpowiedni wiersz i sprawdź źródło.
No space left on device w środku rozpakowywania: /boot albo /var są pełne. Uporządkuj stan poleceniem dpkg --configure -a, zrób miejsce, powtórz. Przed każdą aktualizacją kernela opłaca się rzut oka na df -h /boot.
debconf: unable to initialize frontend: Dialog: to tylko wskazówka, nie awaria. Pojawia się bez w pełni wyposażonego terminala, na przykład w skrypcie. Z DEBIAN_FRONTEND=noninteractive znika.
Porównanie czterech systemów
| Zagadnienie | Debian 13 | Debian 12 | Ubuntu 24.04 | Ubuntu 22.04 |
|---|---|---|---|---|
| Plik źródeł | sources.list.d/debian.sources | sources.list | sources.list.d/ubuntu.sources | sources.list |
| needrestart | doinstalować | doinstalować | preinstalowany | preinstalowany |
| Znacznik restartu | zawodny, użyj needrestart | zawodny, użyj needrestart | /var/run/reboot-required | /var/run/reboot-required |
| Stopniowe udostępnianie | nie | nie | tak | tak |
| Zmiana wersji | przestawić źródła, potem dwustopniowo | do-release-upgrade | ||
Kontrola końcowa
To, że polecenie wróciło bez błędu, nie znaczy jeszcze, że system jest w porządku. Dopiero tych sześć kontroli coś mówi:
apt list --upgradablenie wypisuje nic pozaListing....apt-mark showholdzawiera tylko to, co świadomie zablokowałeś.dpkg --auditmilczy.needrestart -bzgłaszaNEEDRESTART-KSTA: 1i żadnych czekających usług.systemctl --failedniczego nie wymienia.find /etc -name '*.dpkg-dist'nic już nie znajduje, bo każdą rozbieżność masz przerobioną.
Jeśli punkt czwarty domaga się restartu, zaplanuj go i przeprowadź. Serwer, który miesiącami czeka na zaległy restart, zbiera dokładnie te luki, przeciwko którym w ogóle aktualizowałeś. Sprawdź potem ostatni raz uname -r oraz systemctl --failed. Restart jest tym momentem, w którym okazuje się, czy wszystko znowu wstaje.
Najczęstsze pytania
Czym różni się apt upgrade od apt full-upgrade?
Czy dist-upgrade oznacza przejście na następną wersję dystrybucji?
Dlaczego apt zgłasza „The following packages have been kept back”?
apt pyta, czy ma zastąpić plik konfiguracyjny. Co odpowiedzieć?
Po czym poznam, że po aktualizacji potrzebny jest restart?
Po co mi needrestart, skoro i tak restartuję serwer?
Jak aktualizować bez nadzoru, żeby przebieg nie zawisł na pytaniu?
Czy aktualizacją mogę zamknąć sobie dostęp do serwera?
2026 KernelHost GmbH. Wszelkie prawa zastrzeżone. Ten poradnik jest chroniony prawem autorskim. Publikowanie go w innych serwisach, w całości, we fragmentach lub w zmienionej formie, wymaga naszej pisemnej zgody. Cytaty z podaniem źródła i z linkiem są jak najbardziej mile widziane.

