Jak uruchomić stronę .onion na VPS z Ubuntu
Instrukcja konfiguracji usługi v3 onion przy użyciu Tor oraz Nginx na loopback. Dowiedz się, jak poprawnie zabezpieczyć serwer przed wyciekiem adresu IP i utratą anonimowości.
Co budujesz
Strona typu onion to zwykły serwer WWW, który odpowiada wyłącznie w sieci Tor. Zainstaluj tor, dodaj dwie linie do /etc/tor/torrc, odczytaj adres wygenerowany przez tor, a następnie powiąż nginx z 127.0.0.1, aby żadna usługa nie odpowiadała na publicznym adresie IP. Instalacja zajmuje dziesięć minut. Reszta tego przewodnika to lista potencjalnych wycieków danych, ponieważ typową przyczyną awarii strony onion jest konfiguracja, która bezpośrednio wskazuje na operatora.
Tor powstał jako "the onion router", a usługa onion to usługa dostępna wyłącznie za jego pośrednictwem. Adres w wersji 3 składa się z 56 znaków oraz .onion; znaki te stanowią klucz publiczny ed25519 usługi wraz z sumą kontrolną i bajtem wersji, zakodowane w base32. Adresy w wersji 2 (16 znaków) zostały usunięte z sieci w 2021 roku, więc każdy obecnie generowany adres jest w wersji v3. Adres jest kluczem, co niesie ze sobą dwie konsekwencje. Połączenie jest szyfrowane i uwierzytelniane end-to-end bez udziału urzędu certyfikacji, a utrata pliku klucza oznacza bezpowrotną utratę adresu.
Twój serwer nigdy nie akceptuje połączeń przychodzących. Tor wybiera kilka przekaźników jako punkty wprowadzenia (introduction points), przesyła podpisany deskryptor do serwerów katalogowych i spotyka każdego odwiedzającego na przekaźniku spotkań (rendezvous relay) wybranym przez użytkownika. Każde z tych połączeń jest wychodzące z Twojej maszyny. Nie ma portów do otwarcia ani rekordów DNS do opublikowania.
Instalacja tor z repozytorium Tor Project
Ubuntu dostarcza pakiet tor w repozytorium universe, jednak pozostaje on zbliżony do wersji aktualnej w momencie zamrożenia wydania. Oficjalne repozytorium Tor Project śledzi bieżące wydanie stabilne, co jest zalecane w przypadku oprogramowania decydującego o zachowaniu prywatności adresu IP.
sudo apt update
sudo apt install -y apt-transport-https gnupg wget
KEYURL=https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc
wget -qO- "$KEYURL" | gpg --dearmor | sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/nullWpis w repozytorium wykorzystuje format deb822, a Suites musi odpowiadać nazwie kodowej używanego systemu Ubuntu. Należy odczytać ją z /etc/os-release zamiast wpisywać ręcznie, ponieważ błędna nazwa kodowa spowoduje dodanie repozytorium, które zostanie poprawnie rozpoznane, lecz nie będzie zawierało pakietów dla danej wersji systemu.
. /etc/os-release
sudo tee /etc/apt/sources.list.d/tor.sources >/dev/null <<EOF
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: $VERSION_CODENAME
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpg
EOF
sudo apt update
sudo apt install -y tor deb.torproject.org-keyringPakiet deb.torproject.org-keyring zapewnia aktualność klucza podpisu, dzięki czemu rotacja kluczy nie spowoduje błędu apt update w przyszłości. Należy sprawdzić, czy tor uruchomił się i uzyskał połączenie z siecią:
tor --version
sudo journalctl -u tor@default -n 20Dziennik powinien kończyć się wpisem Bootstrapped 100% (done): Done. Jeśli tor zatrzymał się na etapie Bootstrapped 10%, oznacza to brak ścieżki wyjściowej; należy sprawdzić zaporę sieciową dostawcy oraz własne reguły ruchu wychodzącego: sudo ufw status verbose powinno wskazywać allow (outgoing) jako bramę domyślną.
Od tego momentu istotne są dwie nazwy. Pakiet uruchamia tor jako użytkownik debian-tor, a działająca jednostka to tor@default.service, ponieważ tor.service w systemach Debian i Ubuntu stanowi jedynie wrapper dla instancji. Status i logi należy sprawdzać dla nazwy instancji, aby uzyskać informacje o właściwym procesie.
Konfiguracja usługi onion w torrc
Dopisz dwie linie do /etc/tor/torrc:
HiddenServiceDir /var/lib/tor/onion_site/
HiddenServicePort 80 127.0.0.1:8080HiddenServiceDir to lokalizacja, w której tor przechowuje klucze oraz adres dla tej usługi. Nie należy tworzyć tego katalogu samodzielnie. Tor tworzy go przy starcie z odpowiednim właścicielem i uprawnieniami; katalog utworzony przez użytkownika root spowoduje pierwszy błąd z poniższej listy.
HiddenServicePort składa się z dwóch części, a ich pomylenie jest najczęstszym błędem początkujących. Pierwsza liczba to port, z którym łączy się użytkownik wewnątrz tunelu, dlatego 80 jest wartością oczekiwaną i nie ma powodu, aby ją zmieniać. Druga część to adres lokalny, na który tor przekazuje ruch. Zapis HiddenServicePort 80 przekazuje ruch na 127.0.0.1:80, dlatego jawne podanie adresu i użycie wysokiego portu pozwala odizolować vhost onion od usług nasłuchujących na porcie 80.
sudo systemctl restart tor@default
sudo ls -l /var/lib/tor/onion_site/Wylistowanie powinno zawierać hostname, hs_ed25519_public_key, hs_ed25519_secret_key oraz pusty katalog authorized_clients.
Odczyt adresu .onion
sudo cat /var/lib/tor/onion_site/hostnameZwrócony zostanie jeden wiersz: 56 znaków w formacie base32 oraz .onion. Ten ciąg znaków stanowi pełną tożsamość witryny. Nikt go nie przydziela, nikt nie może go przenieść i nikt nie może go odebrać, dopóki użytkownik posiada plik klucza. Należy go teraz skopiować, ponieważ każda poniższa konfiguracja wymaga jego użycia. W dalszej części tego przewodnika ciąg ten oznaczono jako <your-address>.onion.
Udostępnianie witryny przez nginx powiązany z 127.0.0.1
sudo apt install -y nginx
sudo install -d -m 755 /srv/onionWpisz /etc/nginx/sites-available/onion:
server {
listen 127.0.0.1:8080;
server_name <your-address>.onion;
root /srv/onion;
index index.html;
server_tokens off;
etag off;
access_log off;
error_log /var/log/nginx/onion.error.log error;
}echo '<h1>hello from the onion</h1>' | sudo tee /srv/onion/index.html
sudo ln -s /etc/nginx/sites-available/onion /etc/nginx/sites-enabled/onion
sudo nginx -t
sudo systemctl reload nginxTeraz należy zweryfikować dwie kwestie z poziomu serwera. Pierwszą jest to, czy nginx odpowiada na nazwę onion, która jest dokładnym nagłówkiem Host wysyłanym przez tor:
curl -s -H 'Host: <your-address>.onion' http://127.0.0.1:8080/Drugą jest to, czy odpowiada on tylko w tym miejscu i nigdzie indziej:
sudo ss -tlnp | grep 8080Kolumna adresu musi wskazywać 127.0.0.1:8080. Jeśli wskazuje 0.0.0.0:8080 lub *:8080, witryna onion jest również dostępna w publicznym Internecie, co stanowi pierwszy punkt na liście wycieków. Linia listen 8080; bez adresu oznacza powiązanie ze wszystkimi interfejsami, co jest ustawieniem domyślnym.
Otwórz adres w Tor Browser. Pierwsze ładowanie zajmuje kilka sekund, podczas których klient pobiera deskryptor i buduje obwód rendezvous.
Dokumentacja The Tor Project preferuje gniazdo unix zamiast portu loopback: HiddenServicePort 80 unix:/var/run/tor/onion_site.sock, przy czym nginx nasłuchuje na tej ścieżce. Gniazda nie można osiągnąć z innego hosta, nawet jeśli serwer zyska w przyszłości drugi interfejs. Kosztem są uprawnienia do plików, ponieważ nginx tworzy gniazdo, a tor łączy się z nim jako debian-tor, więc obaj użytkownicy muszą mieć dostęp do tego samego katalogu. Loopback ze zweryfikowanym wyjściem ss jest łatwiejszy w poprawnej konfiguracji i to rozwiązanie jest zakładane w dalszej części tego przewodnika.
Przy witrynie działającej na loopback, serwer nie wymaga żadnych reguł przychodzących dla tej usługi. Pozostaw otwarty port 22 dla siebie i zablokuj resztę (domyślne ustawienia ufw warte zastosowania na VPS). Pamiętaj, że zapora sieciowa nie unieważnia usługi powiązanej z 0.0.0.0, a jedynie filtruje pakiety docierające do zapory. Kontenery zaostrzają ten problem, ponieważ publikowanie portu Docker zapisuje reguły iptables przed ufw, więc -p 8080:80 wystawia backend onion na publiczny adres IP, podczas gdy ufw nadal raportuje port jako zablokowany. Publikuj porty kontenerów jako -p 127.0.0.1:8080:80.
Wycieki prowadzące do deanonimizacji strony onion
Tor ukrywa lokalizację serwera. Żaden element sieci Tor nie ukrywa treści przesyłanych przez serwer. Każdy z poniższych punktów opisuje dane, które publikuje Twój stos technologiczny.
Ta sama witryna odpowiadająca na publicznym adresie IP
To najczęstsza przyczyna wpadek. Skanery nieustannie indeksują odpowiedzi HTTP każdego routowalnego adresu, a wyniki te są publiczne i przeszukiwalne. Serwowanie tej samej strony na publicznym adresie IP oraz pod adresem onion pozwala na ich powiązanie za pomocą jednego zapytania: ten sam tytuł, ten sam skrót favicon, ten sam ETag, ta sama kolejność nagłówków. Linia listen 127.0.0.1:8080; powyżej stanowi rozwiązanie. Zweryfikuj to z innej maszyny, nie z poziomu samego serwera:
curl -sv --max-time 5 http://<your-public-ip>:8080/Connection refused lub przekroczenie czasu oczekiwania to prawidłowy wynik. Jakakolwiek treść HTML oznacza, że witryna jest publiczna. Jeśli na tej samej maszynie działa również witryna w sieci clearnet, przypisz jej vhostowi osobny katalog główny i zachowaj jawny blok default_server w publicznym listenerze, aby niedopasowany nagłówek Host nigdy nie trafił do vhosta onion.
Banery wersji
curl -sI http://127.0.0.1:8080/ | grep -i '^server'Domyślna konfiguracja nginx odpowiada Server: nginx/1.24.0. Ten ciąg wersji, wraz z dokładną kolejnością pozostałych nagłówków, stanowi odcisk palca, który pozwala powiązać Twój adres onion z hostem w sieci clearnet. server_tokens off; redukuje go do Server: nginx. Nie usuwa to nagłówka, a nginx nie posiada wbudowanej dyrektywy do tego celu, więc moduł headers-more jest standardowym rozwiązaniem, jeśli chcesz się go pozbyć. PHP dodaje X-Powered-By, dopóki nie ustawisz expose_php = Off. etag off; należy do tej samej kategorii, ponieważ nginx generuje ETag na podstawie czasu modyfikacji i rozmiaru pliku, więc te same pliki skopiowane na dwa serwery będą zwracać ten sam ETag na obu.
Bezwzględne adresy URL wskazujące na domenę clearnet
Znacznik rel="canonical", Open Graph og:url, kanał RSS, mapa witryny, e-mail z resetem hasła, zakodowany na sztywno adres URL logo. Każdy z nich wskazuje na witrynę clearnet wewnątrz strony serwowanej przez onion. Używaj ścieżek relatywnych względem katalogu głównego, takich jak /static/logo.svg, i pozwól aplikacji odczytywać bazowy adres URL z hosta żądania zamiast używać stałej. Przekierowania to ten sam błąd w innym miejscu: return 301 https://example.com$request_uri; w bloku catch-all wysyła odwiedzającego onion do Twojej właściwej domeny, a nagłówek Location dostarcza im odpowiedź bezpośrednio.
Certyfikat TLS współdzielony z witryną clearnet
Adres onion uwierzytelnia się sam, ponieważ jest kluczem publicznym, więc http:// przez połączenie onion jest już szyfrowane end-to-end, a Tor Browser traktuje je jako bezpieczny kontekst. Instalacja istniejącego certyfikatu na vhoście onion publikuje powiązanie między nimi, ponieważ każdy publicznie zaufany certyfikat jest rejestrowany w logach Certificate Transparency, a logi te są publiczne, trwałe i przeszukiwalne według nazwy. Zachowaj certyfikaty Let's Encrypt na vhoście clearnet, a vhost onion pozostaw na zwykłym HTTP.
Zewnętrzne czcionki i analityka
Czcionka z sieci CDN (content delivery network) lub skrypt analityczny. Przeglądarka odwiedzającego pobiera każdy z nich bezpośrednio, więc podmiot trzeci dowiaduje się, że ktoś załadował Twoją stronę i zazwyczaj którą konkretnie, a bardziej rygorystyczne poziomy bezpieczeństwa Tor Browser i tak blokują takie żądania, co prowadzi do błędnego wyświetlania układu strony. Hostuj samodzielnie każdy zasób wymagany przez stronę.
Niedopasowanie nagłówka Host
Jeśli server_name nie pasuje do nagłówka Host wysyłanego przez tor, nginx wraca do domyślnego serwera dla danego adresu nasłuchiwania. Na maszynie z jednym vhostem jest to niewidoczne, ponieważ jedyny blok serwera jest jednocześnie domyślnym. Dodaj vhost clearnet w późniejszym czasie, a żądania onion mogą zacząć trafiać na niego, wraz z jego kanonicznymi tagami i przekierowaniami. Uruchom ponownie test curl -H 'Host: ...' po każdej zmianie w nginx i przefiltruj wynik pod kątem swojej właściwej domeny:
curl -s -H 'Host: <your-address>.onion' http://127.0.0.1:8080/ | grep -o 'https\?://[^"]*' | sort -uWiedza o tym, który proces posiada dane gniazdo, stanowi większość tej pracy (jak działają porty i gniazda nasłuchujące w systemie Linux).
Co pozostaje w logach
Każde żądanie dociera z 127.0.0.1, więc nginx nie ma adresu odwiedzającego do zapisania, a access_log off; nic Cię nie kosztuje. Aplikacja działająca powyżej to inna kwestia, ponieważ zamówienie, adres e-mail czy metadane przesłanego pliku należą do Twojego zakresu odpowiedzialności. Twoje własne nawyki również mają znaczenie: administrowanie maszyną przez niezabezpieczony login wykracza poza ochronę sieci Tor, więc traktuj utwardzanie SSH na tym samym VPS jako część tej konfiguracji.
Utwórz kopię zapasową klucza prywatnego, ponieważ stanowi on adres
/var/lib/tor/onion_site/hs_ed25519_secret_key jest usługą. Nie istnieje żaden rejestrator ani mechanizm odzyskiwania. Utrata klucza oznacza utratę adresu. Kopia klucza pozwala każdej osobie posiadającej ten plik na serwowanie własnych treści pod Twoim adresem, bez możliwości unieważnienia dostępu.
sudo systemctl stop tor@default
sudo tar -C /var/lib/tor -czf onion-keys.tgz onion_site
sudo chmod 600 onion-keys.tgz
sudo systemctl start tor@defaultZaszyfruj to archiwum (gpg -c onion-keys.tgz) i przenieś je poza serwer. Przywrócenie usługi na nowym VPS wymaga archiwum oraz nadania uprawnień, których oczekuje tor:
sudo systemctl stop tor@default
sudo tar -C /var/lib/tor -xzf onion-keys.tgz
sudo chown -R debian-tor:debian-tor /var/lib/tor/onion_site
sudo chmod 700 /var/lib/tor/onion_site
sudo systemctl start tor@default
sudo cat /var/lib/tor/onion_site/hostnameTen sam adres powróci na nowym sprzęcie w ciągu minuty lub dwóch, gdy tor ponownie opublikuje deskryptor. To cała procedura migracji: bez zmian w DNS i bez konieczności ponownego wydawania certyfikatów.
Onion-Location, gdy witryna działa również w sieci publicznej
Jeśli usługa onion stanowi udogodnienie, a nie sposób na zachowanie poufności, należy ją reklamować z poziomu vhosta w sieci publicznej:
add_header Onion-Location http://<your-address>.onion$request_uri;Tor Browser wyświetla wówczas przycisk .onion available na pasku adresu i oferuje przełączenie. Nagłówek jest uwzględniany tylko wtedy, gdy strona w sieci publicznej jest serwowana przez HTTPS, a wartość stanowi poprawny adres URL onion.
Występuje tu problem z jedną regułą nginx. Dyrektywy add_header są dziedziczone przez blok location tylko wtedy, gdy blok ten nie deklaruje własnych dyrektyw tego typu. W rezultacie blok location posiadający własne add_header powoduje ciche pominięcie Onion-Location. Należy powtórzyć dyrektywę w tym bloku lub przechowywać wszystkie nagłówki odpowiedzi w jednym miejscu. Publikacja tego nagłówka celowo łączy obie witryny, co jest poprawne w przypadku lustrzanej kopii, lecz niewłaściwe dla usług, które mają pozostać niepowiązane.
Adresy typu vanity
mkp224o generuje pary kluczy do momentu uzyskania adresu rozpoczynającego się od wskazanego prefiksu. Jest to wyszukiwanie metodą brute force, więc poza określeniem prefiksu i czasem oczekiwania nie ma żadnych dodatkowych opcji konfiguracji.
sudo apt install -y git gcc libc6-dev libsodium-dev make autoconf
git clone https://github.com/cathugger/mkp224o
cd mkp224o
./autogen.sh
./configure --enable-amd64-51-30k
make
./mkp224o -d onionkeys blogKażde trafienie zapisywane jest w onionkeys/<address>.onion/, zawierającym hostname oraz hs_ed25519_secret_key. Aby zainstalować taki adres, należy zatrzymać tor, skopiować ten katalog w miejsce swojego HiddenServiceDir, a następnie nadać takie same chown i chmod 700, jak w przypadku przywracania opisanego powyżej.
Długość prefiksu determinuje koszt operacji. Adres jest zapisany w formacie base32, więc każdy kolejny wymagany znak zwiększa oczekiwaną liczbę generowanych kluczy 32-krotnie. Krótki prefiks można wygenerować na laptopie. Długi prefiks jest niemożliwy do uzyskania na posiadanym sprzęcie. Używanie prefiksów typu vanity uczy również użytkowników rozpoznawania tylko pierwszych kilku znaków zamiast całego adresu, co jest nawykiem wykorzystywanym przez phishingowe kopie stron onion.
Tryby awarii i towarzyszące im komunikaty
Brak pliku hostname po restarcie. Tor nie uruchomił się lub odmówił dostępu do katalogu. sudo journalctl -u tor@default -n 50 wskazuje przyczynę:
/var/lib/tor/onion_site/ is not owned by this user (debian-tor, 108) but by root (0). Perhaps you are running Tor as the wrong user?Tak wygląda katalog utworzony ręcznie. Należy poprawić właściciela i uprawnienia (mode) lub usunąć katalog i pozwolić, aby tor utworzył go samodzielnie.
Tor Browser wyświetla Onionsite Not Found (0xF0). Klient nie mógł pobrać deskryptora, co oznacza, że z punktu widzenia sieci pod tym adresem nic nie jest opublikowane. Należy potwierdzić, że tor działa i zakończył proces bootstrap, porównać wpisany adres z sudo cat /var/lib/tor/onion_site/hostname znak po znaku, a następnie sprawdzić czas systemowy. Tor wymaga dokładnego czasu do publikacji i walidacji deskryptorów, a timedatectl powinno zwracać System clock synchronized: yes.
Adres jest rozpoznawany, ale strona się nie ładuje. Tor zakończył proces rendezvous, ale połączenie nie powiodło się na ostatnim etapie, między tor a nginx. Ponieważ jest to połączenie lokalne, dziennik tor nie wykazuje błędów. Należy uruchomić curl -sI http://127.0.0.1:8080/ na serwerze. Connection refused oznacza, że nginx nie działa lub nasłuchuje na innym adresie, niż wskazuje HiddenServicePort.
Strona ładuje się, ale wszystkie linki prowadzą do właściwej domeny. Przyczyną są bezwzględne adresy URL w szablonach. Należy uruchomić sprawdzenie grep -o 'https\?://[^"]*' i poprawić wskazane elementy przed udostępnieniem adresu.
Usługa działa, ale przestaje po restarcie systemu. Przed rozpoczęciem korzystania z witryny należy celowo zrestartować serwer, a następnie uruchomić sudo systemctl status tor@default oraz sudo systemctl status nginx. Usługa uruchomiona ręcznie wygląda identycznie jak ta włączona w systemd, dopóki maszyna nie zostanie zrestartowana.
FAQ
Czy muszę otwierać port w zaporze sieciowej dla usługi onion w sieci Tor?
Nie. Demon tor nawiązuje wyłącznie połączenia wychodzące do serwerów katalogowych, punktów wprowadzenia (introduction points) oraz przekaźników rendezvous, dlatego nie jest wymagana żadna reguła przychodząca, a sam serwer WWW nasłuchuje na 127.0.0.1. Należy utrzymać domyślną politykę deny dla ruchu przychodzącego w ufw, zezwalając jedynie na SSH. Ta sama właściwość sprawia, że usługa onion działa na maszynie znajdującej się za NAT (network address translation), nawet jeśli nie posiada ona publicznego adresu IP.
Dlaczego nie mogę uzyskać dostępu do mojego adresu .onion w Tor Browser?
Należy przeprowadzić diagnostykę, zaczynając od serwera. sudo journalctl -u tor@default -n 50 powinno wskazywać Bootstrapped 100% (done): Done, następnie curl -sI http://127.0.0.1:8080/ na serwerze powinno zwrócić linię statusu, a na koniec należy porównać wpisany adres z zawartością pliku hostname, ponieważ jeden błędny znak oznacza zupełnie inną usługę. Onionsite Not Found (0xF0) oznacza, że nie znaleziono deskryptora dla danego adresu, co zazwyczaj świadczy o tym, że tor nie jest uruchomiony lub zegar systemowy wskazuje błędny czas.
Czy mogę przenieść witrynę onion na nowy serwer i zachować ten sam adres?
Tak. Adres jest wywodzony z hs_ed25519_secret_key, więc należy skopiować cały katalog HiddenServiceDir na nową maszynę, ustawić właściciela na debian-tor oraz uprawnienia na 700, a następnie uruchomić tor. Adres stanie się aktywny, gdy deskryptor zostanie ponownie opublikowany; nie ma potrzeby aktualizacji żadnych rekordów DNS. Utrata tego pliku oznacza nieodwracalną utratę adresu, dlatego należy wykonać jego zaszyfrowaną kopię zapasową poza serwerem w dniu utworzenia usługi.
Czy witryna onion wymaga certyfikatu HTTPS?
Nie. 56-znakowy adres jest kluczem publicznym usługi, więc połączenie jest już szyfrowane i uwierzytelniane typu end-to-end, a Tor Browser traktuje http:// w domenie .onion jako bezpieczny kontekst. Ponowne użycie certyfikatu z sieci publicznej (clearnet) dla vhosta onion jest niezalecane, ponieważ logi Certificate Transparency są publiczne i trwale rejestrują, które nazwy współdzielą certyfikat. Jedynym powodem zakupu certyfikatu dla nazwy .onion jest chęć uzyskania potwierdzenia wiarygodności od urzędu certyfikacji (CA), jednak takie powiązanie jest z założenia publiczne.