SSD Nodes Learn 🎉 VPS від $5.50/міс
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-13

SSH через Tor onion service без відкритих портів

Налаштуйте sshd за Tor onion service без вхідних портів: авторизація клієнта v3 і точний порядок змін, який запобігає втраті доступу до VPS.

Що змінює SSH через onion service Tor

SSH через onion service Tor дає змогу адмініструвати VPS, який не приймає вхідних з’єднань на жодному порту. Сервер сам підключається до мережі Tor і підтримує це з’єднання відкритим. Ваш SSH-сеанс проходить через нього у зворотному напрямку, тому на публічній IP-адресі нічого не має приймати з’єднання.

Вплив на журнал видно одразу. Сервер із публічним SSH-портом щодня отримує тисячі невдалих спроб входу за паролем від сканерів. Якщо розмістити sshd за onion service і заблокувати вхідний трафік у firewall, /var/log/auth.log фіксуватиме лише сеанси, які ви запускали.

Недоліком є те, що tor бере участь у кожному сеансі адміністрування. Це daemon у userspace, який має запуститися та встановити з’єднання після кожного перезавантаження, перш ніж ви зможете ввійти. Врахуйте це до закриття порту, оскільки в разі збою ви втратите доступ до машини, до якої не маєте фізичного доступу.

Підготуйте спосіб відновлення доступу, перш ніж щось змінювати

Не починайте, доки не підготуєте спосіб відновлення доступу без SSH.

Відкрийте консоль свого провайдера: VNC або серійну консоль у панелі керування. Увійдіть через неї. Якщо пароль root невідомий, спочатку скиньте пароль root через панель і перевірте, що він працює. Консоль, яку ви ніколи не тестували, не є способом відновлення доступу.

Наведений нижче порядок має значення. Перед виконанням наступного кроку перевіряється результат попереднього. Порт 22 залишається відкритим, доки onion-маршрут не запрацює.

  1. Установіть tor і переконайтеся, що він успішно запускається.
  2. Визначте onion-сервіс і прочитайте його адресу.
  3. Підключіться через onion, доки порт 22 ще відкритий.
  4. Додайте авторизацію клієнта, а потім підключіться ще раз.
  5. Прив’яжіть sshd до loopback і закрийте порт 22.
  6. Перезавантажте сервер, а потім знову підключіться через onion.

Увесь час залишайте поточний сеанс SSH відкритим. Установлене з’єднання переживе зміну брандмауера, яка заблокувала б нове підключення. Тому це ваш перший спосіб відновити доступ.

Встановлення tor на сервері

Ubuntu постачає tor у власному репозиторії, але ця збірка часто застаріла. Репозиторій Tor Project містить версію, описану в їхній документації. Додайте його за допомогою команд із посібника з 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

Введіть /etc/apt/sources.list.d/tor.sources. Suites підставляє кодову назву вашого випуску, яку виводить lsb_release -cs (noble в 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

Журнал має завершуватися повідомленням Bootstrapped 100% (done). Якщо він зупиняється раніше, tor не може підключитися до мережі. Майже завжди причина полягає у вихідному правилі брандмауера або суттєво неправильному системному часі.

Назва unit є пасткою. systemctl status tor повідомляє Active: active (exited), навіть коли все працює правильно, оскільки Debian і Ubuntu пакують tor як головний unit для кількох екземплярів. Його єдине завдання — підключити фактичний екземпляр. Сам демон працює як tor@default.service. Використовуйте цю назву для status і journalctl. Запуск, зупинка та перезавантаження конфігурації tor все одно передаються екземпляру, тому sudo systemctl reload tor працює очікувано.

Визначте onion-сервіс для порту 22

Додайте два рядки до /etc/tor/torrc.

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

Другий рядок вказує tor приймати віртуальний порт 22 на onion-адресі та підключатися до 127.0.0.1:22 на сервері. Tor звертається до sshd через loopback. Саме тому пізніше sshd можна буде вимкнути на публічній адресі.

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

Ця команда виводить 56 символів base32, після яких іде .onion. Ці символи є закодованим відкритим ключем сервісу. У цій схемі немає центру сертифікації та реєстрації імен у будь-якому сервісі.

Дозвольте tor самостійно створити /var/lib/tor/ssh/. Якщо створити його вручну з неправильним власником або з правами, ширшими за 0700, tor відмовиться його використовувати, а журнал повідомить, що права доступу до каталогу надто широкі. Файли всередині містять ідентичність сервісу: hs_ed25519_secret_key є адресою. Створіть резервну копію цього каталогу з правами 600 і зберігайте копію не на цьому сервері, оскільки її втрата означає нову адресу та зміну конфігурації на кожному клієнті.

Підключення з робочої станції

На робочій станції потрібен клієнт Tor. Додатково його налаштовувати не потрібно. У Debian або Ubuntu це sudo apt install -y tor netcat-openbsd. Після цього Tor прослуховує 127.0.0.1:9050 як проксі SOCKS5. SOCKS — це універсальний протокол проксі. Версія 5 може передавати ім’я хоста замість IP-адреси. Саме це тут важливо.

OpenSSH не має власного клієнта SOCKS, тому для підключення потрібна допоміжна програма. Додайте це до ~/.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 вибирає SOCKS5, а -x 127.0.0.1:9050 вказує на локальний Tor. %h передає ім’я onion-вузла до Tor саме як ім’я, тому Tor розпізнає його всередині мережі. Це має бути OpenBSD netcat. GNU netcat не підтримує параметр -X і завершує роботу з повідомленням nc: invalid option -- 'X'.

ssh myvps

Перше підключення повільне, оскільки Tor спочатку будує circuit. Прийміть fingerprint ключа хоста так само, як і в інших підключеннях. Надалі звичайна робота з ключами SSH не змінюється. Змінюється транспорт. Автентифікація залишається тією самою.

Для одноразового підключення запис конфігурації можна пропустити: torsocks ssh admin@xxxxx.onion виконує те саме завдання.

Додайте авторизацію клієнта v3

Зараз будь-хто, хто дізнається адресу, може отримати банер SSH і почати підбирати облікові дані. Onion-адреси неможливо перелічити через систему каталогів, тому адреса поводиться як секрет, але може витекти звичайними способами: через історію shell або конфігураційні файли, зафіксовані в git-репозиторії. Авторизація клієнта усуває цю проблему. Сервіс публікує свій дескриптор, зашифрований для ключа клієнта, тому той, хто має адресу, але не має ключа, навіть не зможе знайти сервіс.

Згенеруйте пару ключів x25519 на клієнті. Це конвеєр із посібника Tor Project з авторизації клієнта, але з однією зміною.

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

В опублікованій версії цих рядків використовується base64pem -d, якого немає у стандартній інсталяції Ubuntu. Після цього команда завершується помилкою base64pem: command not found. GNU base64 -d декодує тіло PEM так само, тому використовуйте його.

На сервері встановіть відкритий ключ.

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

Зчитуються лише файли, що закінчуються на .auth. Збережіть ключ як laptop.auth.txt, інакше tor без повідомлення про помилку проігнорує файл, а сервіс непомітно залишиться доступним для всіх, хто має адресу.

На клієнті встановіть закритий ключ. В Ubuntu демон tor працює від імені користувача debian-tor і не може читати файли у вашому домашньому каталозі, тому розмістіть каталог у місці, доступному цьому користувачу.

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

Додайте ClientOnionAuthDir /var/lib/tor/onion_auth до /etc/tor/torrc клієнта та перезавантажте конфігурацію tor. Якщо ви запускаєте tor від імені власного користувача, наприклад збірку Homebrew у macOS, вкажіть у ClientOnionAuthDir шлях до ~/.tor/onion_auth з режимом 0700.

Адреса у цьому файлі містить 56 символів без суфікса .onion. Після завершення видаліть /tmp/k1.prv.pem і /tmp/k1.prv.key.

Тепер перевірте обидва варіанти. ssh myvps має й надалі підключатися. З комп’ютера, на якому немає ключа, підключення за тією самою адресою має завершитися невдачею. Це підтверджує, що авторизацію активовано.

Закрийте порт 22 у такому порядку

Спочатку встановіть запобіжний таймер. Ця одна команда скасує обидві наведені нижче зміни через п’ятнадцять хвилин, якщо ви втратите доступ до сервера.

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'

Скасуйте таймер командою sudo systemctl stop ssh-rescue.timer після того, як переконаєтеся, що onion-маршрут і далі працює.

Далі припиніть прослуховування публічної адреси процесом sshd. В Ubuntu 24.04 SSH активується через socket unit, тому ListenAddress у sshd_config ігнорується: сокет для прослуховування належить ssh.socket, а не sshd. Перевірте, який варіант використовується у вашій системі.

systemctl is-enabled ssh.socket

Якщо команда виведе enabled, виконайте sudo systemctl edit ssh.socket і додайте такий фрагмент.

[Socket]
ListenStream=
ListenStream=127.0.0.1:22

Порожнє значення ListenStream= очищає значення, успадковане від пакетного unit. Якщо не додати цей рядок, ви створите другий listener, але публічний залишиться активним. Це найпоширеніша причина непомітної помилки на цьому кроці.

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

Команда ss має показати 127.0.0.1:22 і не показувати нічого на 0.0.0.0:22. Якщо ssh.socket було вимкнено, додайте ListenAddress 127.0.0.1 у /etc/ssh/sshd_config.d/10-onion.conf, виконайте sudo systemctl restart ssh, а потім перевірте результат тим самим рядком ss. Вивід команди в обох випадках підтверджує правильність налаштування.

Потім налаштуйте firewall. Це звичайне керування правилами ufw на VPS. Спочатку виконайте sudo ufw status numbered і видаліть правило SSH, яке буде показано у виводі.

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

Не забороняйте вихідний трафік. Tor підключається до relay на таких портах, як 443 і 9001, тому політика за замовчуванням із забороною вихідного трафіку зупиняє початкове підключення Tor і водночас усуває єдиний спосіб повторно отримати доступ до сервера. Більшість провайдерів також мають окремий мережевий firewall у панелі керування. Закрийте порт 22 і там, інакше він залишатиметься доступним незалежно від того, що показує ufw.

Якщо на цьому сервері працює Docker, перевірте опубліковані порти перед завершенням роботи. Docker додає власні правила до тих самих таблиць і публікує порти контейнерів безпосередньо в обхід ufw, тому політика deny в ufw не дає повної картини.

Перезавантажте сервер перед перевіркою

systemctl is-enabled tor@default
sudo reboot

Якщо перша команда не повідомляє, що сервіс увімкнено, виконайте sudo systemctl enable tor@default перед перезавантаженням. Зачекайте дві хвилини, а потім виконайте ssh myvps. Після завантаження Tor має виконати bootstrap, тому onion-адреса починає відповідати через деякий час після запуску самого сервера.

Якщо сервіс так і не відновився, відкрийте консоль і перегляньте sudo journalctl -u tor@default -b. Там буде виведено помилку синтаксису torrc або проблему з правами доступу до каталогу. Також можна перевірити зміни в torrc перед їх застосуванням.

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

Чого це варте порівняно з тунелем WireGuard

Порівняно з WireGuard VPN на власному VPS, onion service працює повільніше й менш передбачувано. Перед початком роботи чесно оцініть цей компроміс.

Затримка. Клієнтський circuit складається з трьох relay, а сторона сервісу додає ще три, тому введені символи проходять приблизно через шість машин, випадково вибраних у різних країнах. Під час інтерактивного введення затримка помітна, а копіювання файлів повільне. WireGuard додає один hop. Виміряйте власний випадок за допомогою time ssh myvps 'echo ok', оскільки результат залежить від circuit, який tor побудував цього разу, і змінюється, коли tor будує інший circuit.

Userspace daemon у критичному ланцюжку. WireGuard працює в kernel і запускається разом із мережею. Tor — це процес, який має запуститися, виконати bootstrap і встановити з’єднання з guard relay, перш ніж щось запрацює. Якщо він не запускається, вам потрібен provider console.

Точність годинника. Onion service descriptors публікуються для певних періодів часу, тому суттєво неправильний час на системному годиннику порушує пошук адреси, і зрозумілого повідомлення про це може не бути ніде. timedatectl має повідомляти System clock synchronized: yes.

Натомість ви отримуєте захист, який більше не залежить від правильності правила firewall. Немає порту для сканування або банера для зчитування, а сама адреса є public key, тому endpoint підтверджує свою ідентичність ще до запуску SSH.

На практиці зазвичай використовують обидва варіанти. Запускайте WireGuard як основний щоденний канал, а onion service залиште як маршрут, що працює навіть тоді, коли конфігурація WireGuard неправильна. У такому разі відкритим залишається один UDP-порт, а не публічний SSH-порт. Це не скасовує потребу в зміцненні самого sshd: автентифікація лише за ключами та вхід не під root залишаються важливими, оскільки onion service захищає мережевий шлях і нічого за його межами.

Режими відмови та помилки, які ви побачите

Tor ніколи не проходить через Bootstrapped 0%. Вихідний трафік заблоковано або час на системі значно неправильний. Перевірте політику вихідного трафіку за допомогою sudo ufw status verbose, а потім виконайте timedatectl.

systemctl status tor повідомляє active (exited). У Debian і Ubuntu це нормально. Натомість перегляньте tor@default.

Дескриптор не знайдено. Tor повертає розширену помилку SOCKS F0: "Onion Service Descriptor Can Not be Found". Дескриптор ще може бути не опублікований, оскільки після перезавантаження це займає деякий час. Інша причина — tor на сервері не запущений.

F4, "Onion Service Missing Client Authorization". Клієнт не має відповідного .auth_private, який може використати tor. Переконайтеся, що ClientOnionAuthDir вказано в torrc, каталог має режим 0700, ім’я файлу закінчується на .auth_private, а debian-tor може прочитати цей файл.

F5, "Onion Service Wrong Client Authorization". Приватний ключ не відповідає файлу .auth на сервері. Це спричиняє кінцевий = або зайвий символ нового рядка всередині рядка base32.

nc: invalid option -- 'X'. Замість OpenBSD netcat встановлено GNU netcat. Виконайте sudo apt install -y netcat-openbsd.

Could not resolve hostname. ssh спробував виконати звичайний DNS-запит. Для .onion немає відповіді, тому ProxyCommand не було виконано. Шаблон Host у ~/.ssh/config не відповідає введеному вами імені.

Permission denied (publickey). Тунель працює, і tor завершив свою роботу. Розглядайте це як звичайну проблему permission denied із publickey і не залучайте tor до подальшої діагностики.

FAQ

Чи справді onion service означає, що на моєму VPS немає відкритих портів?

Так, якщо sshd прив’язаний до 127.0.0.1, а firewall відкидає вхідний трафік. Tor встановлює вихідне TCP-з’єднання з relay, і ваш сеанс проходить через нього у зворотному напрямку, тому жоден процес на сервері не приймає з’єднання на публічній адресі. Перевірте це за допомогою ss -tlnp на сервері та сканування портів з іншого вузла. Не забудьте про власний мережевий firewall провайдера в панелі керування. Це окремий засіб керування, не пов’язаний з ufw, і його також потрібно налаштувати на блокування вхідного трафіку.

Чи достатньо адреси .onion для захисту SSH?

Ні. Адреса має 56 символів, і її неможливо вгадати або отримати через перелік у системі каталогів, тому вона працює як секрет. Однак адреса може потрапити в історію shell і конфігураційні файли. Додайте авторизацію клієнта v3. У такому разі service descriptor шифрується вашим ключем клієнта, тому той, хто має лише адресу, отримує розширену помилку F4 і взагалі не досягає sshd.

Що станеться, якщо tor не запуститься після перезавантаження?

Ви повністю втратите доступ через SSH, оскільки onion address буде єдиним способом підключення. Саме тому консоль провайдера потрібно перевірити до закриття порту 22. Tor також потребує часу для bootstrap після запуску системи, тому адреса починає відповідати пізніше, ніж сервер відповідає на ping. Якщо вона взагалі не відповідає, увійдіть через консоль і перегляньте sudo journalctl -u tor@default -b. Там буде виведено помилку синтаксису torrc або проблему з правами доступу до /var/lib/tor/ssh.

Чи повільніший SSH через Tor за WireGuard?

Так, і суттєво. З’єднання з onion service проходить приблизно через шість relay, вибраних випадково, тоді як WireGuard використовує один зашифрований перехід безпосередньо до сервера. Під час введення команд виникають затримки, а передавання даних відбувається повільно. Поширений варіант — використовувати WireGuard для щоденної роботи, а onion service залишити як аварійний канал, який працює навіть у разі несправної конфігурації VPN.