OpenSSH (Polski)
OpenSSH (OpenBSD Secure Shell) to zestaw programów zapewniających szyfrowane sesje SSH w sieci komputerowej. Stworzony jako alternatywa open source dla zastrzeżonego pakietu Secure Shell oferowanego przez SSH Communications Security. OpenSSH jest rozwijany w ramach projektu OpenBSD, prowadzonego przez Theo de Raadta.
OpenSSH jest czasem mylony z podobnie nazwanym OpenSSL, jednak projekty mają różne cele i są rozwijane przez różne zespoły — podobna nazwa pochodzi jedynie z podobnych celów.
Instalacja
Client usage
Aby połączyć się z serwerem, uruchom:
$ ssh -p port user@server-address
Jeśli serwer zezwala wyłącznie na uwierzytelnianie kluczem publicznym, wykonaj poniższe kroki SSH keys.
Konfiguracja
Klienta można skonfigurować do przechowywania wspólnych opcji i hostów. Wszystkie opcje można zadeklarować globalnie lub ograniczyć do konkretnych hostów. Na przykład:
~/.ssh/config
# global options
User user1
# host-specific options
Host myserver
Hostname server-address
Port port
User user2
Przy takiej konfiguracji następujące polecenia są równoważne
$ ssh -p port user2@server-address $ ssh myserver
See ssh_config(5) for more information.
Some options do not have command line switch equivalents, but you can specify configuration options on the command line with -o. For example -oKexAlgorithms=+diffie-hellman-group1-sha1.
Server usage
sshd to demon OpenSSH, skonfigurowany w /etc/ssh/sshd_config i zarządzany przez sshd.service. Przy każdej zmianie konfiguracji
użyj sshd w trybie testowym przed ponownym uruchomieniem usługi,
aby upewnić się, że uruchomi się prawidłowo. Prawidłowe konfiguracje nie generują żadnych danych wyjściowych.
# sshd -t
Konfiguracja
Aby zezwolić na dostęp tylko niektórym użytkownikom, dodaj następujący wiersz:
AllowUsers user1 user2
Aby zezwolić na dostęp tylko niektórym grupom:
AllowGroups group1 group2
Aby dodać miłą wiadomość powitalną (np. z pliku /etc/issue), skonfiguruj opcję Banner:
Banner /etc/issue
Publiczne i prywatne klucze hosta są automatycznie generowane w /etc/ssh przez usługę sshdgenkeys zarządzania demonem i regenerowane w przypadku ich braku, nawet jeśli opcja HostKeyAlgorithms w sshd_config ogranicza się do wybranych algorytmów. Generowane są trzy pary kluczy na podstawie algorytmów ed25519, ecdsa i rsa. Aby sshd używał konkretnego klucza, określ następującą opcję:
HostKey /etc/ssh/ssh_host_ed25519_key
Jeżeli serwer ma być wystawiony na sieć WAN, zaleca się zmianę domyślnego portu z 22 na losowy, wyższy port, w następujący sposób:
Port 39901
- Aby wybrać alternatywny port niezapisany dla typowej usługi, sprawdź listę numerów portów TCP i UDP. Informacje o portach dostępne są również lokalnie w
/etc/services. Zmiana portu z domyślnego 22 zmniejszy liczbę wpisów dziennika spowodowanych zautomatyzowanymi próbami uwierzytelnienia, ale ich nie wyeliminuje. Więcej informacji w Port knocking. - Zaleca się całkowite wyłączenie logowania hasłem. To znacznie zwiększy bezpieczeństwo. Więcej informacji można znaleźć w artykule #Force public key authentication Więcej zalecanych metod zabezpieczeń można znaleźć w artykule #Protection
- OpenSSH może nasłuchiwać na wielu portach, wystarczy umieścić w pliku konfiguracyjnym kilka wierszy
Port port_number. - Nowe (lub brakujące) pary kluczy hosta można wygenerować, usuwając parę(y), które chcesz zastąpić, z
/etc/sshi uruchamiającssh-keygen -Ajako root.
Zarządzanie demonami
Start/enable sshd.service. Utrzyma demona SSH w stanie aktywnym
i będzie fork'ować dla każdego przychodzącego połączenia.
Socket activation
W wersji openssh 8.0p1-3 usunięto sshd.socket, który korzystał z socket activation systemd,
ponieważ był podatny na denial of service. Zobacz FS#62248 aby uzyskać szczegóły.
Jeśli sshd.socket jest włączony podczas aktualizacji do openssh 8.0p1-3,
jednostki sshd.socket i sshd@.service zostaną skopiowane do /etc/systemd/system/
i reenabled. Jest to zrobione tylko po to, aby nie uszkodzić istniejących konfiguracji;
użytkownikom nadal zaleca się migracja do sshd.service.
sshd.socket, pamiętaj o jego problemach:
- Jednostka
sshd.socketmoże ulec awarii (np. z powodu braku pamięci), a parametruRestart=alwaysnie można określić w jednostkach z gniazdem. Zobacz problem systemd nr 11553. - Użycie aktywacji gniazda może skutkować odmową usługi, ponieważ zbyt duża liczba połączeń może uniemożliwić dalszą aktywację usługi. Zobacz FS#62248.
Użycie sshd.socket neguje ustawienie ListenAddress, co umożliwia połączenia przez dowolny adres. Aby uzyskać efekt ustawienia ListenAddress, należy określić port i adres IP dla ListenStream (np. ListenStream=192.168.1.100:22) poprzez edit pliku sshd.socket. Należy również dodać FreeBind=true w sekcji [Socket], w przeciwnym razie ustawienie adresu IP będzie miało tę samą wadę co ustawienie ListenAddress: socket nie uruchomi się, jeśli sieć nie będzie aktywna w odpowiednim czasie.
Podczas aktywacji przez socket, dla każdego połączenia uruchamiana jest tymczasowa instancja sshd@.service (z różnymi nazwami instancji). W związku z tym ani sshd.socket, ani zwykła sshd.service nie pozwalają monitorować prób połączeń w logach. Logi instancji SSH aktywowanych przez socket można wyświetlić jako root poleceniami: journalctl -u "sshd@*" i journalctl /usr/bin/sshd
Ochrona
Zezwolenie na zdalne logowanie przez SSH jest niezbędne do celów administracyjnych, ale stanowi zagrożenie dla bezpieczeństwa serwera. SSH jest częstym celem ataków siłowych. Dostęp SSH musi być odpowiednio ograniczony, aby zapobiegać nieautoryzowanemu dostępowi.
ssh-audit oferuje automatyczną analizę konfiguracji serwera i klienta. Dostępnych jest kilka innych dobrych poradników i narzędzi na ten temat, na przykład:
Wymuś uwierzytelnianie kluczem publicznym
Jeśli klient nie może uwierzytelniać się za pomocą klucza publicznego, serwer SSH domyślnie powraca do uwierzytelniania hasłem, umożliwiając w ten sposób atakującemu próbę uzyskania dostępu poprzez brute-force hasła. Jednym z najskuteczniejszych sposobów ochrony przed tym atakiem jest całkowite wyłączenie logowania hasłem i wymuszenie użycia kluczy SSH. Można to osiągnąć, ustawiając następujące opcje w pliku konfiguracyjnym serwera:
/etc/ssh/sshd_config.d/20-force_publickey_auth.conf
PasswordAuthentication no AuthenticationMethods publickey
authorized_keys. Patrz SSH keys#Copying the public key to the remote server Aby uzyskać więcej informacji.Uwierzytelnianie dwuskładnikowe i klucze publiczne
Protokół SSH można skonfigurować tak, aby wymagał wielu metod uwierzytelniania. Wymagane metody uwierzytelniania można sprawdzić za pomocą opcji AuthenticationMethods. Umożliwia to korzystanie z kluczy publicznych oraz autoryzacji dwuskładnikowej.
Dostawcy uwierzytelniania
Aby skonfigurować Google Authenticator, zapoznaj się z informacjami na jej temat.
For Duo, install duo_unixAUR which will supply the pam_duo.so module. Read the Duo Unix documentation for instructions on how to setup the necessary Duo credentials (Integration Key, Secret Key, API Hostname).
Konfiguracja PAM
Aby użyć PAM z OpenSSH, edytuj następujące pliki:
/etc/ssh/sshd_config.d/20-pam.conf
KbdInteractiveAuthentication yes AuthenticationMethods publickey keyboard-interactive:pam
Następnie możesz zalogować się kluczem publicznym lub hasłem użytkownika, zgodnie z wymaganiami konfiguracji PAM.
Jeśli natomiast wymagane jest uwierzytelnianie kluczem publicznym i metodą PAM jednocześnie, oddziel je przecinkiem zamiast spacją w opcji AuthenticationMethods:
/etc/ssh/sshd_config.d/20-pam.conf
KbdInteractiveAuthentication yes AuthenticationMethods publickey,keyboard-interactive:pam
Jeśli wymagany jest klucz publiczny i uwierzytelnianie PAM, możesz wyłączyć wymaganie podania hasła:
/etc/pam.d/sshd
auth required pam_securetty.so #disable remote root #Require google authenticator auth required pam_google_authenticator.so #But not password #auth include system-remote-login account include system-remote-login password include system-remote-login session include system-remote-login
Ochrona przed atakami siłowymi
Brute forcing to prosta metoda: wielokrotne próby zalogowania się do strony internetowej lub serwera (np. SSH) przy użyciu dużej liczby losowych kombinacji nazwy użytkownika i hasła.
Zobacz ufw#Rate limiting with ufw lub Simple stateful firewall#Bruteforce attacks dla iptables.
Od wersji 9.8 zaimplementowano podstawową ochronę podobną do fail2ban: opcja PerSourcePenalties posiada rozsądne wartości domyślne. Kary za różne warunki są egzekwowane na podstawie adresu źródłowego klienta, co powoduje odrzucenie połączenia na określony czas.
Alternatywą jest ochrona przed atakami siłowymi poprzez użycie zautomatyzowanego skryptu, który blokuje każdego, kto próbuje wedrzeć się do Twojego systemu siłą.
- Zezwalaj tylko na połączenia przychodzące SSH z zaufanych lokalizacji
- Użyj fail2ban lub sshguard, aby automatycznie blokować adresy IP, które zbyt wiele razy nie przejdą uwierzytelniania hasłem.
- Użyj pam_shield, aby zablokować adresy IP, które podejmują zbyt wiele prób logowania w określonym czasie. W przeciwieństwie do fail2ban lub sshguard, ten program nie bierze pod uwagę powodzenia ani niepowodzenia logowania.
Ogranicz logowanie roota
Zezwalanie użytkownikowi root na nieograniczone logowanie się przez SSH jest powszechnie uważane za złą praktykę. Istnieją dwie metody ograniczenia dostępu użytkownika root przez SSH w celu zwiększenia bezpieczeństwa.
Deny
sudo selektywnie przyznaje uprawnienia roota do operacji wymagających tych uprawnień bez konieczności uwierzytelniania się wobec konta root. Pozwala to na zablokowanie konta root przed dostępem przez SSH i stanowi potencjalną ochronę przed atakami brute-force, ponieważ atakujący musi teraz odgadnąć nazwę użytkownika oprócz hasła.
SSH można skonfigurować, aby zabronić zdalnych logowań użytkownika root, edytując sekcję „Authentication" w pliku konfiguracyjnym daemona. Wystarczy ustawić PermitRootLogin na wartość no:
/etc/ssh/sshd_config.d/20-deny_root.conf
PermitRootLogin no
Następnie restart demona SSH.
Od teraz nie będziesz w stanie zalogować się przez SSH jako root, ale nadal będziesz mógł zalogować się za pomocą zwykłego konta użytkownika i używać su lub sudo do administrowania systemem.
Restrict
Niektóre zadania automatyczne, takie jak zdalna kopia zapasowa całego systemu, wymagają pełnego dostępu root. Aby umożliwić to bezpiecznie zamiast wyłączać logowanie root przez SSH, można ograniczyć logowanie root do wybranych poleceń. Można to osiągnąć, edytując ~root/.ssh/authorized_keys i poprzedzając żądany klucz, np.:
command="rrsync -ro /" ssh-ed25519 ...
Umożliwi to każdemu użytkownikowi z tym kluczem wykonanie tylko polecenia w cudzysłowie
Zwiększoną powierzchnię ataku z ujawnieniem nazwy użytkownika root można ograniczyć, dodając do sshd_config:
PermitRootLogin forced-commands-only
To ustawienie nie tylko ograniczy polecenia, które użytkownik root może wykonywać za pośrednictwem protokołu SSH, ale także wyłączy używanie haseł, wymuszając użycie uwierzytelniania za pomocą klucza publicznego dla konta root.
Nieco mniej restrykcyjna alternatywa pozwoli na dowolne polecenie dla użytkownika root, ale uniemożliwi ataki siłowe poprzez wymuszenie uwierzytelniania kluczem publicznym. W przypadku tej opcji należy ustawić:
PermitRootLogin prohibit-password
Blokowanie pliku authorized_keys
Jeżeli z jakiegoś powodu uważasz, że dany użytkownik nie powinien mieć możliwości dodawania lub zmieniania istniejących kluczy, możesz uniemożliwić mu manipulowanie plikiem.
Na serwerze ustaw plik authorized_keys jako tylko do odczytu dla użytkownika i zablokuj wszystkie inne uprawnienia:
$ chmod 400 ~/.ssh/authorized_keys
Aby uniemożliwić użytkownikowi zmianę uprawnień, set the immutable bit na pliku authorized_keys. Aby uniemożliwić zmianę nazwy katalogu ~/.ssh i utworzenie nowego katalogu ~/.ssh oraz pliku authorized_keys, ustaw atrybut immutable również na katalogu ~/.ssh. Aby dodać lub usunąć klucze, musisz tymczasowo usunąć atrybut immutable z pliku authorized_keys i przyznać uprawnienia zapisu.
authorized_keys np. za pomocą auditd.Certyfikaty SSH
Chociaż zwykłe klucze SSH i ręczna weryfikacja fingerprinti mogą być łatwe w użyciu w przypadku niewielkiej liczby hostów zarządzanych przez jednego administratora, ta metoda uwierzytelniania w żaden sposób się nie skaluje. Gdy wielu serwerów musi być dostępnych dla kilku użytkowników przez SSH, ręczna weryfikacja fingerprinti kluczy publicznych SSH każdego hosta staje się niemal niemożliwa do przeprowadzenia w sposób bezpieczny i niezawodny.
Rozwiązaniem jest użycie certyfikatów SSH, które zapewniają automatyczną weryfikację tożsamości klucza publicznego poprzez łańcuch zaufania, znacznie lepiej skalujący się niż domyślne podejście SSH oparte na TOFU (trust-on-first-use). Certyfikaty SSH to zwykłe klucze publiczne SSH z dodatkowym podpisem od zaufanego urzędu certyfikacji (CA), który weryfikuje tożsamość klucza.
Utwórz klucz urzędu certyfikacji hosta dla swojej infrastruktury
$ ssh-keygen -t ed25519 -f ~/.ssh/ca_host_key -C 'Host certificate authority for *.example.com'
Prywatny klucz urzędu certyfikacji powinien być przechowywany bezpiecznie, najlepiej na karcie inteligentnej lub tokenie sprzętowym, który uniemożliwia wyodrębnienie klucza, np. Nitrokey lub YubiKey.
Podpisz publiczny klucz hosta SSH serwera
Skopiuj klucz serwera publicznego do lokalnego systemu zawierającego klucz prywatny urzędu certyfikacji, aby go podpisać:
$ ssh-keygen -h -s ~/.ssh/ca_key -I certLabel -n server01.example.com ./ssh_host_ed25519_key.pub
Przenieś nowy certyfikat i skonfiguruj sshd, aby go używać
Wygenerowany certyfikat ssh_host_ed25519_key-cert.pub należy skopiować na serwer w katalogu /etc/ssh/.
/etc/ssh/sshd_config.d/20-ed25519_key.conf
HostCertificate /etc/ssh/ssh_host_ed25519_key-cert.pub
Skonfiguruj wszystkich klientów tak, aby ufali urzędowi certyfikacji
~/.ssh/known_hosts
@cert-authority *.example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKL8gB/pjuff005YNazwMCqJpgsXAbQ3r4VStd/CRKwU Host certificate authority for *.example.com
Certyfikaty użytkownika SSH
W zależności od liczby użytkowników i metody wdrożenia, klucze użytkownika SSH mogą być również używane z certyfikatami. W przypadku organizacji z wieloma użytkownikami SSH zdecydowanie zaleca się bezpieczne zarządzanie wdrażaniem kluczy użytkownika.
Wdrażanie certyfikatów użytkowników działa zasadniczo tak samo, jak w przypadku tożsamości serwerów. Więcej szczegółów i instrukcji można znaleźć w Wikibooks:OpenSSH/Cookbook/Certificate-based Authentication.
Automatyzacja wdrażania certyfikatów
Automatyczne wdrażanie certyfikatów SSH można zapewnić za pomocą wielu narzędzi open source. Popularne przykłady to:
- Ansible - openssh_cert module
- privacyIDEA - authentication server
- Theo App - authorized keys manager
SSHFP record
Rekord odcisku palca Secure Shell (SSHFP) to opcjonalny rekord zasobu DNS, który przypisuje klucze SSH do nazwy hosta. Może być używany do weryfikacji odcisku palca SSH na serwerach publicznych za pomocą DNSSEC zamiast wdrażania zaufanych certyfikatów CA, co pozwala nawet niezarządzanym klientom na weryfikację ważności odcisków kluczy.
Wygeneruj wpis rekordu
Aby wygenerować wymagany szesnastkowy odcisk klucza do umieszczenia w rekordzie DNS, wygeneruj hash na serwerze docelowym.
$ ssh-keygen -r host.example.com
Spowoduje to odczytanie wszystkich dostępnych kluczy SSH dla określonej domeny i wygenerowanie prawidłowych rekordów SSHFP, które można następnie zapisać we wpisach DNS danej domeny.
Konfiguracja klienta
Aby automatycznie pobierać i ufać odciskom kluczy SSH w rekordach SSHFP, dodaj to do pliku konfiguracji SSH:
~/.ssh/config
# global options
Match all
VerifyHostKeyDNS yes
Jeśli host docelowy ma prawidłowy rekord SSHFP zweryfikowany prawidłowym podpisem DNSSEC, fingerprint zostaje automatycznie zaakceptowany bez pytania użytkownika o weryfikację tożsamości hosta. W przypadku braku weryfikacji DNSSEC rekordu DNS użytkownik zostaje poproszony o weryfikację fingerprintu w zwykły sposób.
trust-ad option is set in /etc/resolv.conf.Generuj rekordy SSHFP
Aby ustalić fingerprint SSH konkretnej domeny, użyj polecenia ssh-keyscan do pobrania fingerprintów SSH w prawidłowym formacie rekordu DNS. (Domyślnie odciski palców dla każdego dostępnego typu klucza są podawane zarówno w SHA1 jak i SHA256.)
$ ssh-keyscan -D github.com
; github.com:22 SSH-2.0-babeld-57ca1323 ; github.com:22 SSH-2.0-babeld-57ca1323 github.com IN SSHFP 1 1 6f4c60375018bae0918e37d9162bc15ba40e6365 github.com IN SSHFP 1 2 b8d895ced92c0ac0e171cd2ef5ef01ba3417554a4a6480d331ccc2be3ded0f6b ; github.com:22 SSH-2.0-babeld-57ca1323 github.com IN SSHFP 3 1 3358ab5dd3e306c461c840f7487e93b697e30600 github.com IN SSHFP 3 2 a764003173480b54c96167883adb6b55cf7cfd1d415055aedff2e2c8a8147d03 ; github.com:22 SSH-2.0-babeld-57ca1323 github.com IN SSHFP 4 1 e9619e2ed56c2f2a71729db80bacc2ce9ccce8d4 github.com IN SSHFP 4 2 f83898df0bef57a4ee24985ba598ac17fccb0c0d333cc4af1dd92be14bc23aa5 ; github.com:22 SSH-2.0-babeld-57ca1323
Ponieważ rekord SSHFP przechowuje odciski kluczy w formacie heksadecymalnym, a typowe dane wyjściowe odcisków SSH to skrót SHA256 klucza publicznego zakodowany w base64, konieczna jest konwersja rekordu do formatu base64 w celu porównania go z wartościami w pliku known_hosts lub inną dokumentacją, która zwykle przechowuje odciski w formacie SHA256 base64.
$ echo "SSHFP-fingerprint" | xxd -r -p | base64
Przykład dla github.com wykorzystujący wartość szesnastkową odcisku palca sha256 klucza ed25519
$ echo "f83898df0bef57a4ee24985ba598ac17fccb0c0d333cc4af1dd92be14bc23aa5" | xxd -r -p | base64
+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU=
Porównaj z wpisami known_hosts:
$ ssh-keygen -l -f ~/.ssh/known_hosts
Ręczne pobieranie rekordów SSHFP z DNS
$ dig SSHFP targetdomain.tld +short
Porady i wskazówki
Szyfrowany tunel SOCKS
Może to być przydatne dla użytkowników laptopów podłączonych do niebezpiecznych sieci bezprzewodowych. Wymogiem jest serwer SSH działający w bezpiecznym miejscu, takim jak dom lub miejsce pracy. Zalecane jest użycie dynamicznej usługi DNS, na przykład DynDNS, aby nie trzeba było pamiętać adresu IP.
Rozpocznij połączenie
$ ssh -TND 4711 user@host
Flaga N wyłącza interaktywny monit, a flaga D określa lokalny port, na którym nasłuchiwać (możesz wybrać dowolny numer portu). Flaga T wyłącza alokację pseudo-tty.
Można dodać flagę verbose (-v), aby zweryfikować połączenie.
Skonfiguruj swoją przeglądarkę (lub inne programy)
Powyższy krok jest przydatny tylko w połączeniu z przeglądarką lub innym programem. Ponieważ SSH obsługuje zarówno SOCKS v4, jak i SOCKS v5, możesz skonfigurować jeden z nich.
- For Firefox:
- Go to Preferences > General > Network Settings and click on Settings....
- In the new window, check the Manual proxy configuration option and enter
localhostin the SOCKS host text field, and the port number in the Port text field (4711in the example above). - Restart Firefox.
- Note Firefox nie wysyła automatycznie żądań DNS przez tunel SOCKS. Można temu zapobiec, sprawdzając opcję „Serwer proxy DNS podczas korzystania z SOCKS vN” (wersja 4 lub 5).
- Dla Chromium:
- Możesz ustawić ustawienia SOCKS jako zmienne środowiskowe lub opcje wiersza poleceń. Na przykład, dodaj jedną z następujących funkcji do swojego
.bashrc:secure_chromium() { local port=4711 export SOCKS_SERVER=localhost:$port export SOCKS_VERSION=5 (chromium > /dev/null 2>&1 &) } secure_chromium() { local port=4711 (chromium --proxy-server="socks://localhost:$port" > /dev/null 2>&1 &) } - Otwórz terminal i uruchom:
$ secure_chromium
Skonfiguruj lokalny interfejs TUN
Początkowo wymaga to bardziej zaawansowanej konfiguracji, ale pozwala uniknąć konieczności ręcznego konfigurowania każdej aplikacji do użycia proxy SOCKS. Wymaga to skonfigurowania lokalnego interfejsu TUN i routowania ruchu przez niego.
Zobacz VPN over SSH#Set up badvpn and tunnel interface.
Przekierowanie X11
Przekierowanie X11 to mechanizm umożliwiający wyświetlanie graficznych interfejsów programów X11 działających w systemie zdalnym na lokalnym komputerze klienckim. Do przekierowania X11 zdalny host nie musi mieć zainstalowanego pełnego systemu X11, jednak musi mieć zainstalowany co najmniej xauth. xauth to narzędzie, które zarządza konfiguracją Xauthority używaną przez serwer i klient do uwierzytelniania sesji X11 (źródło).
Setup
Zdalny
- zainstaluj pakiety xorg-xauth
- w
/etc/ssh/sshd_config:- ustaw
X11Forwardingna yes - sprawdź, czy opcje
AllowTcpForwardingiX11UseLocalhostsą ustawione na tak i czyX11DisplayOffsetjest ustawione na 10 (są to wartości domyślne, jeśli nic nie zostało zmienione, zobacz sshd_config(5))
- ustaw
- następnie uruchom ponownie sshd daemon.
Klient
- zainstaluj pakiety xorg-xauth
- enable the
ForwardX11option by either specifying the-Xswitch on the command line for opportunistic connections, or by settingForwardX11to yes in the client's configuration.
ForwardX11Trusted option (-Y switch on the command line) if GUI is drawing badly or you receive errors; this will prevent X11 forwardings from being subjected to the X11 SECURITY extension controls. Be sure you have read the warning at the beginning of this section if you do so.Używanie
Zaloguj się do maszyny zdalnej, podając przełącznik -X, jeśli ForwardX11 nie został włączony w pliku konfiguracyjnym klienta:
$ ssh -X user@host
Jeśli otrzymasz błędy przy uruchamianiu aplikacji graficznych, spróbuj zamiast tego ForwardX11Trusted:
$ ssh -Y user@host
Jeśli otrzymasz wynik X11 forwarding request failed, powtórz konfigurację na maszynie zdalnej. Po pomyślnym wykonaniu żądania przekierowania X11 możesz uruchomić dowolny program X na serwerze zdalnym, a zostanie on przekierowany do sesji lokalnej:
$ xclock
Komunikat błędu Can't open display wskazuje, że DISPLAY jest źle ustawione.
Należy uważać na niektóre aplikacje, które sprawdzają, czy na lokalnym komputerze istnieje uruchomiona instancja. Przykładem jest Firefox: zamknij uruchomioną instancję lub użyj następującego parametru uruchomienia, aby uruchomić drugą instancję na lokalnym komputerze:
$ firefox --no-remote
Jeśli podczas łączenia pojawia się błąd „X11 forwarding request failed on channel 0"
(a serwer wyświetla w /var/log/errors.log komunikat „Failed to allocate
internet-domain X11 display socket"), upewnij się, że pakiet xorg-xauth
jest zainstalowany. Jeśli instalacja nie powiedzie się, spróbuj jednej z poniższych
opcji:
- włącz opcję
AddressFamily anywsshd_configna serwerze lub - Ustaw opcję
AddressFamilyw plikusshd_configna serwerze na inet.
Ustawienie jej na inet może rozwiązać problemy z klientami Ubuntu na IPv4.
Aby uruchomić aplikacje X jako inny użytkownik na serwerze SSH, należy za pomocą xauth add dodać linię uwierzytelniania pobraną z wyniku xauth list zalogowanego użytkownika SSH.
Przekierowywanie innych portów
Oprócz wbudowanej obsługi X11, SSH można również użyć do bezpiecznego tunelowania dowolnego połączenia TCP za pomocą lokalnego lub zdalnego przekierowania portów.
Przekierowanie lokalne otwiera port na maszynie lokalnej, do którego połączenia są przekierowywane do hosta zdalnego, a następnie do określonego celu. Najczęściej cel przekierowania jest taki sam jak host zdalny, zapewniając bezpieczną powłokę i, np. bezpieczne połączenie VNC do tej samej maszyny. Przekierowanie lokalne realizuje się przełącznikiem -L ze specyfikacją <tunnel port>:<destination address>:<destination port>.
Thus:
$ ssh -L 1000:mail.google.com:25 192.168.0.100
Użyje protokołu SSH do zalogowania się i otwarcia powłoki na maszynie 192.168.0.100,
a także utworzy tunel z portu TCP 1000 maszyny lokalnej do mail.google.com na porcie 25.
Po nawiązaniu połączenia, połączenia do localhost:1000 będą łączyć się z portem SMTP
Gmaila. Google będzie uważać, że każde takie połączenie (choć niekoniecznie przesyłane
przez nie dane) pochodzi z 192.168.0.100, a dane będą bezpieczne między maszyną
lokalną a maszyną 192.168.0.100, ale nie między 192.168.0.100 a Google, chyba że
zastosowane będą dodatkowe środki.
Podobnie:
$ ssh -L 2000:192.168.0.100:6001 192.168.0.100
umożliwi połączenia do localhost:2000, które będą transparentnie przesyłane do zdalnego hosta na porcie 6001. Przykład ten jest przydatny dla połączeń VNC przy użyciu narzędzia vncserver — części pakietu tightvnc — które, choć bardzo przydatne, nie gwarantuje bezpieczeństwa.
Zdalne przekierowywanie pozwala zdalnemu hostowi połączyć się poprzez tunel SSH z dowolnym hostem za pośrednictwem maszyny lokalnej, stanowiąc odwrócenie lokalnego przekierowywania. Jest przydatne w sytuacjach, gdy zdalny host ma ograniczoną łączność z powodu zapory. Włącza się je przełącznikiem -R i specyfikacją przekierowywania w postaci <tunnel port>:<destination address>:<destination port>.
Zatem:
$ ssh -R 3000:irc.libera.chat:6667 192.168.0.200
otworzy powłokę na 192.168.0.200, a połączenia z 192.168.0.200 na porcie 3000 (localhost:3000 zdalnego hosta) będą przekierowywane przez tunel do maszyny lokalnej, a następnie do irc.libera.chat na porcie 6667. W tym przykładzie umożliwia to używanie programów IRC na zdalnym hoście, nawet jeśli port 6667 byłby normalnie dla niego zablokowany.
Zarówno lokalne, jak i zdalne przekierowywanie może być używane do zapewnienia bezpiecznej „bramy", umożliwiając innym komputerom korzystanie z tunelu SSH bez faktycznego uruchamiania SSH lub serwera SSH poprzez podanie adresu powiązania dla początku tunelu jako części specyfikacji przekierowywania, np. <tunnel address>:<tunnel port>:<destination address>:<destination port>. <tunnel address> może być dowolnym adresem na maszynie na początku tunelu. Adres localhost zezwala na połączenia przez localhost lub interfejs loopback, a pusty adres lub * zezwala na połączenia przez dowolny interfejs. Domyślnie przekierowywanie jest ograniczone do połączeń z maszyny na „początku" tunelu, tj. <tunnel address> jest ustawione na localhost. Lokalne przekierowywanie nie wymaga dodatkowej konfiguracji; jednak zdalne przekierowywanie jest ograniczone przez konfigurację serwera SSH na zdalnej maszynie. Szczegóły znajdują się w opcji GatewayPorts w sshd_config(5) oraz opcji -L w ssh(1).
Jump hosts
W pewnych scenariuszach może nie być bezpośredniego połączenia z docelowym demonem SSH i wymagane jest użycie jump servera (lub bastion hosta). W związku z tym próbujemy połączyć dwa lub więcej tuneli SSH, zakładając, że klucze lokalne są autoryzowane na każdym serwerze w łańcuchu. Jest to możliwe dzięki przekierowaniu agenta SSH (-A) i alokacji pseudo-terminala (-t), które umożliwiają przekazanie klucza lokalnego za pomocą następującej składni:
$ ssh -A -t -l user1 bastion1 \ ssh -A -t -l user2 intermediate2 \ ssh -A -t -l user3 target
Można to zautomatyzować za pomocą opcji ProxyCommand:
$ ssh -o ProxyCommand="ssh -W %h:%p bastion.example.org" targetserver.example.org
Łatwiejszym i bezpieczniejszym sposobem wykonania tego zadania jest użycie opcji ProxyJump z flagą -J:
$ ssh -J user1@bastion1,user2@intermediate2 user3@target
W dyrektywie -J wiele hostów można rozdzielić przecinkiem; będą podłączane w podanej kolejności. Część user...@ jest opcjonalna, ale może być użyta. Specyfikacje hostów dla -J korzystają z pliku konfiguracyjnego ssh, więc w razie potrzeby można tam ustawić opcje dla każdego hosta.
Główną różnicą między opcjami ProxyCommand i ProxyJump jest to, że ProxyJump nie wymaga powłoki systemowej na jump hoście. W konsekwencji serwer jump host nie wymaga dostępu do danych logowania użytkownika ani przekazywania agenta SSH. Dzięki opcji ProxyJump klient SSH łączy się bezpośrednio przez jump host z serwerem docelowym, ustalając zaszyfrowany kanał end-to-end między klientem a serwerem docelowym.
Odpowiednikiem flagi -J w pliku konfiguracyjnym jest opcja ProxyJump; szczegóły można znaleźć w ssh_config(5).
Odwrotny SSH przez przekaźnik
Koncepcja: klient łączy się z serwerem poprzez przekaźnik, a serwer połączony jest z tym samym przekaźnikiem odwrotnym tunelem SSH. Jest to przydatne, gdy serwer znajduje się za NAT-em, a przekaźnik to publicznie dostępny serwer SSH. Warunkami wstępnymi są: klucze klienta autoryzowane na przekaźniku i serwerze, oraz klucze serwera autoryzowane na przekaźniku dla odwrotnego tunelu SSH
Poniższy przykład konfiguracji zakłada, że user1 to konto użytkownika na kliencie, user2 na przekaźniku i user3 na serwerze. Zakładając użycie portu 2222, serwer musi ustanowić tunel odwrotny za pomocą:
$ ssh -R 2222:localhost:22 -N user2@relay
Which can also be automated with a startup script, systemd service, autossh or sidedoorAUR.
Po stronie klienta połączenie nawiązywane jest za pomocą:
$ ssh -t user2@relay ssh user3@localhost -p 2222
ssh user3@relay -p 2222 wymagałoby otwarcia tego portu w zaporze serwera relay, a także zezwolenia na połączenia do tego portu z innych adresów.Zdalne polecenie do ustanowienia połączenia tunelu odwrotnego można również zdefiniować w pliku authorized_keys serwera pośredniczącego, uwzględniając pole command w następujący sposób:
~/.ssh/authorized_keys
command="ssh user3@localhost -p 2222" ssh-ed25519 KEY2 user1@client
W tym przypadku połączenie jest nawiązywane za pomocą:
$ ssh user2@relay
Alternatywnie możesz dodać wpis do konfiguracji SSH, który określa zarówno RemoteCommand, jak i RequestTTY:
~/.ssh/config
Host jump-destination
Hostname relay
User user2
RemoteCommand ssh user3@localhost -p 2222
RequestTTY yes
Co zmniejszy liczbę połączeń z:
$ ssh jump-destination
Multiplexing
Demon SSH zazwyczaj nasłuchuje portu 22. Jednak powszechną praktyką wielu publicznych sieci Wi-Fi jest blokowanie całego ruchu na portach innych niż standardowe HTTP/S (odpowiednio 80 i 443), co w praktyce blokuje połączenia SSH. Rozwiązaniem jest skonfigurowanie sshd do nasłuchiwania dodatkowo na jednym z portów dozwolonych:
/etc/ssh/sshd_config
Port 22 Port 443
Jednak port 443 jest prawdopodobnie już używany przez serwer web udostępniający zawartość HTTPS. W takim przypadku można użyć multipleksera, takiego jak sslh, który nasłuchuje na porcie multipleksera i może kierować pakiety do wielu usług.
Przyspieszanie SSH
Istnieje kilka opcji client configuration, które mogą przyspieszyć połączenia globalnie lub dla określonych hostów. Pełny opis tych opcji można znaleźć w ssh_config(5).
-
Użyj szybszego szyfru: na nowoczesnych procesorach z instrukcjami AESNI,
aes128-gcm@openssh.comiaes256-gcm@openssh.compowinny zapewniać znacznie lepszą wydajność od domyślnego szyfru openssh, zwyklechacha20-poly1305@openssh.com. Szyfr można wybrać flagą-c. Aby uzyskać efekt trwały, umieść opcjęCiphersw~/.ssh/configz szyframi w żądanej kolejności, np.:Ciphers aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
-
Włączanie i wyłączanie kompresji kompresja może zwiększyć prędkość na wolnych połączeniach; włącza się za pomocą opcji
Compression yeslub flagi-C. Jednak używany algorytm kompresji to stosunkowo wolny gzip(1), który stanowi wąskie gardło w szybkich sieciach. Aby przyspieszyć połączenie, należy wyłączyć kompresję za pomocą opcjiCompression now sieciach lokalnych i szybkich.
- „Udostępnianie połączenia": możesz sprawić, że wszystkie sesje do tego samego hosta współdzielą jedno połączenie, używając poniższych opcji:
ControlMaster auto ControlPersist yes ControlPath ~/.ssh/sockets/socket-%r@%h:%p
- gdzie
~/.ssh/socketsmoże być dowolnym katalogiem, do którego inni użytkownicy nie mają prawa zapisu.
-
ControlPersistokreśla, jak długo master powinien czekać w tle na nowych klientów po zamknięciu początkowego połączenia. Możliwe wartości to:-
no, aby natychmiast zamknąć połączenie po rozłączeniu się ostatniego klienta, - czas w sekundach,
-
yesaby czekać w nieskończoność, połączenie nigdy nie zostanie zamknięte automatycznie.
-
- Czas logowania można skrócić poprzez pominięcie wyszukiwania IPv6 za pomocą opcji
AddressFamily inetlub flagi-4.
- Na koniec, jeśli zamierzasz używać SSH do SFTP lub SCP, High Performance SSH/SCP może znacząco zwiększyć przepustowość poprzez dynamiczne zwiększanie rozmiarów buforów SSH. Zainstaluj pakiet openssh-hpnAUR, aby korzystać z poprawionej wersji OpenSSH z tym ulepszeniem.
Montowanie zdalnego systemu plików za pomocą SSHFS
Zapoznaj się z artykułem SSHFS, aby zamontować zdalny system dostępny przez SSH w katalogu lokalnym. Umożliwi Ci to wykonywanie dowolnych operacji na zamontowanych plikach za pomocą dowolnego narzędzia (kopiowanie, zmiana nazwy, edycja za pomocą vim itd.). sshfs jest generalnie preferowany w stosunku do shfs, które nie było aktualizowane od 2004 roku.
Keep alive
Domyślnie sesja SSH automatycznie się wylogowuje po upływie określonego czasu braku aktywności. Aby podtrzymać sesję, klient może wysłać do serwera sygnał keep-alive, jeśli przez pewien czas nie odebrano danych, lub serwer może wysyłać komunikaty w regularnych odstępach, jeśli nie otrzyma danych od klienta.
- Po stronie serwera
ClientAliveIntervalustawia limit czasu w sekundach, po którym, jeśli serwer nie otrzyma żadnych danych od klienta, sshd wyśle żądanie odpowiedzi. Wartość domyślna to 0 (komunikat nie jest wysyłany). Na przykład, aby żądać odpowiedzi od klienta co 60 sekund, ustaw opcjęClientAliveInterval 60w konfiguracji serwera. Patrz też opcjeClientAliveCountMaxiTCPKeepAlive. - Po stronie klienta,
ServerAliveIntervalokreśla interwał wysyłania żądań o potwierdzenie z klienta do serwera. Na przykład, aby wysyłać potwierdzenie co 120 sekund, dodaj opcjęServerAliveInterval 120do client configuration. Patrz również:ServerAliveCountMaxiTCPKeepAlive.
ServerAliveInterval, a pozostałe klienty i serwery pozostawić w konfiguracji domyślnej.Automatyczne ponowne uruchamianie tuneli SSH za pomocą systemd
systemd może automatycznie nawiązywać połączenia SSH podczas rozruchu/logowania i restartować je w przypadku zerwania. Dzięki temu jest to przydatne narzędzie do obsługi tuneli SSH.
Poniższa usługa może uruchomić tunel SSH po zalogowaniu, korzystając z ustawień połączenia w #Configuration ssh configuration. Jeśli połączenie zostanie zamknięte z jakiegokolwiek powodu, odczeka 10 sekund przed ponownym uruchomieniem:
~/.config/systemd/user/tunnel.service
[Unit] Description=SSH tunnel to myserver [Service] Type=simple Restart=always RestartSec=10 ExecStart=/usr/bin/ssh -F %h/.ssh/config -N myserver
Następnie enable i start user unit. Zobacz #Keep alive, aby dowiedzieć się, jak zapobiec przekroczeniu limitu czasu tunelu. Jeśli chcesz uruchomić tunel podczas rozruchu, możesz [systemd#Writing unit files|rewrite the unit]] jako usługę systemową.
Autossh – automatycznie restartuje sesje i tunele SSH
Jeśli nie można utrzymać sesji lub tunelu, na przykład z powodu złych warunków sieciowych powodujących rozłączenia klientów, można użyć autossh, aby automatycznie je ponownie uruchomić.
Przykłady użycia:
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" username@example.com
W połączeniu z SSHFS:
$ sshfs -o reconnect,compression=yes,transform_symlinks,ServerAliveInterval=45,ServerAliveCountMax=2,ssh_command='autossh -M 0' username@example.com: /mnt/example
Łączenie przez proxy SOCKS ustawione w Proxy settings:
$ autossh -M 0 -o "ServerAliveInterval 45" -o "ServerAliveCountMax 2" -NCD 8080 username@example.com
Za pomocą opcji -f można uruchomić autossh jako proces w tle. Jednak uruchomienie go w ten sposób oznacza, że nie można wprowadzić hasła interaktywnie.
Sesja zakończy się w momencie wpisania polecenia exit lub gdy proces autossh otrzyma sygnał SIGTERM, SIGINT lub SIGKILL.
Uruchom autossh automatycznie podczas rozruchu za pomocą systemd
Jeśli chcesz automatycznie uruchamiać autossh, możesz utworzyć plik jednostki systemd:
/etc/systemd/system/autossh.service
[Unit] Description=AutoSSH service for port 2222 After=network.target [Service] Environment="AUTOSSH_GATETIME=0" ExecStart=/usr/bin/autossh -M 0 -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com [Install] WantedBy=multi-user.target
Tutaj AUTOSSH_GATETIME=0 to zmienna środowiskowa określająca, jak długo ssh musi być aktywne, zanim autossh uzna połączenie za udane. Ustawienie jej na 0 powoduje, że autossh ignoruje również błąd pierwszego uruchomienia ssh. Może to być przydatne przy starcie systemu. Inne zmienne środowiskowe dostępne są w autossh(1). W razie potrzeby można tę jednostkę bardziej skomplikować (szczegóły w dokumentacji systemd), a także użyć własnych opcji dla autossh. Należy jednak pamiętać, że opcja -f wraz z AUTOSSH_GATETIME=0 nie działa z systemd.
Pamiętaj, aby później start i/lub enable usługę.
Może być również konieczne wyłączenie ControlMaster:
ExecStart=/usr/bin/autossh -M 0 -o ControlMaster=no -NL 2222:localhost:2222 -o TCPKeepAlive=yes foo@bar.com
Usługa alternatywna na wypadek awarii demona SSH
W przypadku serwerów zdalnych lub bezobsługowych, które polegają wyłącznie na protokole SSH, niepowodzenie uruchomienia demona SSH (np. po uaktualnieniu systemu) może uniemożliwić dostęp administracyjny. systemd oferuje proste rozwiązanie za pomocą opcji OnFailure.
Załóż, że serwer uruchamia sshd, a telnet jest rozwiązaniem awaryjnym. Utwórz następujący plik. Nie enable telnet.socket!**
/etc/systemd/system/sshd.service.d/override.conf
[Unit] OnFailure=telnet.socket
To wszystko. Telnet jest niedostępny, gdy uruchomiony jest sshd. Jeśli sshd nie uruchomi się, można otworzyć sesję telnet w celu odzyskania połączenia.
Kolor tła terminala w zależności od hosta
Aby lepiej rozróżniać, kiedy znajdujesz się na różnych hostach, możesz ustawić inny kolor tła w zależności od rodzaju hosta.
To rozwiązanie działa, ale nie jest uniwersalne (tylko ZSH).
Konfiguracja specyficzna dla sieci
Możesz użyć konfiguracji hosta specyficznej dla sieci, do której jesteś podłączony, używając polecenia Match exec.
Na przykład, gdy używane jest nmcli(1), a połączenie jest skonfigurowane (ręcznie lub przez DHCP) z domeną wyszukiwania:
~/.ssh/config
Match exec "nmcli | grep domains: | grep example.com" CanonicalDomains example.com # Should you use a different username on this network #User username # Use a different known_hosts file (for private network or synchronisation) #UserKnownHostsFile <network>_known_hosts
Inny przykład dla Match host ... exec "...": Weź pod uwagę, że połączenie z internal.example.com wymaga bastion/proxy (przez ProxyJump), chyba że jesteś już połączony przez VPN. Fragment !exec "host internal.example.com" ma zastosowanie tylko wtedy, gdy internal.example.com nie da się rozwiązać przez DNS. Różne alternatywy omówiono w [3].
~/.ssh/config
Match host internal.example.com !exec "host internal.example.com" ProxyJump bastion.example.com Host internal.example.com User foobar
Weryfikacja kluczy hosta sieci prywatnych
Ponieważ różne serwery w różnych sieciach prawdopodobnie korzystają ze wspólnego prywatnego adresu IP, możesz chcieć je obsłużyć w różny sposób.
Najlepszym rozwiązaniem jest użycie #Network specific configuration, aby używać innego pliku UserKnownHostsFile w zależności od sieci. Drugim rozwiązaniem, zalecane jako domyślne podczas pracy w nowych/prototypowych sieciach, jest po prostu ignorowanie hostkeys w sieciach prywatnych:
~/.ssh/config
Host 10.* 192.168.*.* 172.31.* 172.30.* 172.2?.* 172.1?.*
# Disable HostKey verification
# Trust HostKey automatically
StrictHostKeyChecking no
# Do not save the HostKey
UserKnownHostsFile=/dev/null
# Do not display: "Warning: Permanently Added ..."
LogLevel Error
Uruchom polecenie podczas logowania
Jeśli używasz sesji interaktywnej, istnieje kilka sposobów wykonania polecenia po zalogowaniu:
- użyj pliku
authorized_keysna zdalnym hoście (zobacz sshd(8) § AUTHORIZED_KEYS FILE FORMAT) - użyj
~/.ssh/rcna zdalnym hoście, jeśli serwer włączył opcjęPermitUserRC - użyj pliku konfiguracyjnego powłoki na zdalnym hoście, np.
.bashrc
Przekierowanie agenta
Przekierowanie agenta SSH pozwala na korzystanie z kluczy lokalnych po połączeniu z serwerem. Zaleca się [4] włączenie przekierowania agenta tylko dla wybranych hostów.
~/.ssh/config
Host myserver.com
ForwardAgent yes
Następnie skonfiguruj SSH agent i dodaj klucz lokalny za pomocą polecenia ssh-add.
Jeśli teraz połączysz się ze zdalnym serwerem, będziesz mógł połączyć się z innymi usługami, korzystając z kluczy lokalnych.
Generowanie nowych kluczy
Nowe klucze prywatne serwera można wygenerować poprzez:
- Usuwanie wszystkich kluczy, np.:
# rm /etc/ssh/ssh_host_*_key*
-
Restart
sshdgenkeys.servicelub uruchomieniessh-keygen -Ajako root.
Bardziej elegancką alternatywą jest przejście. Najpierw wygeneruj nowe klucze hosta:
# ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key.new # ssh-keygen -t ecdsa -b 521 -f /etc/ssh/ssh_host_ecdsa_key.new # ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key.new
Dodaj stare i nowe klucze do /etc/ssh/sshd_config.d/10-hostkeys.conf:
HostKey /etc/ssh/ssh_host_ecdsa_key HostKey /etc/ssh/ssh_host_ecdsa_key.new HostKey /etc/ssh/ssh_host_ed25519_key HostKey /etc/ssh/ssh_host_ed25519_key.new HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh/ssh_host_rsa_key.new
Restart sshd.service.
Klienci poznają nowe odciski kluczy hosta i dodadzą je do ~/.ssh/known-hosts przy następnym połączeniu z serwerem.
Po pewnym czasie stare klucze można usunąć z /etc/ssh/sshd_config.d/10-hostkeys.conf, pozostawiając jedynie nowe klucze:
HostKey /etc/ssh/ssh_host_ecdsa_key.new HostKey /etc/ssh/ssh_host_ed25519_key.new HostKey /etc/ssh/ssh_host_rsa_key.new
Restart sshd.service, a następnie fizycznie usuń stare klucze:
# rm /etc/ssh/ssh_host_{ecdsa,ed25519,rsa}_key
Klienci automatycznie zaktualizują ~/.ssh/known-hosts, usuwając odciski palców starych kluczy.
Uruchom sshd jako użytkownik bez uprawnień
Możesz chcieć uruchomić sshd jako użytkownik bez uprawnień w kontenerach lub w celach testowych itd.
Ponieważ użytkownik bez uprawnień nie może odczytać kluczy hosta w /etc/ssh, należy wygenerować nowe klucze hosta:
$ ssh-keygen -q -N "" -t rsa -b 4096 -f /path/to/host/keys/ssh_host_rsa_key $ ssh-keygen -q -N "" -t ecdsa -f /path/to/host/keys/ssh_host_ecdsa_key $ ssh-keygen -q -N "" -t ed25519 -f /path/to/host/keys/ssh_host_ed25519_key
Utwórz plik sshd_config. Poniższy przykład używa portu wyższego niż 1024, podaje nową ścieżkę do kluczy hosta i wyłącza PAM:
/path/to/sshd_config
Port 2022 HostKey /path/to/host/keys/ssh_host_rsa_key HostKey /path/to/host/keys/ssh_host_ecdsa_key HostKey /path/to/host/keys/ssh/ssh_host_ed25519_key UsePAM no
Uruchom „sshd” z utworzoną konfiguracją. Flaga -D wyłącza tryb demona, a -e przekierowuje wyjście do stderr, aby umożliwić łatwe monitorowanie.
$ sshd -f /path/to/sshd_config -D -e
Rozwiązywanie problemów
Lista kontrolna
Sprawdź te proste kwestie zanim zaczniesz szukać dalej.
- Katalog konfiguracyjny
~/.sshi jego zawartość powinny być dostępne tylko dla użytkownika (należy to sprawdzić zarówno po stronie klienta, jak i serwera), a katalog domowy użytkownika powinien być dostępny do zapisu tylko dla tego użytkownika:$ chmod go-w ~ $ chmod 700 ~/.ssh $ chmod 600 ~/.ssh/* $ chown -R $USER ~/.ssh
- Sprawdź, czy klucz publiczny klienta (np.
id_ed25519.pub) znajduje się w~/.ssh/authorized_keysna serwerze. - Sprawdź, czy nie ograniczyłeś dostępu SSH za pomocą
AllowUserslubAllowGroupsw server config. - Sprawdź, czy użytkownik ustawił hasło. Czasami nowi użytkownicy, którzy jeszcze nie zalogowali się na serwerze, nie mają hasła.
-
Append
LogLevel DEBUGdo/etc/ssh/sshd_config. - Uruchom
journalctl -xejako root, aby sprawdzić możliwe komunikaty (o błędach). -
Restart
sshdi wyloguj się/zaloguj zarówno na kliencie, jak i serwerze.
Odmowa połączenia lub problem z przekroczeniem limitu czasu
Przekierowanie portów
Jeśli jesteś za NAT-em/routerem (co jest prawdopodobne, chyba że używasz VPS-a lub hosta z adresem publicznym), upewnij się, że router przekierowuje przychodzące połączenia SSH do Twojej maszyny. Znajdź wewnętrzny adres IP serwera za pomocą ip addr i skonfiguruj router do przekierowywania TCP na port SSH na ten adres IP. portforward.com może w tym pomóc.
Czy protokół SSH działa i nasłuchuje?
ss wyświetla wszystkie procesy nasłuchające na porcie TCP za pomocą polecenia:
$ ss --tcp --listening
Jeśli powyższe polecenie nie pokazuje, że system nasłuchuje na porcie ssh, SSH nie jest uruchomiony sprawdź journal pod kątem błędów itd.
Czy istnieją reguły zapory sieciowej blokujące połączenie?
Iptables może blokować połączenia na porcie 22. Sprawdź to za pomocą:
# iptables -nvL
i poszukaj reguł, które mogą powodować odrzucanie pakietów w łańcuchu INPUT. Następnie, jeśli to konieczne, odblokuj port poleceniem takim jak:
# iptables -I INPUT 1 -p tcp --dport 22 -j ACCEPT
Aby uzyskać dalszą pomoc w konfigurowaniu zapór sieciowych, zobacz firewalls.
Czy ruch w ogóle dociera do Twojego komputera?
Rozpocznij przechwyt ruchu na komputerze, na którym występuje problem:
# tcpdump -lnn -i any port ssh and tcp-syn
Powinno to wyświetlić podstawowe informacje, a następnie czekać na pasujący ruch sieciowy przed jego wyświetleniem. Przetestuj połączenie. Jeśli nie widzisz żadnych danych wyjściowych podczas próby połączenia, oznacza to, że coś spoza komputera blokuje ruch (np. zapora sprzętowa, router NAT itp.).
Twój dostawca usług internetowych lub osoba trzecia blokuje domyślny port?
W niektórych przypadkach dostawca usług internetowych może blokować domyślny port SSH (port 22), w związku z czym wszelkie próby (otwieranie portów, hartowanie konfiguracji, obrona przed atakami flood, itp.) okazują się bezużyteczne. Aby to potwierdzić, utwórz serwer nasłuchujący na wszystkich interfejsach (0.0.0.0) i połącz się zdalnie.
Jeśli pojawi się komunikat o błędzie podobny do tego:
ssh: connect to host www.inet.hr port 22: Connection refused
Oznacza to, że port nie jest blokowany przez dostawcę usług internetowych, ale serwer nie uruchamia protokołu SSH na tym porcie (zobacz security through obscurity).
Jeśli jednak pojawi się komunikat o błędzie podobny do tego:
ssh: connect to host 111.222.333.444 port 22: Operation timed out
Oznacza to, że coś odrzuca ruch TCP na porcie 22. Port jest niewidoczny, albo przez zaporę sieciową, albo przez interwencję strony trzeciej (np. dostawcę usług internetowych blokujący lub odrzucający ruch przychodzący na porcie 22). Jeśli na komputerze nie uruchamiasz zapory sieciowej i routery/przełączniki działają prawidłowo, to dostawca usług internetowych blokuje ruch.
Aby to sprawdzić, możesz uruchomić Wiresharka na serwerze i nasłuchiwać ruch na porcie 22. Ponieważ Wireshark to analizator pakietów warstwy 2, a TCP/UDP to warstwy 3 i wyższe (patrz IP Network stack), jeśli nie otrzymasz żadnych danych podczas połączenia zdalnego, trzecia strona najprawdopodobniej blokuje ruch na tym porcie do Twojego serwera.
Diagnosis
Install tcpdump lub Wireshark z pakietem wireshark-cli.
For tcpdump:
# tcpdump -ni interface "port 22"
W przypadku Wiresharka:
$ tshark -f "tcp port 22" -i interface
gdzie interface to interfejs sieciowy połączenia WAN (sprawdź ip a). Jeśli nie odbierasz żadnych pakietów podczas próby połączenia zdalnego, możesz być pewien, że Twój dostawca usług internetowych blokuje ruch przychodzący na porcie 22.
Możliwe rozwiązanie
Rozwiązaniem jest po prostu użycie innego portu, którego dostawca usług internetowych nie blokuje. Otwórz plik /etc/ssh/sshd_config i skonfiguruj go tak, aby korzystał z innych portów. Na przykład dodaj:
Port 22 Port 1234
Upewnij się również, że pozostałe wiersze konfiguracji „Port" w pliku są zakomentowane. Samo zakomentowanie „Port 22" i dodanie „Port 1234" nie rozwiąże problemu, ponieważ wtedy sshd będzie słuchać tylko na porcie 1234. Pozostaw oba wiersze bez komentarza, aby uruchomić serwer SSH na obu portach.
Restart usługę sshd.service — prawie gotowe. Pozostaje skonfigurować klienta(ów) do używania innego portu zamiast domyślnego. Istnieje wiele rozwiązań, poniżej omówimy dwa z nich.
Read from socket failed: connection reset by peer
Najnowsze wersje OpenSSH czasami powodują błąd i wyświetlają powyższy komunikat o błędzie podczas łączenia się ze starszymi serwerami SSH. Można to obejść, ustawiając różne client options dla danego hosta. Więcej informacji na temat poniższych opcji można znaleźć w ssh_config(5).
Problemem mogą być eliptyczne algorytmy klucza hosta ecdsa-sha2-nistp*-cert-v01@openssh. Można je wyłączyć, ustawiając HostKeyAlgorithms na listę wykluczającą te algorytmy. Po stronie klienta, HostKeyAlgorithms, którego klient chce użyć, można również ustawić, poprzedzając listę HostKeyAlgorithms znakiem -, aby usunąć określone algorytmy (w tym symbole wieloznaczne) z domyślnego zestawu (patrz ssh_config(5)).
Możesz sprawdzić aktualnie używany algorytm klucza hosta za pomocą ssh -v server_to_connect_to w wierszu zawierającym kex: host key algorithm:.
Jeśli to nie pomoże, przyczyną może być zbyt długa lista szyfrów. Ustaw opcję Ciphers na krótszą listę (mniej niż 80 znaków powinno wystarczyć). Możesz również spróbować skrócić listę MACs.
Zobacz także dyskusję na forum błędów OpenSSH.
"[your shell]: No such file or directory" / ssh_exchange_identification problem
Jedną z możliwych przyczyn jest wymóg niektórych klientów SSH, aby znaleźć ścieżkę bezwzględną (na przykład zwracaną przez whereis -b [your shell]) w zmiennej $SHELL, nawet jeśli plik binarny powłoki znajduje się w jednym z katalogów $PATH.
"Terminal unknown" or "Error opening terminal" error message
Jeżeli podczas logowania otrzymujesz powyższe błędy, oznacza to, że serwer nie rozpoznaje Twojego terminala. Aplikacje ncurses, takie jak nano, mogą przestać działać, wyświetlając komunikat Error opening terminal.
Prawidłowym rozwiązaniem jest zainstalowanie pliku terminfo terminala klienta na serwerze. Dzięki temu programy konsolowe na serwerze będą mogły poprawnie wchodzić w interakcję z terminalem. Informacje o bieżącym pliku terminfo można uzyskać za pomocą polecenia infocmp, a następnie dowiedzieć się, który pakiet jest jego właścicielem.
Jeżeli nie możesz go install normalnie, możesz skopiować terminfo do katalogu domowego na serwerze:
$ ssh myserver mkdir -p ~/.terminfo/${TERM:0:1}
$ scp /usr/share/terminfo/${TERM:0:1}/$TERM myserver:~/.terminfo/${TERM:0:1}/
Po zalogowaniu się i wylogowaniu z serwera problem powinien zostać rozwiązany.
TERM hack
Alternatywnie, możesz po prostu ustawić TERM=xterm w swoim środowisku na serwerze (np. w .bash_profile). To wyciszy błąd i umożliwi ponowne uruchomienie aplikacji ncurses, ale możesz doświadczyć dziwnego zachowania i błędów graficznych, chyba że sekwencje sterujące w Twoim terminalu będą dokładnie takie same jak w xterm.
Connection closed by x.x.x.x [preauth]
Jeśli widzisz ten błąd w logach sshd, upewnij się, że ustawiłeś prawidłowy HostKey:
/etc/ssh/sshd_config
HostKey /etc/ssh/ssh_host_ed25519_key
subsystem request failed
Ponieważ od wersji OpenSSH 8.8 scp domyślnie używa protokołu SFTP do przesyłania danych, żądając podsystemu sftp. Aby sprawdzić, którego podsystemu używa klient, uruchom scp -v. Błędy takie jak subsystem request failed on channel 0 można naprawić poprzez konfigurację ustawienia sshd_config(5) § Subsystem na serwerze. Konfiguracja serwera powinna przypominać poniższy przykład.
/etc/ssh/sshd_config
... Subsystem subsystem-name /path/to/subsystem-executable ...
id_dsa refused
W OpenSSH 7.0 klucze publiczne DSA zostały wycofane ze względów bezpieczeństwa, a OpenSSH 9.8 został domyślnie zbudowany bez obsługi kluczy DSA. Pierwsza wersja OpenSSH w 2025 roku całkowicie usunie obsługę kluczy DSA. Na razie, jeśli absolutnie musisz ich używać, musisz przebudować openssh, przekazując --enable-dsa-keys do configure.[5]
No matching key exchange method found by OpenSSH 7.0
W OpenSSH 7.0 algorytm klucza diffie-hellman-group1-sha1 został wycofany ze względu na jego słabość i teoretycznie mieści się w zakresie tzw. ataku Logjam (patrz https://www.openssh.com/legacy.html). Jeśli algorytm klucza jest potrzebny dla konkretnego hosta, SSH wygeneruje komunikat o błędzie podobny do poniższego:
Unable to negotiate with 127.0.0.1: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
Najlepszym rozwiązaniem tych problemów jest aktualizacja/skonfigurowanie serwera tak, aby nie używał przestarzałych algorytmów. Jeśli to niemożliwe, można wymusić na kliencie ponowne włączenie algorytmu za pomocą client option KexAlgorithms +diffie-hellman-group1-sha1.
tmux/screen session killed when disconnecting from SSH
Parafrazując odpowiedź na platformie Unix Stackexchange:
Jeśli procesy są zamykane na koniec sesji SSH, możliwe że używasz aktywacji soketów. Twój proces jest zamykany przez systemd, gdy wykryje, że proces sesji SSH się zakończył. W tym przypadku istnieją dwa rozwiązania:
- Unikaj aktywacji soketów poprzez migrację do
sshd.service(zalecane, patrz #Socket activation) lub - Ustaw
KillMode=processw sekcji[Service]wsshd@.service.
Choć nie jest to konieczne, ustawienie KillMode=process w sshd.service może być również przydatne, gdyż pozwala uniknąć zamykania procesu sesji SSH i jego procesu screen lub tmux po zatrzymaniu lub ponownym uruchomieniu serwera.
Należy pamiętać, że ta opcja może nie działać z logind.
Sesja SSH przestaje odpowiadać
SSH reaguje na flow control commands XON i XOFF. Po naciśnięciu Ctrl+s protokół zawiesi się lub przestanie odpowiadać. Użyj Ctrl+q, aby wznowić sesję.
Broken pipe
Jeśli próbujesz utworzyć połączenie, co skutkuje odpowiedzią Broken pipe na packet_write_wait, powinieneś ponowić próbę nawiązania połączenia w trybie debugowania i sprawdzić, czy dane wyjściowe zakończą się błędem:
debug3: send packet: type 1 packet_write_wait: Connection to A.B.C.D port 22: Broken pipe
Powyższy wiersz send packet wskazuje, że pakiet odpowiedzi nigdy nie został odebrany. Wynika z tego, że jest to problem z „QoS”. Aby zmniejszyć prawdopodobieństwo utraty pakietu, ustaw IPQoS:
/etc/ssh/ssh_config
Match all
IPQoS reliability
Problem powinien zostać rozwiązany przez usługę typu reliability (0x04), a także przez 0x00 i throughput (0x08).
Zakończ nieodpowiadające połączenie SSH
Jeśli sesja klienta nie odpowiada i nie można jej zakończyć, wydając polecenie działającemu programowi (np. shell), nadal można zakończyć sesję, naciskając kolejno Enter, ~ i ..
~ to znak ucieczki pseudo-terminala (patrz ssh(1) § ESCAPE CHARACTERS), który można dodać wielokrotnie w zależności od sesji klienta, którą chcesz zakończyć. Na przykład, jeśli połączyłeś się z A do B, a następnie z B do C, a sesja z B do C zawiesi się, możesz ją zakończyć, naciskając Enter i wpisując ~~., co pozostawi Cię w działającej sesji na B.
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
Jeśli klient ostrzega o zmianie klucza serwera SSH, należy zweryfikować, czy nowo udostępniony klucz rzeczywiście należy do operatora serwera, za pośrednictwem uwierzytelnionego (niekoniecznie szyfrowanego) kanału. Następnie należy usunąć stary klucz z pliku known_hosts za pomocą polecenia ssh-keygen -R $SSH_HOST i zaakceptować nowy klucz tak, jakby był to nowy serwer.
Łączenie się ze zdalnym komputerem bez odpowiedniego wpisu terminfo
Łącząc się z hostami, które nie mają wpisu terminfo dla Twojego terminala, na przykład podczas korzystania z emulatora terminala, którego wpis terminfo nie jest dostarczany z ncurses (np. kitty i rxvt-unicode), lub łącząc się z hostami z ograniczoną bazą danych terminfo (np. systemami z OpenWrt), mogą pojawić się różne problemy z oprogramowaniem, które opiera się na terminfo(5).
Prawidłowym rozwiązaniem jest umieszczenie odpowiedniego wpisu terminfo na hoście. Jeśli nie jest to możliwe, alternatywą jest ustawienie TERM na wartość, która jest obsługiwana przez host zdalny i zgodna z terminalem.
Od OpenSSH 8.7 można przesłać dowolną zmienną środowiskową TERM do zdalnych hostów za pomocą prostej konfiguracji:
~/.ssh/config
Host example.com SetEnv TERM=xterm-256color
Connection through jump host fails with "bash: No such file or directory"
Jeśli zmienna środowiskowa SHELL nie jest ustawiona na pełną, prawidłową ścieżkę (na serwerze jump), połączenie nie powiedzie się z komunikatem o błędzie podobnym do:
bash: No such file or directory kex_exchange_identification: Connection closed by remote host Connection closed by UNKNOWN port 65535
Możesz rozwiązać to, ustawiając SHELL na pełną ścieżkę powłoki, która będzie ważna również na jump serverze, lub ustawiając zmienną SHELL dla każdego serwera w pliku ~/.ssh/config.