Jak zmienić port SSH w systemach RHEL, Rocky i AlmaLinux
Dowiedz się jak bezpiecznie zmienić port SSH bez utraty dostępu. Instrukcja obejmuje konfigurację sshd_config, dodanie reguły w firewalld oraz aktualizację etykiety portu w SELinux.
Dlaczego zmiana portu SSH wymaga tutaj trzech kroków
Aby zmienić port SSH w systemach Rocky Linux, AlmaLinux, CentOS Stream lub Fedora, jedna edycja nie wystarczy. Trzy oddzielne systemy decydują o tym, czy połączenie na nowym porcie będzie działać. firewalld decyduje, czy pakiet dotrze do maszyny. SELinux decyduje, czy sshd w ogóle może przypisać się do tego numeru portu. sshd_config określa, o który port prosi demon. Pominięcie kroku z SELinux spowoduje, że demon odmówi uruchomienia. Pominięcie kroku z firewalld sprawi, że usługa wystartuje i będzie nasłuchiwać, ale nikt nie uzyska do niej dostępu.
W systemie Ubuntu to samo zadanie wymaga jednej edycji i restartu, ponieważ Ubuntu używa AppArmor zamiast SELinux i nie dostarcza profilu ograniczającego porty, do których może przypisać się sshd. Jeśli działa tam ufw, należy dodać tylko jedną regułę. Na tym polega cała różnica. Rodzina systemów RHEL ma domyślnie uruchomiony firewalld oraz SELinux w trybie enforcing, a oba te mechanizmy kontrolują numery portów.
Wykonaj pracę w tej kolejności, aby bieżąca sesja pozostała aktywna na każdym etapie:
- Otwórz nowy port w firewalld, pozostawiając port 22 otwarty na ten moment.
- Dodaj etykietę SELinux dla nowego portu za pomocą
semanage. - Ustaw port w konfiguracji sshd.
- Zrestartuj
sshd, a następnie zaloguj się na nowy port z drugiego terminala przed zamknięciem pierwszego.
Przed rozpoczęciem znajdź konsolę internetową swojego dostawcy (VNC lub szeregową) i sprawdź, czy możesz się przez nią zalogować. Ta konsola jest drogą powrotu, jeśli zmiana się nie powiedzie. Zmiana portu jest jedną z najczęstszych przyczyn, dla których użytkownik traci dostęp do serwera, za który właśnie zapłacił.
Najpierw zainstaluj semanage
semanage to narzędzie służące do edycji ustawień polityki SELinux, a minimalna instalacja Rocky Linux lub AlmaLinux go nie zawiera. Znajduje się ono w pakiecie policycoreutils-python-utils.
sudo dnf install -y policycoreutils-python-utilsUruchomienie tego polecenia przed zainstalowaniem pakietu skutkuje błędem sudo: semanage: command not found i jest to moment, w którym wielu użytkowników decyduje, że SELinux nie jest zainstalowany i pomija ten krok. SELinux jest zainstalowany. Brakuje jedynie narzędzia do zarządzania. Jeśli składnia dnf jest nowa, odpowiedniki poleceń dnf i apt pozwolą odnieść ją do znanych już rozwiązań.
Wybór portu i weryfikacja jego dostępności
Można użyć dowolnego wolnego portu TCP z zakresu od 1024 do 65535. Przed podjęciem decyzji należy wykonać dwa sprawdzenia:
sudo ss -tlnp | grep -w 2222
sudo semanage port -l | grep -w 2222Pierwsze polecenie wskazuje, czy proces już nasłuchuje na danym numerze. Drugie sprawdza, czy polityka SELinux przypisuje go już do innego typu usługi. Wolny port nie zwraca żadnych wyników w obu przypadkach. Jeśli port jest już zajęty przez politykę, polecenie semanage port -a w kroku 2 zakończy się błędem ValueError: Port tcp/2222 already defined; rozwiązaniem jest wybór innego numeru.
W całym przewodniku jako przykładu użyto portu 2222. Jest to również pierwszy port sprawdzany przez skanery po porcie 22, dlatego na serwerze produkcyjnym warto wybrać mniej oczywistą wartość.
Krok 1: otwarcie portu w firewalld
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports--permanent zapisuje regułę w pliku strefy na dysku i nie ingeruje w działający firewall. --reload ładuje konfigurację z dysku do działającego firewalla. Pominięcie przeładowania sprawia, że reguła istnieje, ale nie działa do czasu kolejnego restartu firewalld, co jest jedną z najczęstszych przyczyn pozornego niepowodzenia całej procedury.
Na razie należy pozostawić wpis usługi ssh bez zmian. Ten wpis utrzymuje port 22 otwartym i stanowi zabezpieczenie na czas testów.
Należy również sprawdzić panel sterowania dostawcy. Wielu dostawców utrzymuje sieciowy firewall przed VPS, poza systemem operacyjnym, więc port otwarty w firewalld może być nadal blokowany na poziomie nadrzędnym. Podstawowy przewodnik po firewalld dla VPS omawia strefy oraz różnice między konfiguracją działającą (runtime) a trwałą (permanent), jeśli ten model jest nowy.
Krok 2: przypisanie portu dla SELinux
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo semanage port -l | grep ssh_port_t-a dodaje nowe przypisanie portu. -t ssh_port_t to typ przypisywany portom SSH. Drugie polecenie wyświetla wszystkie porty obsługiwane przez ssh_port_t, co pozwala potwierdzić dodanie numeru portu przed wprowadzeniem zmian w demonie.
Dlaczego SELinux w ogóle blokuje port
SELinux (Security-Enhanced Linux) nadaje każdemu obiektowi w systemie etykietę, a numery portów TCP są obiektami takimi jak każde inne. Demon SSH działa w ramach domeny o nazwie sshd_t. Polityka zezwala sshd_t na wiązanie portów TCP oznaczonych etykietą ssh_port_t, a domyślnie jedynym portem z taką etykietą jest 22. Jeśli demon otrzyma polecenie powiązania z portem 2222, jądro sprawdza etykietę, odnajduje ogólny typ przypisany w polityce do tego numeru i odmawia uprawnienia name_bind dla gniazda.
Dlatego ten błąd nie wygląda na problem z firewallem. Jądro odmawia dostępu, zanim gniazdo nasłuchujące w ogóle powstanie, więc sshd zgłasza błąd i kończy działanie. Problem z firewallem to sytuacja odwrotna: demon działa poprawnie, a pakiety są odrzucane w drodze do niego.
getenforce informuje o trybie, w jakim znajduje się system. W trybie Permissive odmowa jest rejestrowana, ale nie jest egzekwowana, więc zmiana portu wydaje się działać, dopóki ktoś nie uruchomi setenforce 1 lub system nie zrestartuje się w trybie wymuszania (enforcing). Należy nadać etykietę portowi w obu przypadkach. Podstawowy przewodnik po SELinux dla serwera szczegółowo omawia tryby, konteksty i wartości logiczne (booleans).
Krok 3: ustawienie portu w konfiguracji sshd
W systemach Rocky Linux 9 i 10, AlmaLinux 9 i 10 oraz bieżących wersjach Fedora plik /etc/ssh/sshd_config rozpoczyna się od dyrektywy include, dlatego najwłaściwszym miejscem na wprowadzenie zmian jest osobny plik konfiguracyjny (drop-in). Dzięki temu aktualizacje pakietów nie nadpiszą wprowadzonych modyfikacji.
grep -n '^Include' /etc/ssh/sshd_config
echo 'Port 2222' | sudo tee /etc/ssh/sshd_config.d/10-port.conf
sudo sshd -tJeśli grep nie zawiera linii Include, co ma miejsce w Rocky Linux 8 i innych starszych obrazach, należy umieścić Port 2222 bezpośrednio w /etc/ssh/sshd_config. Polecenie sshd -t analizuje całą konfigurację, w tym pliki drop-in, i zgłasza błędy składni. Należy usunąć wszelkie zgłoszone błędy przed restartem, ponieważ niepoprawna składnia uniemożliwi ponowne uruchomienie demona.
Dyrektywa Port może wystąpić więcej niż raz, a sshd nasłuchuje na każdym wskazanym porcie. Pozostawienie Port 22 obok Port 2222 przez pierwszy dzień stanowi tanie zabezpieczenie, pod warunkiem, że pamięta się o późniejszym usunięciu starego portu.
Czy usługa sshd jest uruchamiana przez jednostkę typu socket?
Niektóre obrazy systemowe uruchamiają SSH poprzez mechanizm socket activation w systemd, zamiast jako usługę działającą w tle. W takiej konfiguracji systemd zarządza gniazdem nasłuchującym i przekazuje połączenia do sshd, dlatego dyrektywa Port w pliku sshd_config jest całkowicie ignorowana. Przed wykonaniem jakiegokolwiek restartu należy sprawdzić konfigurację:
systemctl is-enabled sshd.socketOdpowiedź enabled oznacza, że port jest zdefiniowany w jednostce typu socket, a nie w pliku sshd_config:
sudo systemctl edit sshd.socket[Socket]
ListenStream=
ListenStream=2222Wymagane jest użycie pustej dyrektywy ListenStream=. Wartości w plikach konfiguracyjnych sumują się, więc bez wyczyszczenia listy gniazdo będzie nasłuchiwać zarówno na porcie 22, jak i 2222. Zastosuj zmianę za pomocą sudo systemctl daemon-reload, a następnie wykonaj sudo systemctl restart sshd.socket. Jeśli jednostka jest wyłączona lub nie istnieje na serwerze, ta sekcja nie ma zastosowania.
Krok 4: restart i test z poziomu drugiego terminala
sudo systemctl restart sshd
systemctl status sshd
sudo ss -tlnp | grep sshdPozostaw ten terminal otwarty. Nie wylogowuj się z niego. Otwórz drugi terminal na własnym komputerze i połącz się przez nowy port:
ssh -p 2222 youruser@203.0.113.10Zamknij pierwszą sesję dopiero po poprawnym zalogowaniu się w drugiej. Jeśli połączenie nie zostanie nawiązane, nadal posiadasz aktywną powłokę, z poziomu której możesz wycofać wprowadzone zmiany. Ten nawyk stanowi różnicę między pięciominutową konfiguracją a popołudniem spędzonym na pracy w konsoli dostawcy usług.
Odrzucenie przez firewall czy blokada SELinux? Jak je rozróżnić
Z poziomu laptopa obie awarie wyglądają niemal identycznie. Na serwerze różnią się całkowicie.
- Jeśli
systemctl status sshdwskazuje, że jednostka nie wystartowała, demon nigdy nie otrzymał swojego gniazda. Jest to błąd konfiguracji lub blokada SELinux. - Jeśli jednostka jest aktywna, a
ss -tlnppokazuje, że sshd nasłuchuje na nowym porcie, demon działa poprawnie, a problem leży na ścieżce sieciowej: firewalld, zewnętrzny firewall dostawcy lub błędny adres i port docelowy.
W przypadku SELinux należy odczytać wpis w dzienniku audytu zamiast zgadywać:
sudo ausearch -m AVC -ts recent
sudo journalctl -u sshd -n 50 --no-pagerBlokada name_bind w klasie tcp_socket wskazuje proces w comm="sshd", numer portu w src= oraz etykietę przypisaną do portu w tcontext=. To ostatnie pole zawiera rozwiązanie. Wartość inna niż ssh_port_t oznacza, że krok 2 nie został poprawnie zastosowany do używanego portu, co zazwyczaj wynika z literówki w numerze lub błędnego protokołu. Zainstaluj sealert, jeśli wolisz, aby setroubleshoot-server przekształciło wpis w czytelne zdanie.
Komunikat zapisywany przez sam proces sshd, gdy jądro odmawia powiązania z portem, wygląda następująco:
error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.Permission denied na porcie powyżej 1024, gdzie uprawnienia roota nie są wymagane do powiązania, jest sygnaturą SELinux. Address already in use w tej samej linii oznacza inny błąd: inny proces zajmuje już ten port. Od strony klienta różnica między connection refused a connection timed out pozwala rozróżnić dwa przypadki sieciowe, ponieważ odmowa oznacza, że pakiet dotarł do hosta, ale nikt nie nasłuchiwał, natomiast przekroczenie czasu oznacza, że nie otrzymano żadnej odpowiedzi.
Zamknięcie portu 22 i aktualizacja klientów
Gdy kilka logowań na nowy port zakończy się powodzeniem, należy zamknąć port 22:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
sudo firewall-cmd --list-allEtykietę SELinux dla portu 22 należy pozostawić bez zmian. Wynika ona z polityki podstawowej i nie przyznaje żadnych uprawnień, gdy firewall przestaje przepuszczać pakiety.
Następnie należy zaktualizować klientów, ponieważ każde narzędzie zakładające użycie portu domyślnego wymaga teraz wskazania nowego portu. Warto dodać odpowiedni wpis w ~/.ssh/config na własnej maszynie, aby uniknąć ciągłego wpisywania -p:
Host myvps
HostName 203.0.113.10
Port 2222
User youruserscp, sftp, rsync oraz Ansible odczytują ten plik. Zadania kopii zapasowych, testy monitoringu oraz skrypty cron, w których port 22 jest wpisany na sztywno, nie korzystają z tego pliku, dlatego należy je odnaleźć, póki zmiana jest świeża w pamięci.
Co daje, a czego nie daje zmiana portu
Zmniejsza ona szum w logach. Zautomatyzowane skanery nieustannie atakują port 22, a przeniesienie usługi na inny port usuwa większość tych wpisów z dziennika, co ułatwia dostrzeżenie rzeczywistych zdarzeń. Nie jest to mechanizm bezpieczeństwa. Każdy skaner skanujący pełny zakres portów i tak wykryje demona oraz odczyta jego baner wersji. Zmianę portu należy traktować jako porządkowanie systemu, a rzeczywistą ochronę oprzeć na uwierzytelnianiu wyłącznie za pomocą kluczy przy wyłączonym logowaniu hasłem, co krok po kroku opisuje przewodnik po zabezpieczaniu SSH na VPS.
Powyższe informacje działają identycznie w obu głównych dystrybucjach typu RHEL rebuild, ponieważ bazują one na tych samych źródłach. Zobacz porównanie Rocky Linux i AlmaLinux, jeśli nadal dokonujesz wyboru między nimi. Przed skorzystaniem ze starszych poradników sprawdź za pomocą cat /etc/os-release, którą wersję systemu faktycznie posiadasz. Poradniki napisane dla Rocky Linux 8 nadal są wysoko pozycjonowane, a zawarte w nich kroki semanage oraz firewall-cmd pozostają poprawne, jednak Rocky 8 nie posiada linii include sshd_config.d ani jednostki socket, więc część dotycząca sshd w tych przewodnikach nie odpowiada współczesnym systemom.
Należy poinformować fail2ban o nowym porcie
Pakiet fail2ban nie znajduje się w podstawowych repozytoriach. Pochodzi on z EPEL (Extra Packages for Enterprise Linux):
sudo dnf install -y epel-release
sudo dnf install -y fail2ban fail2ban-firewalldPodpakiet fail2ban-firewalld sprawia, że fail2ban realizuje blokady za pośrednictwem firewalld, co jest pożądanym rozwiązaniem w systemie, w którym firewalld zarządza zestawem reguł.
Domyślne więzienie (jail) sshd ustawia port = ssh, a ta nazwa jest rozwiązywana przez /etc/services do portu 22. Po wprowadzeniu zmian więzienie monitoruje port, który nie jest atakowany, więc nie blokuje nikogo, podczas gdy nieudane próby logowania gromadzą się na porcie 2222. Należy ustawić port za pomocą numeru w pliku /etc/fail2ban/jail.local:
[sshd]
enabled = true
port = 2222
backend = systemd
maxretry = 5
bantime = 3600backend = systemd odczytuje nieudane próby logowania z dziennika systemowego (journal) zamiast z pliku /var/log/secure, co jest bezpieczniejszym wyborem w minimalnej instalacji, gdzie rsyslog może nie być obecny. Uruchom usługę za pomocą sudo systemctl enable --now fail2ban i sprawdź stan więzienia poleceniem sudo fail2ban-client status sshd. Składnia więzienia jest taka sama, jak ta użyta w konfiguracji fail2ban dla SSH w systemie Ubuntu 24.04. Różnią się jedynie źródło pakietu oraz akcja blokowania.
Aktualizacje zabezpieczeń są ważniejsze niż numer portu
Serwer z przeniesionym portem SSH i czteromiesięcznymi zaległościami w aktualizacjach zabezpieczeń jest w gorszym stanie niż serwer działający na porcie 22, który aktualizuje się automatycznie każdej nocy. Włącz automatyczne aktualizacje w tej samej sesji, będąc zalogowanym jako root: automatyczne aktualizacje dnf w systemach Rocky Linux i AlmaLinux zawiera opis timera oraz wybór między pobieraniem aktualizacji a ich automatycznym instalowaniem.
FAQ
Dlaczego sshd nie uruchamia się po zmianie portu w systemie Rocky Linux?
Przyczyną jest niemal zawsze brak etykiety portu SELinux. sshd działa w izolacji w domenie sshd_t, a polityka zezwala na nasłuchiwanie wyłącznie na portach oznaczonych jako ssh_port_t, co domyślnie ogranicza się do portu 22. Jądro odrzuca próbę powiązania portu, więc demon kończy działanie zamiast nasłuchiwać, a journalctl -u sshd zawiera linię o treści error: Bind to port 2222 on 0.0.0.0 failed: Permission denied.. Należy wykonać polecenie sudo semanage port -a -t ssh_port_t -p tcp 2222 z własnym numerem portu, a następnie zrestartować usługę. Jeśli semanage nie jest dostępne, należy najpierw zainstalować pakiet policycoreutils-python-utils.
Czy nadal muszę używać semanage, jeśli SELinux działa w trybie permissive?
Tak. W trybie permissive odmowa jest rejestrowana, ale powiązanie portu zostaje mimo to dozwolone, więc zmiana wydaje się poprawna. Etykieta nadal jednak nie istnieje. W momencie, gdy ktokolwiek wykona setenforce 1 lub serwer uruchomi się z parametrem SELINUX=enforcing w pliku /etc/selinux/config, sshd przestanie się uruchamiać na tym porcie. Dodanie etykiety wymaga jednego polecenia i eliminuje awarię, która w przeciwnym razie pojawiłaby się po tygodniach bez wyraźnej przyczyny.
Port jest oznaczony, sshd działa, dlaczego połączenie przekracza czas oczekiwania?
Działający demon oznacza, że SELinux nie blokuje operacji, więc pakiet jest odrzucany na etapie wejścia. Należy sprawdzić sudo firewall-cmd --list-ports dla danego portu i potwierdzić wykonanie firewall-cmd --reload po dodaniu reguły --permanent, ponieważ trwała reguła nie jest automatycznie stosowana do działającego firewalla. Następnie należy sprawdzić panel sterowania hosta pod kątem zewnętrznego firewalla sieciowego przed serwerem VPS. Jest to drugie miejsce, w którym ruch jest blokowany, a żadne narzędzie wewnątrz systemu operacyjnego tego nie wykaże.
Jakiego portu użyć zamiast 22?
Dowolnego wolnego portu TCP z zakresu od 1024 do 65535. Należy unikać portów 2222 oraz 22222 na serwerach produkcyjnych, ponieważ skanery sprawdzają je zaraz po porcie 22. Należy potwierdzić dostępność numeru za pomocą sudo ss -tlnp, sprawdzić czy polityka SELinux nie przypisała go już do innej usługi za pomocą sudo semanage port -l oraz pominąć porty przypisane do usług, które mogą zostać zainstalowane w przyszłości. Wysoki, trudny do zapamiętania numer jest odpowiedni, ponieważ zostanie zapisany w ~/.ssh/config tylko raz i nie będzie wymagał ręcznego wpisywania.