SSD Nodes Learn Hosting plans →
Przewodniki Matt ConnorAutor: Matt Connor · Zaktualizowano 2026-08-28

SSH przez Tor onion service bez otwartych portów

Konfiguracja SSH przez ukrytą usługę sieci Tor pozwala wyłączyć porty przychodzące na VPS. Poradnik omawia autoryzację v3 oraz kolejność działań zapobiegającą utracie dostępu.

Co zmienia SSH przez usługę onion sieci Tor

SSH przez usługę onion sieci Tor umożliwia administrowanie serwerem VPS, który nie akceptuje żadnych połączeń przychodzących na żadnym porcie. Serwer nawiązuje połączenie z siecią Tor i utrzymuje je w stanie otwartym. Sesja SSH dociera przez ten tunel, dzięki czemu żaden proces nie musi nasłuchiwać na publicznym adresie IP.

Wpływ na logi jest natychmiastowy. Maszyna z publicznym portem SSH rejestruje tysiące nieudanych prób logowania dziennie, pochodzących ze skanerów. Przeniesienie sshd za usługę onion i zablokowanie ruchu przychodzącego na firewallu sprawia, że /var/log/auth.log rejestruje od tego momentu wyłącznie sesje zainicjowane przez administratora.

Koszt tego rozwiązania polega na tym, że tor znajduje się na ścieżce każdej sesji administracyjnej. Jest to demon działający w przestrzeni użytkownika, który musi uruchomić się i zainicjować po każdym restarcie systemu, zanim możliwe będzie zalogowanie. Należy to uwzględnić przed zamknięciem portu, ponieważ awaria w tym scenariuszu oznacza utratę dostępu do maszyny, do której nie ma fizycznego dostępu.

Zapewnienie dostępu awaryjnego przed rozpoczęciem prac

Nie należy rozpoczynać działań bez przygotowania ścieżki odzyskiwania, która nie wykorzystuje SSH.

Należy otworzyć konsolę dostawcy, czyli konsolę VNC lub szeregową w panelu sterowania, i zalogować się za jej pomocą. Jeśli hasło użytkownika root nie jest znane, należy najpierw zresetować hasło root z poziomu panelu i potwierdzić jego działanie. Konsola, która nie została przetestowana, nie stanowi ścieżki odzyskiwania.

Kolejność kroków ma znaczenie. Każdy etap jest weryfikowany przed przejściem do kolejnego, a port 22 pozostaje otwarty do momentu poprawnego działania trasy onion.

  1. Zainstaluj tor i potwierdź, że proces bootstrap został zakończony.
  2. Zdefiniuj usługę onion i odczytaj jej adres.
  3. Połącz się przez sieć onion, podczas gdy port 22 jest nadal otwarty.
  4. Dodaj autoryzację klienta, a następnie połącz się ponownie.
  5. Powiąż sshd z interfejsem loopback i zamknij port 22.
  6. Zrestartuj system, a następnie połącz się ponownie przez sieć onion.

Przez cały czas należy utrzymywać otwartą bieżącą sesję SSH. Ustanowiona sesja przetrwa zmianę reguł firewalla, która zablokowałaby nowe połączenie, dlatego stanowi ona pierwszą linię ratunkową.

Instalacja tor na serwerze

Ubuntu dostarcza tor we własnym repozytorium, a ta wersja jest często przestarzała. Repozytorium Tor Project zawiera wersję opisaną w ich dokumentacji. Należy je dodać za pomocą poleceń z ich przewodnika po repozytorium apt.

sudo apt update
sudo apt install -y apt-transport-https wget gpg
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/null

Użyj /etc/apt/sources.list.d/tor.sources. Suites przyjmuje nazwę kodową wydania, którą wyświetla lsb_release -cs (noble w przypadku Ubuntu 24.04).

Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: noble
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpg
sudo apt update
sudo apt install -y tor deb.torproject.org-keyring
sudo journalctl -u tor@default -n 20 --no-pager

Dziennik powinien kończyć się wpisem Bootstrapped 100% (done). Zatrzymanie się poniżej tego punktu oznacza, że tor nie może uzyskać dostępu do sieci, co niemal zawsze wynika z reguły wychodzącej firewalla lub nieprawidłowego ustawienia zegara systemowego.

Nazwa jednostki jest myląca. systemctl status tor zgłasza Active: active (exited) nawet wtedy, gdy wszystko działa poprawnie, ponieważ w systemach Debian i Ubuntu pakiet tor jest jednostką nadrzędną dla wielu instancji, której jedynym zadaniem jest uruchomienie właściwej instancji. Sam demon działa jako tor@default.service. Należy używać tej nazwy w poleceniach status oraz journalctl. Polecenia start, stop i reload wydane dla tor nadal docierają do instancji, więc sudo systemctl reload tor działa zgodnie z oczekiwaniami.

Definiowanie usługi onion dla portu 22

Dodaj dwie linie do /etc/tor/torrc.

HiddenServiceDir /var/lib/tor/ssh/
HiddenServicePort 22 127.0.0.1:22

Druga linia instruuje tor, aby akceptował wirtualny port 22 na adresie onion i łączył się z 127.0.0.1:22 na serwerze. Tor uzyskuje dostęp do sshd przez interfejs loopback, co jest powodem, dla którego sshd może później przestać nasłuchiwać na publicznym adresie. Skierowanie tej drugiej linii na serwer WWW pod adresem 127.0.0.1:80 pozwala na publikację witryny pod adresem onion, co jest użyteczną drugą usługą po zainstalowaniu tor.

sudo systemctl reload tor
sudo cat /var/lib/tor/ssh/hostname

Polecenie to wyświetla 56 znaków w formacie base32, po których następuje .onion. Znaki te stanowią klucz publiczny usługi w formie zakodowanej. W tym procesie nie uczestniczy żaden urząd certyfikacji ani rejestracja nazwy.

Pozwól, aby tor samodzielnie utworzył /var/lib/tor/ssh/. Ręczne utworzenie tego katalogu z niewłaściwym właścicielem lub uprawnieniami luźniejszymi niż 0700 spowoduje, że tor odmówi jego użycia, a dziennik systemowy zgłosi błąd zbyt szerokich uprawnień. Pliki wewnątrz katalogu stanowią tożsamość usługi: hs_ed25519_secret_key jest adresem. Wykonaj kopię zapasową tego katalogu z uprawnieniami 600 i przechowuj ją poza serwerem, ponieważ utrata tych plików oznacza konieczność wygenerowania nowego adresu i edycji konfiguracji u każdego klienta.

Połączenie ze stacji roboczej

Stacja robocza wymaga klienta tor, który nie wymaga żadnej konfiguracji. W systemach Debian lub Ubuntu jest to sudo apt install -y tor netcat-openbsd. Tor nasłuchuje następnie na 127.0.0.1:9050 jako proxy SOCKS5. SOCKS to ogólny protokół proxy, a wersja 5 potrafi przesyłać nazwę hosta zamiast adresu IP, co jest w tym przypadku kluczowe.

OpenSSH nie posiada własnego klienta SOCKS, dlatego do nawiązania połączenia wykorzystywany jest program pomocniczy. Należy dodać poniższą konfigurację do ~/.ssh/config.

Host myvps
  HostName xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.onion
  User admin
  ProxyCommand /usr/bin/nc -X 5 -x 127.0.0.1:9050 %h %p
  ServerAliveInterval 30

-X 5 wybiera SOCKS5, a -x 127.0.0.1:9050 wskazuje na lokalny proces tor. %h przekazuje nazwę onion do tor jako nazwę, dzięki czemu tor rozwiązuje ją wewnątrz sieci. Wymagane jest użycie OpenBSD netcat. GNU netcat nie posiada opcji -X i kończy działanie błędem nc: invalid option -- 'X'.

ssh myvps

Pierwsze połączenie jest powolne, ponieważ tor musi najpierw zbudować obwód. Należy zaakceptować odcisk klucza hosta w taki sam sposób, jak w każdym innym przypadku. Od tego momentu mają zastosowanie standardowe zasady obsługi kluczy SSH. Warstwa transportowa uległa zmianie. Uwierzytelnianie pozostało bez zmian.

W przypadku jednorazowego połączenia można pominąć wpis w konfiguracji: torsocks ssh admin@xxxxx.onion wykonuje to samo zadanie.

Dodawanie autoryzacji klienta v3

W obecnej konfiguracji każdy, kto pozna adres, może połączyć się z banerem SSH i rozpocząć próby odgadywania hasła. Adresy Onion nie są wymienione w systemie katalogów, więc adres działa jak sekret, jednak wycieka w typowy sposób: poprzez historię powłoki oraz pliki konfiguracyjne zatwierdzone w repozytorium git. Autoryzacja klienta eliminuje to ryzyko. Usługa publikuje swój deskryptor zaszyfrowany kluczem klienta, więc osoba posiadająca adres, ale nieposiadająca klucza, nie jest w stanie nawet zlokalizować usługi.

Wygeneruj parę kluczy x25519 na kliencie. Poniżej znajduje się potok poleceń pochodzący z przewodnika autoryzacji klienta projektu Tor, z jedną modyfikacją.

openssl genpkey -algorithm x25519 -out /tmp/k1.prv.pem
grep -v " PRIVATE KEY" /tmp/k1.prv.pem | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.prv.key
openssl pkey -in /tmp/k1.prv.pem -pubout | grep -v " PUBLIC KEY" | base64 -d | tail --bytes=32 | base32 | sed 's/=//g' > /tmp/k1.pub.key

Opublikowana wersja tych linii używa base64pem -d, którego standardowa instalacja Ubuntu nie zawiera. Polecenie kończy się wtedy błędem base64pem: command not found. GNU base64 -d dekoduje ten sam korpus PEM, dlatego należy użyć go w zamian.

Na serwerze zainstaluj klucz publiczny.

sudo install -d -m 700 -o debian-tor -g debian-tor /var/lib/tor/ssh/authorized_clients
echo "descriptor:x25519:PASTE_PUBLIC_KEY_HERE" | sudo tee /var/lib/tor/ssh/authorized_clients/laptop.auth >/dev/null
sudo chown debian-tor:debian-tor /var/lib/tor/ssh/authorized_clients/laptop.auth
sudo systemctl reload tor

Odczytywane są tylko pliki kończące się na .auth. Zapisanie pliku jako laptop.auth.txt spowoduje, że tor zignoruje go bez wyświetlenia błędu, a usługa pozostanie otwarta dla każdego, kto zna adres.

Na kliencie zainstaluj klucz prywatny. W systemie Ubuntu demon tor działa jako użytkownik debian-tor i nie ma uprawnień do odczytu plików w katalogu domowym użytkownika, dlatego należy umieścić katalog w miejscu dostępnym dla tego użytkownika.

sudo install -d -m 700 -o debian-tor -g debian-tor /var/lib/tor/onion_auth
echo "ADDRESS_WITHOUT_DOT_ONION:descriptor:x25519:PASTE_PRIVATE_KEY_HERE" | sudo tee /var/lib/tor/onion_auth/myvps.auth_private >/dev/null
sudo chown debian-tor:debian-tor /var/lib/tor/onion_auth/myvps.auth_private
sudo chmod 600 /var/lib/tor/onion_auth/myvps.auth_private

Dodaj ClientOnionAuthDir /var/lib/tor/onion_auth do pliku /etc/tor/torrc klienta i przeładuj tor. Jeśli tor jest uruchamiany jako własny użytkownik, na przykład w kompilacji Homebrew w systemie macOS, wskaż ClientOnionAuthDir na ~/.tor/onion_auth z uprawnieniami 0700.

Adres wewnątrz tego pliku to 56 znaków bez przyrostka .onion. Usuń /tmp/k1.prv.pem oraz /tmp/k1.prv.key po zakończeniu pracy.

Teraz przetestuj oba kierunki. ssh myvps powinno nadal nawiązywać połączenie. Z maszyny nieposiadającej klucza, ten sam adres powinien zwracać błąd. Ten błąd jest dowodem na to, że autoryzacja jest aktywna.

Zamknięcie portu 22 w określonej kolejności

Najpierw należy ustawić zabezpieczenie. Poniższe polecenie cofnie obie zmiany opisane poniżej po upływie 15 minut, jeśli użytkownik zostanie zablokowany.

sudo systemd-run --on-active=15m --unit=ssh-rescue \
  /bin/sh -c 'ufw allow 22/tcp; rm -f /etc/systemd/system/ssh.socket.d/override.conf; systemctl daemon-reload; systemctl restart ssh.socket'

Po potwierdzeniu, że połączenie przez sieć onion nadal działa, należy anulować to zabezpieczenie za pomocą sudo systemctl stop ssh-rescue.timer.

Następnie należy zatrzymać nasłuchiwanie sshd na publicznym adresie IP. System Ubuntu 24.04 aktywuje ssh poprzez jednostkę typu socket, dlatego ListenAddress w pliku sshd_config jest ignorowane: to ssh.socket zarządza gniazdem nasłuchującym, a nie sshd. Należy sprawdzić, który przypadek dotyczy bieżącej konfiguracji.

systemctl is-enabled ssh.socket

Jeśli polecenie zwróci enabled, należy uruchomić sudo systemctl edit ssh.socket i dodać poniższą treść.

[Socket]
ListenStream=
ListenStream=127.0.0.1:22

Pusta wartość ListenStream= czyści wartość odziedziczoną z domyślnej jednostki pakietu. Pominięcie tej linii spowoduje dodanie drugiego gniazda nasłuchującego przy jednoczesnym zachowaniu publicznego, co jest najczęstszą przyczyną niepowodzenia tego kroku bez wyświetlenia komunikatu o błędzie.

sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
ss -tlnp | grep ':22'

Polecenie ss powinno wyświetlić 127.0.0.1:22 i brak wpisów dla 0.0.0.0:22. Jeśli ssh.socket było wyłączone, należy umieścić ListenAddress 127.0.0.1 w /etc/ssh/sshd_config.d/10-onion.conf, uruchomić sudo systemctl restart ssh, a następnie sprawdzić wynik za pomocą tego samego polecenia ss. Wyświetlony wynik stanowi potwierdzenie poprawności konfiguracji w obu przypadkach.

Następnie należy skonfigurować zaporę sieciową, co jest standardową procedurą zarządzania regułami ufw na VPS. Najpierw należy uruchomić sudo ufw status numbered i usunąć regułę SSH wskazaną na liście.

sudo ufw status numbered
sudo ufw delete allow OpenSSH
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw status verbose

Należy pozostawić ruch wychodzący jako dozwolony. Tor łączy się z przekaźnikami przez porty takie jak 443 oraz 9001, więc polityka domyślnego blokowania ruchu wychodzącego (default-deny) uniemożliwi proces bootstrapu sieci Tor i jednocześnie usunie jedyną pozostałą drogę dostępu do serwera. Większość dostawców oferuje również zewnętrzną zaporę sieciową w panelu zarządzania. Należy zamknąć port 22 również tam, w przeciwnym razie port pozostanie dostępny niezależnie od raportów ufw.

Jeśli na serwerze działa Docker, przed zakończeniem prac należy sprawdzić opublikowane porty. Docker zapisuje własne reguły bezpośrednio do tych samych tablic i publikuje porty kontenerów z pominięciem ufw, dlatego polityka deny w ufw nie daje pełnego obrazu sytuacji.

Zrestartuj przed zaufaniem

systemctl is-enabled tor@default
sudo reboot

Jeśli pierwsze polecenie nie wskazuje, że usługa jest włączona, uruchom sudo systemctl enable tor@default przed restartem. Odczekaj dwie minuty, a następnie ssh myvps. Tor musi przeprowadzić proces bootstrapu po uruchomieniu systemu, więc adres onion zaczyna odpowiadać dopiero po pewnym czasie od startu maszyny.

Jeśli usługa nie powraca do działania, otwórz konsolę i odczytaj sudo journalctl -u tor@default -b. Znajdują się tam informacje o błędach składni w pliku torrc lub problemach z uprawnieniami do katalogów. Przed zastosowaniem zmian w pliku torrc warto również zweryfikować jego poprawność.

sudo -u debian-tor tor --verify-config

Koszty w porównaniu z tunelem WireGuard

W zestawieniu z własnym VPN WireGuard na VPS, usługa onion jest wolniejsza i mniej przewidywalna. Przed podjęciem decyzji należy uczciwie ocenić różnice.

Opóźnienia. Obwód klienta składa się z trzech przekaźników, a strona usługi dodaje kolejne trzy, więc wpisywane znaki przechodzą przez około sześć losowo wybranych maszyn na całym świecie. Interaktywne pisanie wiąże się z widocznym opóźnieniem, a kopiowanie plików jest powolne. WireGuard dodaje tylko jeden przeskok. Warto zmierzyć własny przypadek za pomocą time ssh myvps 'echo ok', ponieważ wynik zależy od obwodu zbudowanego przez tor i zmienia się przy każdej jego przebudowie.

Demon w przestrzeni użytkownika na ścieżce krytycznej. WireGuard działa w jądrze systemu i uruchamia się wraz z siecią. Tor jest procesem, który musi wystartować, przeprowadzić bootstrap i połączyć się z przekaźnikiem wejściowym (guard relay), zanim cokolwiek zadziała. W przypadku awarii konieczne jest skorzystanie z konsoli dostawcy.

Dokładność zegara. Deskryptory usług onion są publikowane w oparciu o przedziały czasowe, więc nieprawidłowy czas systemowy uniemożliwia wyszukiwanie adresów bez wyświetlenia jasnego komunikatu o błędzie. timedatectl powinno zwracać System clock synchronized: yes.

W zamian otrzymuje się odporność, która nie zależy już od poprawności reguł firewalla. Nie ma portów do skanowania ani banerów do przechwycenia, a sam adres jest kluczem publicznym, więc punkt końcowy potwierdza swoją tożsamość, zanim jeszcze rozpocznie się sesja SSH.

Praktycznym rozwiązaniem jest zazwyczaj stosowanie obu metod. WireGuard służy jako codzienna ścieżka dostępu, a usługa onion pozostaje drogą awaryjną, która działa nawet wtedy, gdy konfiguracja WireGuard jest błędna. Pozwala to na pozostawienie otwartego jednego portu UDP zamiast publicznego portu SSH. Żadne z tych rozwiązań nie zastępuje utwardzania samego sshd: uwierzytelnianie wyłącznie kluczami oraz logowanie użytkownika innego niż root pozostają kluczowe, ponieważ usługa onion chroni jedynie ścieżkę sieciową, a nie to, co znajduje się za nią.

Tryby awarii i występujące błędy

Tor nigdy nie przekazuje Bootstrapped 0%. Ruch wychodzący jest blokowany lub zegar systemowy jest znacznie rozsynchronizowany. Sprawdź politykę ruchu wychodzącego za pomocą sudo ufw status verbose, a następnie uruchom timedatectl.

systemctl status tor zwraca active (exited). Jest to zachowanie typowe dla systemów Debian i Ubuntu. Zamiast tego należy sprawdzić tor@default.

Nie można odnaleźć deskryptora. Tor zwraca rozszerzony błąd SOCKS F0: "Onion Service Descriptor Can Not be Found". Deskryptor nie został jeszcze opublikowany (co zajmuje chwilę po przeładowaniu) lub usługa tor na serwerze nie działa.

F4, "Onion Service Missing Client Authorization". Klient nie posiada pasującego pliku .auth_private, z którego mógłby skorzystać tor. Sprawdź, czy w pliku torrc znajduje się wpis ClientOnionAuthDir, czy katalog posiada uprawnienia 0700, czy nazwa pliku kończy się na .auth_private oraz czy użytkownik debian-tor ma uprawnienia do jego odczytu.

F5, "Onion Service Wrong Client Authorization". Klucz prywatny nie pasuje do pliku .auth na serwerze. Przyczyną jest często znak = na końcu linii lub zbędny znak nowej linii wewnątrz ciągu base32.

nc: invalid option -- 'X'. Zainstalowano wersję GNU netcat zamiast wersji OpenBSD. Uruchom sudo apt install -y netcat-openbsd.

Could not resolve hostname. ssh podjęło próbę użycia standardowego DNS, który nie posiada rekordu dla .onion, przez co ProxyCommand nie zostało uruchomione. Wzorzec Host w pliku ~/.ssh/config nie pasuje do wpisanej nazwy hosta.

Permission denied (publickey). Tunel działa poprawnie i rola tor została zakończona. Należy traktować to jako standardowy problem z odmową dostępu przy uwierzytelnianiu kluczem publicznym i pominąć tor w dalszej diagnostyce.

FAQ

Czy usługa onion faktycznie oznacza brak otwartych portów na VPS?

Tak, pod warunkiem, że sshd jest powiązany z 127.0.0.1, a firewall odrzuca ruch przychodzący. Tor nawiązuje wychodzące połączenie TCP z przekaźnikiem, a sesja jest przesyłana zwrotnie przez tę ścieżkę. Dzięki temu żaden proces na serwerze nie akceptuje połączeń na publicznym adresie IP. Można to zweryfikować za pomocą ss -tlnp na serwerze oraz skanowania portów z zewnątrz. Należy pamiętać o sieciowym firewallu dostawcy w panelu sterowania; jest to mechanizm niezależny od ufw, który również musi zostać zamknięty.

Czy sam adres .onion zapewnia wystarczające bezpieczeństwo dla SSH?

Nie. Adres składa się z 56 znaków i nie można go odgadnąć ani wyliczyć z systemu katalogów, więc działa jak sekret, ale może wyciec przez historię powłoki lub pliki konfiguracyjne. Należy dodać autoryzację klienta w wersji v3. Dzięki niej deskryptor usługi jest szyfrowany kluczem klienta, więc osoba posiadająca tylko adres otrzyma rozszerzony błąd F4 i w ogóle nie połączy się z sshd.

Co się stanie, jeśli tor nie uruchomi się po restarcie?

Utracisz dostęp SSH, ponieważ adres onion jest wówczas jedyną drogą wejścia. Dlatego przed zamknięciem portu 22 należy przetestować konsolę dostawcy. Tor potrzebuje również czasu na bootstrap po uruchomieniu systemu, więc adres odpowie później niż maszyna na polecenie ping. Jeśli usługa nigdy nie odpowiada, zaloguj się przez konsolę i odczytaj sudo journalctl -u tor@default -b, gdzie zapisywane są błędy składni w torrc lub problemy z uprawnieniami do /var/lib/tor/ssh.

Czy SSH przez Tor jest wolniejsze niż WireGuard?

Tak, znacznie. Połączenie z usługą onion przechodzi przez około sześć losowo wybranych przekaźników, podczas gdy WireGuard to jeden szyfrowany przeskok bezpośrednio do serwera. Wpisywanie znaków jest odczuwalnie opóźnione, a transfery są wolne. Typowa konfiguracja zakłada używanie WireGuard do codziennej pracy, przy zachowaniu usługi onion jako awaryjnej ścieżki dostępu, która działa nawet w przypadku błędnej konfiguracji VPN.