Aktualizacje bez niespodzianek: jak zarządzany serwer pozostaje aktualny
Aktualizacja, której nie zauważasz
Najlepsza aktualizacja serwera jest nudna. Zespół otwiera pocztę, pliki, zdjęcia, hasła albo VPN dokładnie tak jak wczoraj. Wersja się zmieniła. Poprawka bezpieczeństwa została wgrana. Nic więcej nie stało się Twoim problemem.
To trudniejsze, niż brzmi. Aktualizacje są potrzebne, bo oprogramowanie się starzeje: zależności się zmieniają, luki wychodzą na jaw, a dostawcy kończą wspieranie starych wydań. Ale aktualizacja też jest zmianą, a zmiana może popsuć rzeczy dookoła. W lipcu 2024 roku wadliwa aktualizacja treści CrowdStrike zakłóciła działanie komputerów z Windowsem na całym świecie; Microsoft szacował, że incydent dotknął 8,5 miliona urządzeń z Windowsem, czyli mniej niż 1% takich urządzeń, ale wystarczyło to, żeby zakłócić pracę przedsiębiorstw obsługujących kluczowe usługi (Microsoft, CrowdStrike).
Ten incydent nie jest argumentem przeciwko aktualizowaniu. Jest argumentem przeciwko wgrywaniu każdej zmiany wszędzie i od razu. Rozsądny środek to zmiana pod kontrolą.
Dlaczego przypinamy wersje zamiast gonić za latest
Serwer małej firmy nie powinien składać się z tego, co akurat dziś rano ktoś opublikował. Etykiety typu latest są wygodne do prób, ale w produkcji utrudniają kontrolę. Jeśli ta sama komenda instalacji może pobrać inne oprogramowanie w poniedziałek i inne we wtorek, nie da się go rzetelnie przetestować, wycofać ani wyjaśnić, skąd wzięła się zmiana zachowania.
Dokumentacja Dockera wprost opisuje tę różnicę. Etykiety obrazów są zmienne: wydawca może w każdej chwili przestawić etykietę taką jak alpine:3.21 na inny obraz, więc ta sama linia FROM alpine:3.21 przy każdej przebudowie „resolves to the latest patch version for 3.21” (wskazuje najnowszą wersję poprawek dla 3.21) — jaka akurat wtedy jest aktualna. Przypięcie przez digest usuwa tę niejednoznaczność: „By pinning your images to a digest, you’re guaranteed to always use the same image version, even if a publisher replaces the tag with a new image” (przypinając obrazy do skrótu (digest), masz gwarancję, że zawsze użyjesz tej samej wersji obrazu, nawet jeśli wydawca podmieni etykietę na nowy obraz) (dokumentacja Dockera). Odwołanie przypięte przez digest wygląda tak:
image: myapp:1.4.2@sha256:<64 znaki hex>
Dokumentacja Dockera wprost nazywa też koszt tego rozwiązania: przypięcie przez digest oznacza „opting out of automated security fixes” (rezygnację z automatycznych poprawek bezpieczeństwa), bo nic samo nie przesunie digestu naprzód. Dokumentacja proponuje łączyć przypięcie przez digest z narzędziem, które samo otwiera zgłoszenie aktualizacji (wymienia obsługę ekosystemu Docker w Dependabocie), zamiast przypinać i zapominać.
Ta sama zasada działa wyżej: wersje aplikacji, baz danych, dodatków i szablonów konfiguracji powinny być zapisane wprost — czy to przez digest, czy przez etykietę wersji wraz z udokumentowanym procesem jej podnoszenia.
Przypięcie wersji to nie zamrożenie. Każdy serwer ma znany skład: tę wersję Nextclouda, tę wersję PostgreSQL, tę wersję serwera pośredniczącego, dokładnie tę konfigurację. Kiedy pojawia się aktualizacja, można spokojnie porównać stare z nowym. Jeśli coś pójdzie źle, da się sprawdzić, co się zmieniło.
Jak wygląda bezpieczny proces aktualizacji
Bezpieczny proces aktualizacji przepuszcza zmianę przez trzy bramki, zanim trafi ona na prawdziwy serwer.
Pierwszą bramką są sprawdzenia składni i statyczna kontrola. Konfiguracja musi się poprawnie wczytać. Szablony muszą się wyrenderować. Oczywiste błędy powinny zostać wyłapane, zanim dotkną prawdziwego serwera.
Drugą bramką są testy kontraktowe. Każda zarządzana aplikacja ma kilka obietnic ważniejszych niż lista zmian. Rzetelny test kontraktowy sprawdza co najmniej:
- czy logowanie działa przez zwykłą ścieżkę uwierzytelnienia aplikacji
- czy punkt kontroli stanu (health check) aplikacji odpowiada
- czy katalogi z danymi są podpięte tam, gdzie aplikacja ich oczekuje
- czy zadanie kopii zapasowej dalej kończy się poprawnie po aktualizacji
- czy serwer pośredniczący nadal kieruje ruch we właściwe miejsce
- czy aplikacja nadal dogada się ze swoją bazą danych i może czytać oraz zapisywać dane
To rzeczy, które użytkownik odczuje natychmiast, gdy zawiodą — dlatego są sprawdzane, zanim cokolwiek innego.
Trzecia bramka to ta, którą większość ludzi ma na myśli, mówiąc o bezpiecznych aktualizacjach, i zarazem najtrudniejsza: sprawdzenie zmiany na czymś, co można zepsuć, zanim trafi na coś, czego zepsuć nie wolno. W praktyce znaczy to najpierw małą, odwracalną próbę, sposób na sprawdzenie, czy próba naprawdę wróciła do zdrowia, i moment decyzji, zanim zmiana pójdzie dalej. Awaria nadal jest możliwa; chodzi o to, żeby jedna zła zmiana pozostała mała, widoczna i możliwa do cofnięcia. To, kiedy zmiana trafia na serwer klienta, a nie na maszynę kontrolowaną przez operatora, jest tą częścią zarządzanych aktualizacji, która dopiero powstaje.
Takie podejście pasuje do głównego nurtu zaleceń dla łańcucha dostaw oprogramowania. NIST Secure Software Development Framework mówi o ochronie oprogramowania przed podmianą, weryfikowaniu integralności wydań i przechowywaniu danych o pochodzeniu każdego wydania (NIST SP 800-218). SLSA opisuje tę samą myśl dla procesu budowania: trzeba wiedzieć, skąd pochodzą artefakty, i utrudniać przemycenie nieuprawnionych zmian (SLSA v1.0).
To standardy pisane dla producentów oprogramowania, ale ta sama myśl przenosi się na utrzymanie serwera. Dla właściciela firmy najważniejsze jest coś prostszego: plan aktualizacji nie powinien powstawać dopiero w dniu, w którym pojawi się luka.
Co z tego wynika dla Ciebie
Przez większość czasu dobrze utrzymany serwer nie powinien niczego pokazywać.
Firma nie powinna wybierać między pięcioma wersjami bazy danych, czytać wątków na forum, żeby sprawdzić, czy dodatek przestanie działać po aktualizacji, ani odkrywać w trakcie pracy dla klienta, że serwer plików wymaga ręcznej naprawy, bo kontener po cichu przeskoczył na nowe wydanie główne. Do tego służy dyscyplina przypinania wersji i trzy opisane wyżej bramki: znany skład serwera i zmiana, która zdążyła się już sprawdzić, zanim trafi na produkcję.
Dziś aktualizację na serwerze principale uruchamiasz sam, z panelu. Większość obrazów w katalogu jest przypięta do dokładnej wersji, a wiele także do niezmiennego skrótu obrazu; kilka, np. obrazy Nextclouda, wciąż korzysta z ruchomej etykiety wersji. Centralnie zarządzane aktualizacje, uruchamiane za Ciebie, dopiero powstają.
Celem jest oprogramowanie bez niespodzianek. Poprawki bezpieczeństwa trafiają na miejsce. Aplikacje pozostają aktualne. Twój dzień pracy toczy się dalej.
principale.dev instaluje takie narzędzia open source na serwerze, który należy do Ciebie. Każda instalacja jest darmowa. Zobacz, jak to działa.