Posłuchaj wersji podcastowej:
Klonowanie maszyn wirtualnych z szablonu w Proxmox
Klonując maszynę wirtualną (np. z szablonu kontenera LXC w Proxmox) dostajemy gotowe środowisko. Z jednej strony fajnie, bo jest już wstępnie skonfigurowane i nie musimy od nowa instalować narzędzi i aktulizacji, ale z drugiej strony niekoniecznie fajnie, bo nasza praca nie kończy się na sklonowaniu i przypisaniu nowej nazwy hosta oraz IP, ponieważ:
maszyna ta będzie nam się w różnych sytuacjach przedstawiać tak samo jak pozostałe utworzone z tego szablonu
Ma to istotne znaczenie m.in. dla komunikacji za pośrednictwem protokołu SSH.
Przy inicjalizacji każdego nowego połączenia, nasz lokalny klient SSH dodaje odcisk palca maszyny do pliku known_hosts.
Ten odcisk palca tworzony jest na podstawie kluczy hosta, przechowywanych w katalogu /etc/ssh/
.
Jeżeli mamy wiele hostów z tymi samymi kluczami, nasz klient SSH myśli, że za każdym razem nawiązuje połączenie z tym samym serwerem.
Ze względu m.in. na to, że każdy z nich ma inny adres IP, klient podejrzewa atak typu man in the middle.
Generalnie w momencie, gdy nasz klient SSH wyświetla nam odcisk palca serwera i pyta, czy chcemy kontynuować, zwykle bez zastanowienia dajemy yes
, ale dobrą praktyką jest… czytanie komunikatów 😉 i sprawdzenie, czy to rzeczywiście jest TEN serwer.
Dlatego też, po utworzeniu nowej maszyny warto wygenerować nowy zestaw kluczy dla hosta.
Btw. dobrą praktyką robienie tego po utworzeniu maszyny wirtualnej z szablonu u dostawców chmurowych.
W środowiskach chmurowych większość dostawców automatycznie generuje unikalne klucze hosta podczas tworzenia nowej maszyny z wykorzystaniem cloud-init
.
Znacząco podnosi to poziom bezpieczeństwa – każda instancja otrzymuje własny identyfikator kryptograficzny, eliminując ryzyko powielania kluczy między różnymi VM. Dzięki temu minimalizujemy zagrożenie atakami typu man-in-the-middle oraz unikamy problemów z rozpoznawaniem hostów przez klientów SSH, co jest szczególnie istotne w dynamicznych, wieloserwerowych środowiskach chmurowych.
Jeżeli usuniesz klucze hosta i zakończysz połączenie, to nie połączysz się z tym serwerem w ogóle. Przy próbie połączenia dostaniesz komunikat:
kex_exchange_identification: read: Connection reset by peer
Aktywne połączenie nie zostanie przerwane samo z siebie po usunięciu kluczy hosta, ale dokonując zmian jakichkolwiek ustawień serwera SSH, zanim zamkniemy bieżące połączenie, warto w drugim oknie sprawdzić, czy właśnie nie zepsuliśmy czegoś tak bardzo, że zostaliśmy odcięci.
Generowanie nowego zestawu kluczy
Aby wygenerować nowy zestaw kluczy:
usunięcie starych kluczy
sudo rm -f -v /etc/ssh/ssh_host*key*
wygenerowanie nowych kluczy
ssh-keygen -A -v
Klucze powinny zostać zapisane w katalogu /etc/ssh/.
próba nawiązania nowego połączenia
Nawiązując nowe połączenie ssh w drugim oknie terminala powinnno wyświetlić się ostrzeżenie.
usunięcie starego odcisku palca na komputerze klienta
(na linuksie): /home/<nazwa_użytkownika>/.ssh/known_hosts (na macu): /Users/<nazwa_użytkownika>/.ssh/known_hosts
Korzystając z vima można to zrobić trzema skrótami:
- przejście do ostatniej linii: shift + g
- usunięcie linii: d d albo: shift + d
- zapis i wyjście z pliku: Z Z (w razie czego, jak nie chcesz zapisywać zmian to: Z Q)
Automatyzacja z użyciem cloud-init w Proxmox
Zanim przejdziemy dalej, warto wiedzieć, że Proxmox obsługuje narzędzie cloud-init, które pozwala na automatyzację wielu czynności konfiguracyjnych podczas pierwszego uruchomienia maszyny wirtualnej – w tym również generowanie unikalnych kluczy hosta SSH.
Jeśli korzystasz z cloud-init, nie musisz ręcznie przygotowywać jednostki systemd – wystarczy odpowiednia konfiguracja w panelu Proxmox, a klucze zostaną wygenerowane automatycznie, podobnie jak u większości dostawców chmurowych.
To rozwiązanie jest szczególnie wygodne w środowiskach, gdzie często klonujesz lub tworzysz nowe VM.
Automatyzacja z wykorzystaniem szablonu maszyny wirtualnej
Aby uniknąć tego problemu, możemy odpowiednio przygotować maszynę, która będzie służyć za szablon. Najlepiej wykorzystać do tego świeżą instalację systemu o długim wsparciu (np. Ubuntu w wersji LTS) z podstawową konfiguracją - dopasowaną do potrzeb naszej infrastruktury.
utworzenie jednostki systemd
sudo vi /etc/systemd/system/regenerate_ssh_host_keys.service
[Unit]
Description=Regenerate SSH host keys
Before=ssh.service
ConditionFileIsExecutable=/usr/bin/ssh-keygen
[Service]
Type=oneshot
ExecStartPre=-/bin/dd if=/dev/hwrng of=/dev/urandom count=1 bs=4096
ExecStartPre=-/bin/sh -c "/bin/rm -f -v /etc/ssh/ssh_host_*_key*"
ExecStart=/usr/bin/ssh-keygen -A -v
ExecStartPost=/bin/systemctl disable regenerate_ssh_host_keys
[Install]
WantedBy=multi-user.target
przeładowanie demona
sudo systemctl daemon-reload
aktywacja usługi
sudo systemctl enable regenerate_ssh_host_keys.service
Jeżeli spojrzysz w plik jednostki usług, to zauważysz, że w jednym z ostatnich kroków znajduje się polecenie dezaktywacji po pierwszym przebiegu - bez tego przy każdym uruchomieniu maszyny klucze byłby resetowane od nowa.
utworzenie szablonu w Proxmox
Zamknij maszynę i utwórz z niej szablon w interfejsie Proxmox.
Przy kolejnym uruchomieniu tej maszyny klucze zostaną zresetowane, więc dopilnuj, żeby zaraz po aktywowaniu jednostki (krok 5.) została ona zamknięta a nie np. zrestartowana.