Onion-Location header toevoegen in Nginx
Configureer de Onion-Location header in Nginx zodat Tor Browser uw onion-adres herkent. Voorkom dat redirects of externe assets uw anonimiteit onbedoeld schaden via deze gids.
Wat de Onion-Location header doet
De Onion-Location header is één regel in uw clearnet vhost die uw onion-adres adverteert aan Tor Browser. Een bezoeker die https://example.com via Tor bereikt, ziet een paarse pil in de adresbalk met de tekst .onion available. Met één klik wordt de bezoeker naar uw onion-service verplaatst. Het is uitsluitend een ontdekkingsmechanisme. De header creëert de onion-service niet en verbergt niets over u.
Deze handleiding gaat ervan uit dat beide helften al bestaan. U heeft een site op een VPS achter nginx en u heeft een werkende v3 onion-service die daarnaar verwijst. Als u de tweede helft nog niet heeft, bouw deze dan eerst: het hosten van een onion-site op een VPS behandelt de torrc-regels en het eerste hostname-bestand. Wat volgt gaat over het koppelen van beide zonder dat de een in de ander lekt.
Wat Tor Browser vereist voordat de header wordt geaccepteerd
Het Tor Project documenteert drie voorwaarden. Aan alle drie moet worden voldaan, anders verschijnt de melding niet.
- De
Onion-Location-waarde moet een geldige URL zijn met eenhttp:- ofhttps:-schema en een.onion-hostnaam. - De webpagina die de header definieert, moet via HTTPS worden geserveerd.
- De webpagina die de header definieert, mag zelf geen onion-site zijn.
De tweede voorwaarde is waar gebruikers vaak tegenaan lopen, en de derde verklaart waarom u deze header nooit op de onion-vhost moet instellen. Er is een vierde regel die niet in de documentatie staat, maar wel in de implementatie: Tor Browser reageert alleen op de header voor het hoofddocument. De code vergelijkt het laaddoel met het document voordat er actie wordt ondernomen; een header die wordt geretourneerd bij een stylesheet, een afbeelding of een API-respons wordt daarom genegeerd.
Standaard toont de browser de melding en wacht op een klik. Een lezer die een automatische overstap wil, kan dit inschakelen onder Instellingen, vervolgens Privacy en beveiliging, en dan Onion-services, waar "Prioritize .onion sites when known" kan worden ingesteld op "Always". U kunt dit niet vanaf de serverzijde afdwingen. Beschouw de header als een aanbod, niet als een redirect.
De Onion-Location header toevoegen in nginx
De header hoort thuis in het server-blok dat TLS-termination verzorgt voor uw clearnet-domein. Plaats deze niet in het poort 80-blok; daar gebeurt niets, omdat dat blok enkel een redirect uitvoert en de tweede vereiste regels uitsluit voor headers op een onbeveiligde HTTP-pagina.
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 bevat het pad en de query-string, zodat een bezoeker op https://example.com/guides/tor op het onion-adres naar hetzelfde pad wordt geleid. Laat u dit weg, dan belandt elke bezoeker op de startpagina van de onion-site in plaats van op de pagina die zij aan het lezen waren.
always is van belang vanwege een gedocumenteerde limiet in nginx. add_header voegt het veld alleen toe wanneer de response-code 200, 201, 204, 206, 301, 302, 303, 304, 307 of 308 is. Uw 404-pagina is een reëel startpunt vanuit zoekresultaten, en zonder always bevat deze helemaal geen header.
De tweede valkuil in nginx is overerving, wat geruisloos faalt. add_header-directives worden alleen overgeërfd van het voorgaande configuratieniveau als er geen add_header-directives op het huidige niveau staan. Een location /assets/ { add_header Cache-Control ...; }-blok negeert dus de Onion-Location op server-niveau voor elke URL daaronder. Als u headers per locatie instelt, herhaal dan de Onion-Location-regel in elk van die blokken. Hoe nginx een server- en locatie-blok kiest is het lezen waard als dit gedrag nieuw voor u is.
Herlaad de configuratie en controleer zowel een normale pagina als een niet-bestaande pagina:
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-locationBeide commando's horen een onion-location:-regel te tonen. De tweede is het bewijs dat always werkt. Geen output bij het tweede commando betekent dat de flag ontbreekt of dat een location-blok de directive overschaduwt.
De HTML-metatag wanneer u geen headers kunt instellen
Statische hosts en sommige CDN-dashboards staan niet toe dat u willekeurige response-headers toevoegt. Dezelfde waarde werkt als een meta-element in de head van het document, omdat de browser deze via dezelfde document-headergegevens leest, ongeacht of deze via HTTP of als een http-equiv-tag is binnengekomen.
<meta http-equiv="onion-location" content="http://<your-onion-address>.onion" />De drie vereisten blijven van kracht. De pagina die de tag bevat, moet HTTPS gebruiken en mag geen onion-adres zijn. Het verschil is dat de tag één vast adres zonder pad bevat, omdat er geen server-side variabele is om uit te breiden. Elke pagina die de tag bevat, verwijst naar de onion-homepage. Dat is het nadeel van dit alternatief; geef daarom de voorkeur aan de header wanneer u de server beheert.
De onion-site serveren via een eigen nginx vhost
De clearnet-site en de onion-site mogen geen server block delen. Tor Browser verstuurt Host: <your-onion-address>.onion. Als geen enkel server block die naam claimt, valt nginx terug op de default server, wat uw clearnet vhost is. Elke URL die die vhost genereert, benoemt dan uw domein.
Laat de hidden service verwijzen naar een poort die alleen op de loopback-interface reageert:
HiddenServiceDir /var/lib/tor/onion_site/
HiddenServicePort 80 127.0.0.1:8080Geef die poort vervolgens een eigen 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 houdt deze vhost weg van uw publieke IP-adres. Hierdoor kan iemand die het VPS-adres scant, de site niet ophalen en byte voor byte vergelijken met de clearnet-kopie. absolute_redirect off zorgt ervoor dat nginx relatieve Location-waarden uitgeeft. Hierdoor geeft de redirect bij een ontbrekende slash aan het einde van een directory Location: /guides/ terug in plaats van een volledige URL. nginx bouwt redirects al op basis van de Host-header in plaats van server_name, omdat server_name_in_redirect standaard op off staat, maar een relatieve redirect neemt deze vraag volledig weg.
Waarom stuurt de onion-pagina bezoekers nog steeds door naar de clearnet-site?
nginx is zelden de oorzaak van het lek. Uw applicatie is dat wel. Alles wat een absolute URL opbouwt op basis van een geconfigureerd site-adres, zal uw domein noemen, ongeacht welke vhost het verzoek heeft afgehandeld.
- Een
rel="canonical"link-tag die naarhttps://example.com/...wijst. Dit komt het meest voor en toont de exacte clearnet-pagina aan iedereen die de broncode bekijkt. - Redirects die door het framework worden gegenereerd in plaats van door nginx, zoals Django's
SECURE_SSL_REDIRECTof de optieshomeensiteurlin WordPress. og:urlen andere meta-tags voor sociale media.- Sitemap- en RSS-items, die volgens de specificatie absoluut zijn.
- Foutpagina's van applicaties, die meestal een "terug naar de startpagina"-link bevatten die is opgebouwd vanuit dezelfde instelling.
De oplossing hangt af van uw stack en er is geen algemene methode. De controle is wel algemeen. Haal de onion-pagina op via Tor en doorzoek het antwoord op uw domein.
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/ \
| grep -i 'example\.com'--socks5-hostname stuurt de naam naar de SOCKS-poort van tor voor resolutie; dit is vereist omdat niets op uw machine lokaal een .onion-naam kan omzetten. Poort 9050 is de standaard voor een geïnstalleerde tor-daemon. Een leeg resultaat betekent dat de test is geslaagd. Elke treffer is een pagina die uw clearnet-domein doorgeeft aan elke onion-bezoeker. Voer dit uit op de startpagina en vervolgens op een URL die een 404 genereert.
Controleer de redirect-keten afzonderlijk, omdat de body van een redirect meestal leeg is:
curl -sI --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/guides \
| grep -i '^location'Een Location-waarde die example.com noemt, betekent dat een redirect uw onion-bezoeker terugstuurt naar het clearnet, via een exit-node, bij een verzoek waarvan zij dachten dat het binnen Tor bleef.
Presenteer uw clearnet-certificaat niet op de onion-service
Een v3 onion-adres is afgeleid van de publieke sleutel van de service zelf. Hierdoor authenticeert en versleutelt Tor het circuit naar die specifieke service voordat er een HTTP-verzoek wordt verzonden. Plain HTTP binnen een onion-service is de standaardconfiguratie en is niet hetzelfde als plain HTTP via het openbare internet.
Als u de onion-vhost bouwt door de clearnet-configuratie te kopiëren, kopieert u ook ssl_certificate. De onion-service presenteert nu een certificaat waarvan de subject alternative names-lijst example.com bevat. Er gaan dan twee dingen mis. De browser toont een foutmelding over een naamconflict, omdat de URL het onion-adres is en het certificaat dit niet dekt. Daarnaast ontvangt elke bezoeker die doorklikt een ondertekende verklaring dat deze twee sites op dezelfde machine draaien. Houd de onion-vhost in een eigen bestand met een eigen server_name. Dit voorkomt ook dat de Certbot nginx plugin hierop ingrijpt, aangezien die plugin het server-blok aanpast dat overeenkomt met het domein waarvoor u een certificaat aanvraagt.
Welk tor-pakket en het veilig bewaren van de servicesleutel
Het tor-pakket in het Ubuntu-archief werkt hiervoor en vereist geen extra configuratie. Het loopt echter achter op de huidige stabiele reeks. Gebruik voor een service die u langdurig wilt draaien daarom de Debian-repository van het Tor Project en laat apt deze samen met de rest van het systeem bijwerken. Per augustus 2026 zijn de gedocumenteerde stappen als volgt:
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/nullSchrijf /etc/apt/sources.list.d/tor.sources en vervang de suite door uw release-codename uit 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-keyringHet deb.torproject.org-keyring-pakket houdt de ondertekeningssleutel actueel, zodat de repository over een jaar niet stopt met verifiëren. Kies één bron en blijf daarbij. Het archiefpakket en het repository-pakket bevatten verschillende versies; als beide zijn ingeschakeld, zal apt bij upgrades tussen deze versies wisselen.
De HiddenServiceDir bevat uw service-identiteit. Het bestand hs_ed25519_secret_key in die map is uw onion-adres, aangezien het adres de publieke helft van dat sleutelpaar is. Raakt u het bestand kwijt, dan is het adres permanent verloren, omdat er geen autoriteit is die het opnieuw kan uitgeven. Kopieert u het bestand naar een onveilige locatie, dan kan iedereen die de kopie bezit uw onion-service draaien.
tor weigert een map te gebruiken die door andere gebruikers gelezen kan worden. Controleer de modus en de eigenaar voordat u iets anders controleert:
sudo ls -ld /var/lib/tor/onion_site
sudo -u debian-tor cat /var/lib/tor/onion_site/hostnameDe lijstweergave moet drwx------ tonen met eigenaar en groep debian-tor op Debian en Ubuntu. Als de rechten ruimer zijn, logt tor een regel zoals Permissions on directory /var/lib/tor/onion_site/ are too permissive. en start de service niet. Herstel dit met sudo chown -R debian-tor:debian-tor /var/lib/tor/onion_site gevolgd door sudo chmod 700 /var/lib/tor/onion_site, herstart met sudo systemctl restart tor en lees het resultaat met sudo journalctl -u tor@default -n 30.
Maak een back-up van die map zoals u dat doet met een privésleutel: buiten de server en versleuteld. Voeg deze nooit toe aan de repository die uw site bevat. Als dezelfde server ook beheerderstoegang via Tor vereist, is SSH bereiken via een onion-service een nettere scheiding dan het blootstellen van een beheerpad op de publieke site.
Analytics en assets van derden lekken meer dan de header
Dit is het belangrijkste onderdeel, en het heeft niets te maken met Onion-Location. Elk asset van derden waarnaar uw pagina verwijst, is een verzoek dat de browser van de bezoeker buiten het onion-netwerk doet en via een exit node terug op het clearnet plaatst. Een lettertype van een publiek CDN, een gehost analytics-script, een ingesloten videospeler, een reactiewidget: elk element vertelt die derde partij dat iemand uw pagina laadt, tijdens een sessie die de lezer bewust via Tor heeft gerouteerd.
Dit heeft twee gevolgen. De derde partij komt te weten dat het bezoek plaatsvindt. En omdat uw clearnet-kopie dezelfde assets van dezelfde aanbieders laadt, kan iedereen die zicht heeft op beide kanten de twee eigendommen moeiteloos aan elkaar koppelen.
Serveer alles vanaf dezelfde bron. Host uw lettertypes zelf. Verwijder de gehoste analytics-tag of verplaats deze naar uw eigen server, waar self-hosted analytics op een VPS het verzoek binnen het onion-netwerk houdt. Houd er rekening mee dat de standaardinstellingen van Tor Browser veel van wat een analytics-tool probeert te verzamelen, blokkeren of anonimiseren; dit is het gewenste resultaat. Als een pagina niet kan functioneren zonder een script van derden, publiceer die pagina dan niet op de onion-site.
Maak een lijst van wat een pagina daadwerkelijk ophaalt:
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/ \
| grep -oE '(src|href)="https?://[^"]+"' | sort -uElke regel die dit commando afdrukt, is een absolute URL die uw pagina de browser laat ophalen. Alles wat niet uw eigen onion-adres is, is een uitgaand clearnet-verzoek dat u uw lezers namens uzelf laat uitvoeren.
Het dreigingsmodel, helder uitgelegd
Onion-Location maakt een onion-service eenvoudig vindbaar, en dat is alles wat het doet. Het anonimiseert u als beheerder niet, omdat uw clearnet-domein nog steeds registrar-gegevens, DNS-records, een certificaat in de Certificate Transparency-logs en een VPS-account met uw factuurgegevens bevat. Het anonimiseert de onion-service evenmin, omdat u zojuist vanaf dat clearnet-domein een duurzame openbare verklaring heeft gepubliceerd dat beide adressen dezelfde site zijn. Het voordeel is voor de lezer: iemand die via Tor binnenkomt, kan binnen Tor blijven, zonder exit-node in het pad en zonder DNS-opzoeking voor uw domein. Als uw doel een onion-service is waar niemand u kan koppelen aan uw identiteit, publiceer deze header dan niet en draai de twee kopieën niet op dezelfde machine.
Hierbij komen twee gerelateerde vragen naar voren die beide hun eigen antwoord hebben. Het verschil tussen Tor en een VPN bepaalt wat u gebruikt voor uw eigen verkeer; dit is een afzonderlijke beslissing van wat u publiceert. En als lezers in een gecensureerd netwerk de clearnet-site helemaal niet kunnen bereiken, zien zij de header nooit. In dat geval zijn bridges en pluggable transports belangrijker dan alles wat op deze pagina staat.
Controleer de gehele configuratie eenmalig
Voer deze stappen in volgorde uit. Elke stap levert een resultaat op dat u kunt inzien.
curl -sI https://example.com/ | grep -i onion-locationtoont de header.- Hetzelfde commando tegen een URL die een 404-fout geeft, toont deze ook.
curl -s --socks5-hostname 127.0.0.1:9050 http://<your-onion-address>.onion/retourneert uw pagina.- Het doorzoeken van die uitvoer met grep op uw clearnet-domein levert niets op.
- Tor Browser op
https://example.comtoont de.onion available-pil.
Als stap 1 tot en met 4 slagen en stap 5 niet, ligt de oorzaak bijna altijd bij de bron van de header in plaats van de header zelf. Controleer of de browser daadwerkelijk de HTTPS-pagina heeft geladen en niet een gecachte redirect. Voer vervolgens curl -sI uit tegen de exacte URL die u heeft geopend, omdat een location-blok op dat specifieke pad de server-level instructie kan negeren.
FAQ
Waarom toont Tor Browser de ".onion available"-melding niet?
Controleer eerst de drie gedocumenteerde vereisten. De waarde moet een volledige URL zijn met een http: of https:-schema en een .onion-host; een kaal adres zonder schema werkt niet en geeft geen foutmelding. De pagina moet via HTTPS worden geserveerd, dus een header die in uw poort 80-redirectblok is ingesteld, wordt nooit gelezen. Bovendien mag de pagina zelf geen onion-pagina zijn. Controleer daarna Nginx: elke add_header binnen het bijbehorende location-blok negeert elke add_header op serverniveau, en zonder de always-vlag ontbreekt de header bij 404- en 500-responses. Voer curl -sI uit op de exacte URL die u in de browser heeft geladen en bevestig dat de header daadwerkelijk wordt verzonden.
Heb ik een TLS-certificaat nodig voor mijn onion-site?
Nee. Een v3-onion-adres is afgeleid van de publieke sleutel van de service, waardoor het circuit wordt geverifieerd voor die specifieke service en end-to-end wordt versleuteld voordat er een HTTP-verzoek wordt verzonden. Gewone HTTP binnen een onion-service is de standaardconfiguratie. Wat u moet vermijden, is het tonen van uw clearnet-certificaat op de onion-site. De "subject alternative names" bevatten uw domein, wat in de browser een waarschuwing voor een naamconflict veroorzaakt en aan elke bezoeker bevestigt dat beide sites op dezelfde machine draaien.
Maakt het publiceren van Onion-Location mijn site anoniem?
Nee. De header is een publieke verklaring van uw clearnet-domein dat een specifiek onion-adres bij u hoort, en iedereen kan dit opvragen. Het voordeel is voor de lezer, die naar de onion-site kan overstappen en daarmee de exit-node en de DNS-lookup uit het pad verwijdert. Als beheerder wint u geen anonimiteit en koppelt u de twee adressen permanent aan elkaar. Een onion-service die niet naar u herleidbaar mag zijn, moet ergens anders worden gepubliceerd, op hardware die niets deelt met de clearnet-site.
Kan ik de meta-tag gebruiken in plaats van de HTTP-header?
Ja, wanneer u geen response-headers kunt instellen, wat vaak het geval is bij een statische host. Plaats <meta http-equiv="onion-location" content="http://youraddress.onion" /> in de head van het document. Dezelfde drie vereisten zijn van toepassing: de pagina moet HTTPS zijn en mag geen onion-pagina zijn. Het enige echte verschil is dat de tag een vast adres zonder pad bevat, terwijl de Nginx-header $request_uri kan toevoegen en de bezoeker dezelfde pagina op de onion-site kan aanbieden in plaats van alleen de startpagina.