Jak dodać nagłówek Onion-Location w nginx
Skonfiguruj nagłówek Onion-Location w nginx, aby Tor Browser automatycznie wykrywał adresy onion. Dowiedz się, jak uniknąć wycieków danych przez przekierowania i zasoby zewnętrzne.
Działanie nagłówka Onion-Location
Nagłówek Onion-Location to pojedyncza linia w konfiguracji vhosta w sieci publicznej, która informuje przeglądarkę Tor Browser o istnieniu adresu onion. Użytkownik odwiedzający https://example.com przez sieć Tor zobaczy w pasku adresu fioletowy przycisk z napisem .onion available. Jedno kliknięcie przeniesie go do usługi onion. Jest to wyłącznie mechanizm wykrywania. Nagłówek nie tworzy usługi onion i nie zapewnia anonimowości.
Niniejszy przewodnik zakłada, że obie części są już gotowe. Posiadasz witrynę na serwerze VPS z zainstalowanym nginx oraz działającą usługę onion w wersji v3, która jest do niej skierowana. Jeśli nie posiadasz jeszcze drugiej części, skonfiguruj ją w pierwszej kolejności: hosting witryny onion na VPS zawiera opis linii w pliku torrc oraz pliku hostname. Poniższa treść dotyczy połączenia obu elementów bez ujawniania informacji między nimi.
Wymagania Tor Browser przed uwzględnieniem nagłówka
Tor Project definiuje trzy warunki. Wszystkie muszą zostać spełnione, aby przycisk (pill) się pojawił.
- Wartość
Onion-Locationmusi być poprawnym adresem URL ze schematemhttp:lubhttps:oraz nazwą hosta.onion. - Strona internetowa definiująca nagłówek musi być serwowana przez HTTPS.
- Strona internetowa definiująca nagłówek nie może być sama w sobie witryną onion.
Drugi warunek jest najczęstszą przyczyną problemów, a trzeci wyjaśnia, dlaczego nie należy ustawiać tego nagłówka na vhostach onion. Istnieje czwarta zasada, która nie została ujęta w dokumentacji opisowej, ale wynika z implementacji: Tor Browser reaguje na nagłówek tylko w przypadku dokumentu najwyższego poziomu. Kod porównuje cel ładowania z dokumentem przed podjęciem jakichkolwiek działań, dlatego nagłówek zwrócony w arkuszu stylów, obrazie lub odpowiedzi API jest ignorowany.
Domyślnie przeglądarka wyświetla przycisk i oczekuje na kliknięcie. Użytkownik, który chce automatycznego przekierowania, może włączyć tę opcję w Ustawieniach, następnie w sekcji Prywatność i bezpieczeństwo, a potem w Usługi Onion, gdzie opcję "Priorytetyzuj strony .onion, gdy są znane" można ustawić na "Zawsze". Nie można wymusić tego zachowania po stronie serwera. Nagłówek należy traktować jako ofertę, a nie jako przekierowanie.
Dodawanie nagłówka Onion-Location w nginx
Nagłówek ten należy umieścić w bloku server, który kończy połączenie TLS dla domeny w sieci publicznej. Umieszczenie go w bloku portu 80 nie przyniesie efektu, ponieważ blok ten jedynie wykonuje przekierowanie, a druga zasada wyklucza nagłówek zdefiniowany na stronie przesyłanej przez zwykłe HTTP.
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
add_header Onion-Location http://<your-onion-address>.onion$request_uri always;
root /srv/example.com/public;
}$request_uri przenosi ścieżkę oraz ciąg zapytania, dzięki czemu czytelnik na https://example.com/guides/tor otrzymuje ofertę przejścia do tej samej ścieżki w sieci onion. Bez tego parametru każdy odwiedzający trafi na stronę główną onion zamiast na stronę, którą aktualnie czytał.
always ma znaczenie ze względu na udokumentowane ograniczenie w nginx. add_header dodaje pole tylko wtedy, gdy kod odpowiedzi to 200, 201, 204, 206, 301, 302, 303, 304, 307 lub 308. Strona 404 jest realnym punktem wejścia z wyników wyszukiwania, a bez always nie zawiera ona żadnego nagłówka.
Drugą pułapką w nginx jest dziedziczenie, które przebiega bez zgłaszania błędów. Dyrektywy add_header są dziedziczone z poprzedniego poziomu konfiguracji tylko wtedy, gdy na bieżącym poziomie nie występują żadne dyrektywy add_header. Zatem blok location /assets/ { add_header Cache-Control ...; } odrzuca zdefiniowany na poziomie serwera Onion-Location dla każdego adresu URL w jego obrębie. Jeśli nagłówki są ustawiane indywidualnie dla lokalizacji, należy powtórzyć linię Onion-Location wewnątrz każdego z tych bloków. Warto przeczytać Jak nginx wybiera blok server i location, jeśli to zachowanie jest nowe.
Przeładuj konfigurację i sprawdź zarówno zwykłą stronę, jak i stronę nieistniejącą:
sudo nginx -t && sudo systemctl reload nginx
curl -sI https://example.com/ | grep -i onion-location
curl -sI https://example.com/no-such-page | grep -i onion-locationOba polecenia powinny wyświetlić linię onion-location:. Drugie polecenie jest dowodem na to, że always działa poprawnie. Brak danych wyjściowych z drugiego polecenia oznacza, że flaga jest nieobecna lub blok location przesłania dyrektywę.
Znacznik meta HTML w przypadku braku możliwości ustawienia nagłówków
Statyczne hosty oraz niektóre panele CDN nie pozwalają na dodanie dowolnego nagłówka odpowiedzi. Ta sama wartość działa jako element meta w sekcji head dokumentu, ponieważ przeglądarka odczytuje ją poprzez te same dane nagłówka dokumentu, niezależnie od tego, czy dotarły one przez HTTP, czy jako znacznik http-equiv.
<meta http-equiv="onion-location" content="http://<your-onion-address>.onion" />Nadal obowiązują trzy wymagania. Strona zawierająca znacznik musi korzystać z HTTPS i nie może być adresem onion. Różnica polega na tym, że znacznik zawiera jeden stały adres bez ścieżki, ponieważ nie ma zmiennej po stronie serwera, którą można by rozwinąć. Każda strona, która go zawiera, oferuje stronę główną onion. Jest to koszt rozwiązania zastępczego, dlatego należy preferować nagłówek zawsze, gdy istnieje kontrola nad serwerem.
Serwowanie strony onion z osobnego vhosta nginx
Strona w sieci publicznej oraz usługa onion nie mogą współdzielić bloku serwera. Tor Browser wysyła Host: <your-onion-address>.onion. Jeśli żaden blok serwera nie obsługuje tej nazwy, nginx używa domyślnego serwera, którym jest vhost dla sieci publicznej, a każdy wygenerowany przez niego adres URL wskazuje na domenę publiczną.
Skieruj usługę ukrytą na port, który odpowiada wyłącznie na interfejsie loopback:
HiddenServiceDir /var/lib/tor/onion_site/
HiddenServicePort 80 127.0.0.1:8080Następnie przypisz temu portowi osobny vhost:
server {
listen 127.0.0.1:8080;
server_name <your-onion-address>.onion;
absolute_redirect off;
port_in_redirect off;
root /srv/example.com/public;
}listen 127.0.0.1:8080 sprawia, że ten vhost nie jest dostępny pod publicznym adresem IP, dzięki czemu skanowanie adresu VPS nie pozwala na pobranie zawartości i porównanie jej bajt po bajcie z kopią w sieci publicznej. absolute_redirect off powoduje, że nginx generuje relatywne wartości Location, dzięki czemu przekierowanie z końcowym ukośnikiem w katalogu zwraca Location: /guides/, a nie pełny adres URL. nginx domyślnie tworzy bezwzględne przekierowania na podstawie nagłówka Host, a nie server_name, ponieważ server_name_in_redirect ma domyślnie ustawione off, jednak użycie przekierowania relatywnego całkowicie eliminuje ten problem.
Dlaczego strona onion nadal przekierowuje odwiedzających do witryny w sieci clearnet?
Nginx rzadko jest przyczyną wycieku. Odpowiada za to aplikacja. Każdy mechanizm budujący bezwzględny adres URL na podstawie skonfigurowanego adresu witryny wskaże domenę clearnet, niezależnie od tego, który vhost obsłużył żądanie.
- Znacznik
rel="canonical"wskazujący nahttps://example.com/.... Jest to najczęstsza przyczyna; ujawnia dokładny adres strony w sieci clearnet każdemu, kto przejrzy kod źródłowy. - Przekierowania generowane przez framework zamiast przez nginx, takie jak
SECURE_SSL_REDIRECTw Django czy opcjehomeisiteurlw WordPress. og:urloraz inne meta tagi kart społecznościowych.- Wpisy w mapach witryn (sitemap) i kanałach RSS, które zgodnie ze specyfikacją muszą zawierać adresy bezwzględne.
- Strony błędów aplikacji, które zazwyczaj zawierają odnośnik „powrót do strony głównej” zbudowany na podstawie tego samego ustawienia.
Rozwiązanie zależy od użytego stosu technologicznego i nie istnieje jedna uniwersalna metoda. Metoda weryfikacji jest jednak uniwersalna. Pobierz stronę onion przez Tor i przeszukaj odpowiedź pod kątem wystąpienia domeny.
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/ \
| grep -i 'example\.com'--socks5-hostname wysyła nazwę do portu SOCKS usługi tor w celu rozwiązania adresu, co jest wymagane, ponieważ żaden proces w systemie nie potrafi lokalnie rozwiązać nazwy .onion. Port 9050 jest domyślnym portem dla zainstalowanego demona tor. Brak wyniku oznacza poprawną konfigurację. Każde trafienie wskazuje na stronę, która przekazuje domenę clearnet każdemu odwiedzającemu przez sieć Tor. Uruchom test dla strony głównej, a następnie dla adresu URL generującego błąd 404.
Łańcuch przekierowań należy sprawdzić oddzielnie, ponieważ treść odpowiedzi przy przekierowaniu jest zazwyczaj pusta:
curl -sI --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/guides \
| grep -i '^location'Wartość Location wskazująca na example.com oznacza, że przekierowanie wypycha odwiedzającego z sieci onion z powrotem do sieci clearnet przez węzeł wyjściowy, mimo że żądanie miało pozostać wewnątrz sieci Tor.
Nie należy prezentować certyfikatu z sieci publicznej w usłudze onion
Adres onion w wersji v3 jest generowany na podstawie klucza publicznego usługi, dzięki czemu sieć Tor uwierzytelnia i szyfruje połączenie z konkretną usługą, zanim zostanie wysłane jakiekolwiek żądanie HTTP. Zwykły protokół HTTP wewnątrz usługi onion jest standardową konfiguracją i nie należy go utożsamiać z przesyłaniem danych przez HTTP w otwartym Internecie.
Jeśli wirtualny host dla usługi onion zostanie utworzony przez skopiowanie konfiguracji z sieci publicznej, przeniesiona zostanie również dyrektywa ssl_certificate. W rezultacie usługa onion prezentuje certyfikat, którego lista alternatywnych nazw podmiotu example.com nie zawiera adresu .onion. Prowadzi to do dwóch problemów. Przeglądarka zgłasza niezgodność nazwy, ponieważ adres URL jest adresem onion, a certyfikat go nie obejmuje. Ponadto każdy użytkownik, który zaakceptuje wyjątek, otrzymuje podpisane potwierdzenie, że obie witryny znajdują się na tej samej maszynie. Należy przechowywać konfigurację wirtualnego hosta onion w osobnym pliku z własną dyrektywą server_name. Pozwala to również uniknąć konfliktów z wtyczką Certbot nginx plugin, ponieważ wtyczka ta automatycznie modyfikuje blok serwera odpowiadający domenie, dla której generowany jest certyfikat.
Wybór pakietu tor oraz bezpieczeństwo klucza usługi
Pakiet tor w archiwum Ubuntu jest odpowiedni do tego celu i nie wymaga dodatkowej konfiguracji. Jest on jednak opóźniony względem bieżącej stabilnej serii, więc w przypadku usługi planowanej do długotrwałego działania należy użyć oficjalnego repozytorium Debian projektu Tor i pozwolić apt na aktualizację wraz z resztą systemu. Według stanu na sierpień 2026 udokumentowane kroki są następujące:
sudo apt install apt-transport-https
wget -qO- https://deb.torproject.org/torproject.org/A3C4F0F979CAA22CDBA8F512EE8CBC9E886DDD89.asc \
| gpg --dearmor \
| sudo tee /usr/share/keyrings/deb.torproject.org-keyring.gpg >/dev/nullUtwórz /etc/apt/sources.list.d/tor.sources, zastępując nazwę dystrybucji (suite) nazwą kodową wydania z lsb_release -c:
Types: deb deb-src
URIs: https://deb.torproject.org/torproject.org/
Suites: noble
Components: main
Signed-By: /usr/share/keyrings/deb.torproject.org-keyring.gpgsudo apt update
sudo apt install tor deb.torproject.org-keyringPakiet deb.torproject.org-keyring utrzymuje klucz podpisu w aktualnym stanie, dzięki czemu repozytorium nie przestanie przechodzić weryfikacji za rok. Należy wybrać jedno źródło i pozostać przy nim. Pakiet z archiwum oraz pakiet z repozytorium mają różne wersje, a apt będzie przełączać między nimi podczas aktualizacji, jeśli oba źródła są włączone.
Katalog HiddenServiceDir przechowuje tożsamość usługi. Plik hs_ed25519_secret_key w tym katalogu jest adresem onion, ponieważ adres ten stanowi publiczną część pary kluczy. Utrata pliku oznacza bezpowrotną utratę adresu, gdyż nie istnieje organ, który mógłby go ponownie wydać. Skopiowanie pliku w nieodpowiednie miejsce sprawia, że każdy posiadacz kopii może uruchomić usługę onion.
tor odmawia korzystania z katalogu, który może być odczytany przez innych użytkowników. Przed sprawdzeniem czegokolwiek innego należy zweryfikować uprawnienia i właściciela:
sudo ls -ld /var/lib/tor/onion_site
sudo -u debian-tor cat /var/lib/tor/onion_site/hostnameLista powinna wskazywać drwx------ z właścicielem i grupą debian-tor w systemach Debian i Ubuntu. Jeśli uprawnienia są szersze, tor zapisze w dzienniku linię typu Permissions on directory /var/lib/tor/onion_site/ are too permissive., a usługa nie zostanie uruchomiona. Należy naprawić to za pomocą sudo chown -R debian-tor:debian-tor /var/lib/tor/onion_site, a następnie sudo chmod 700 /var/lib/tor/onion_site, zrestartować usługę poleceniem sudo systemctl restart tor i odczytać wynik za pomocą sudo journalctl -u tor@default -n 30.
Katalog ten należy archiwizować w sposób właściwy dla klucza prywatnego: poza serwerem i w formie zaszyfrowanej. Nigdy nie należy umieszczać go w repozytorium, w którym znajduje się kod strony. Jeśli ten sam serwer wymaga również dostępu administracyjnego przez Tor, uzyskanie dostępu SSH przez usługę onion stanowi czystsze rozwiązanie niż wystawianie ścieżki zarządzania w publicznej witrynie.
Analityka i zasoby stron trzecich wyciekają więcej niż nagłówek
To jest najważniejsza część i nie ma ona związku z Onion-Location. Każdy zasób strony trzeciej, do którego odwołuje się witryna, to żądanie, które przeglądarka użytkownika wysyła poza sieć onion, z powrotem do publicznej sieci (clearnet) przez węzeł wyjściowy. Czcionka z publicznego CDN, hostowany skrypt analityczny, osadzony odtwarzacz wideo, widżet komentarzy: każdy z nich informuje podmiot zewnętrzny, że ktoś ładuje stronę w ramach sesji, którą czytelnik celowo skierował przez Tor.
Pociąga to za sobą dwie konsekwencje. Podmiot zewnętrzny dowiaduje się o wizycie. Ponieważ kopia strony w publicznej sieci ładuje te same zasoby od tych samych dostawców, każdy, kto ma wgląd w obie strony, może bez wysiłku powiązać obie te właściwości.
Serwuj wszystko z tego samego źródła. Hostuj czcionki samodzielnie. Usuń tagi zewnętrznej analityki lub przenieś je na własny serwer, gdzie samodzielnie hostowana analityka na VPS utrzymuje żądanie wewnątrz sieci onion. Należy oczekiwać, że domyślne ustawienia Tor Browser zablokują lub ograniczą większość danych, które narzędzia analityczne próbują zebrać, co jest pożądanym rezultatem. Jeśli strona nie może funkcjonować bez skryptu strony trzeciej, nie publikuj jej w sieci onion.
Wylistuj zasoby, które faktycznie pobiera strona:
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/ \
| grep -oE '(src|href)="https?://[^"]+"' | sort -uKażda linia wyświetlona przez to polecenie to bezwzględny adres URL, który strona nakazuje pobrać przeglądarce. Wszystko, co nie jest Twoim adresem onion, to wychodzące żądanie do publicznej sieci, które zmuszasz czytelników do wykonania w Twoim imieniu.
Model zagrożeń w prostych słowach
Onion-Location ułatwia odnalezienie usługi onion i tylko do tego służy. Nie zapewnia anonimowości operatorowi, ponieważ domena w sieci publicznej nadal posiada wpisy u rejestratora, rekordy DNS, certyfikat opublikowany w logach Certificate Transparency oraz powiązane konto VPS z danymi rozliczeniowymi. Nie zapewnia również anonimowości samej usłudze onion, ponieważ z poziomu domeny publicznej opublikowano trwałe, jawne powiązanie wskazujące, że oba adresy dotyczą tej samej witryny. Korzyść odnosi czytelnik: osoba korzystająca z Tor może pozostać wewnątrz sieci Tor, eliminując węzeł wyjściowy (exit node) oraz zapytania DNS dla danej domeny. Jeśli celem jest stworzenie usługi onion, z którą nikt nie może się połączyć, nie należy publikować tego nagłówka ani uruchamiać obu instancji na tej samej maszynie.
W tym kontekście pojawiają się dwa powiązane pytania, z których każde ma własną odpowiedź. Różnica między Tor a VPN determinuje narzędzie używane do własnego ruchu sieciowego, co jest decyzją odrębną od tego, co publikujemy. Jeśli natomiast czytelnicy w cenzurowanej sieci w ogóle nie mogą uzyskać dostępu do witryny w sieci publicznej, nigdy nie zobaczą nagłówka; w takiej sytuacji mostki i transporty wtykowe (pluggable transports) mają znacznie większe znaczenie niż cokolwiek opisanego na tej stronie.
Weryfikacja poprawności konfiguracji
Należy wykonać poniższe polecenia w podanej kolejności. Każde z nich zwraca wynik, który można zweryfikować.
curl -sI https://example.com/ | grep -i onion-locationwyświetla nagłówek.- To samo polecenie wykonane dla adresu URL zwracającego błąd 404 również wyświetla nagłówek.
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/zwraca stronę.- Przeszukiwanie tego wyniku za pomocą grep pod kątem domeny clearnet nie zwraca żadnych danych.
- Tor Browser pod adresem
https://example.comwyświetla ikonę.onion available.
Jeśli kroki od 1 do 4 kończą się powodzeniem, a krok 5 nie, przyczyną jest niemal zawsze miejsce serwowania nagłówka, a nie sam nagłówek. Należy potwierdzić, że przeglądarka faktycznie wczytała stronę HTTPS, a nie przekierowanie z pamięci podręcznej, a następnie wykonać curl -sI dla dokładnego adresu URL, który został otwarty. Blok location dla tej konkretnej ścieżki może bowiem odrzucać dyrektywę z poziomu serwera.
FAQ
Dlaczego Tor Browser nie wyświetla paska „.onion available”?
W pierwszej kolejności należy sprawdzić trzy udokumentowane wymagania. Wartość musi być pełnym adresem URL ze schematem http: lub https: oraz hostem .onion, dlatego sam adres bez schematu nie zadziała i nie wygeneruje błędu. Strona musi być serwowana przez HTTPS, więc nagłówek ustawiony w bloku przekierowania portu 80 nie zostanie odczytany. Ponadto sama strona nie może być adresem onion. Następnie należy sprawdzić konfigurację nginx: każda dyrektywa add_header wewnątrz pasującego bloku location odrzuca wszystkie nagłówki add_header z poziomu serwera, a bez flagi always nagłówek nie pojawi się w odpowiedziach 404 i 500. Należy uruchomić curl -sI dla dokładnego adresu URL wczytanego w przeglądarce i potwierdzić, czy nagłówek faktycznie znajduje się w przesyłanych danych.
Czy potrzebuję certyfikatu TLS dla mojej strony onion?
Nie. Adres onion w wersji v3 jest wywodzony z klucza publicznego usługi, więc połączenie jest uwierzytelnione dla tej konkretnej usługi i szyfrowane od końca do końca przed wysłaniem jakiegokolwiek żądania HTTP. Zwykły protokół HTTP wewnątrz usługi onion jest standardową konfiguracją. Należy unikać prezentowania certyfikatu z sieci publicznej (clearnet) w usłudze onion. Lista alternatywnych nazw podmiotu (SAN) zawiera domenę, co wywołuje ostrzeżenie o niezgodności nazw w przeglądarce i potwierdza każdemu odwiedzającemu, że obie witryny działają na tej samej maszynie.
Czy publikacja Onion-Location zapewnia anonimowość witryny?
Nie. Nagłówek jest publiczną deklaracją domeny z sieci publicznej, że dany adres onion należy do operatora, a każdy może go pobrać. Korzyść odnosi czytelnik, który może przejść do sieci onion i usunąć węzeł wyjściowy oraz zapytanie DNS ze swojej ścieżki. Jako operator nie zyskuje się anonimowości, a oba adresy zostają trwale powiązane. Usługa onion, która nie powinna być powiązana z operatorem, powinna być publikowana w innym miejscu, na sprzęcie, który nie współdzieli żadnych zasobów z witryną w sieci publicznej.
Czy można użyć znacznika meta zamiast nagłówka HTTP?
Tak, w sytuacjach, gdy nie można ustawić nagłówków odpowiedzi, co jest typowe dla hostingu statycznego. Należy umieścić <meta http-equiv="onion-location" content="http://youraddress.onion" /> w sekcji head dokumentu. Obowiązują te same trzy wymagania, więc strona musi korzystać z HTTPS i nie może być adresem onion. Jedyna istotna różnica polega na tym, że znacznik zawiera stały adres bez ścieżki, podczas gdy nagłówek nginx może dołączyć $request_uri i zaoferować odwiedzającemu tę samą stronę w sieci onion, zamiast przekierowywać go na stronę główną.