SSD Nodes Learn 🎉 VPS dari $5.50/bln
Panduan Matt ConnorOleh Matt Connor · Dikemas kini 2026-08-13

Cara Bina Laman Onion v3 di VPS Ubuntu

Ketahui cara menjalankan perkhidmatan onion v3 dengan Tor dan Nginx pada Ubuntu. Panduan ini menunjukkan langkah mengikat Nginx ke loopback serta menutup kebocoran IP awam.

Apa yang anda sedang bina

Laman onion ialah pelayan web biasa yang hanya menjawab permintaan melalui rangkaian Tor. Pasang tor, tambah dua baris ke dalam /etc/tor/torrc, baca alamat yang ditulis oleh tor untuk anda, kemudian ikat (bind) nginx ke 127.0.0.1 supaya tiada apa-apa yang menjawab pada IP awam. Bahagian pemasangan mengambil masa sepuluh minit. Selebihnya panduan ini adalah senarai kebocoran, kerana cara biasa laman onion gagal adalah apabila konfigurasinya sendiri menghala terus kembali kepada pengendali.

Tor bermula sebagai "the onion router", dan perkhidmatan onion ialah perkhidmatan yang hanya boleh dicapai melaluinya. Alamat versi 3 terdiri daripada 56 aksara diikuti dengan .onion, dan aksara tersebut ialah kunci awam ed25519 perkhidmatan itu berserta checksum dan bait versi, yang dikodkan dalam base32. Alamat versi 2 (16 aksara) telah dibuang daripada rangkaian pada tahun 2021, jadi apa sahaja yang anda jana hari ini adalah v3. Alamat tersebut adalah kunci itu sendiri, yang membawa dua akibat. Sambungan disulitkan dan disahkan dari hujung ke hujung tanpa melibatkan pihak berkuasa sijil (certificate authority), dan kehilangan fail kunci bermakna kehilangan alamat tersebut selama-lamanya.

Pelayan anda tidak pernah menerima sambungan masuk. Tor memilih beberapa relay sebagai titik pengenalan (introduction points), memuat naik deskriptor yang ditandatangani ke pelayan direktori, dan bertemu setiap pelawat di relay pertemuan (rendezvous relay) yang dipilih oleh pelawat tersebut. Setiap sambungan itu adalah sambungan keluar daripada kotak anda. Tiada port untuk dibuka dan tiada rekod DNS untuk diterbitkan.

Memasang Tor daripada repositori Tor Project

Ubuntu membekalkan pakej tor dalam universe, namun versinya kekal hampir sama dengan versi semasa apabila keluaran tersebut dibekukan. Repositori Tor Project sendiri menjejaki keluaran stabil semasa, iaitu apa yang anda perlukan bagi perisian yang menentukan sama ada alamat anda kekal milik anda.

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/null

Entri repositori menggunakan format deb822, dan Suites mestilah nama kod Ubuntu anda. Baca ia daripada /etc/os-release dan bukannya menaipnya, kerana nama kod yang salah akan memberikan anda repositori yang dapat diselesaikan dengan baik tetapi tidak mempunyai pakej untuk keluaran anda.

. /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-keyring

Pakej deb.torproject.org-keyring memastikan kunci penandatangan sentiasa terkini, supaya putaran kunci tidak merosakkan apt update pada tahun hadapan. Pastikan tor telah bermula dan mencapai rangkaian:

tor --version
sudo journalctl -u tor@default -n 20

Jurnal sepatutnya berakhir dengan Bootstrapped 100% (done): Done. Tor yang tersangkut pada Bootstrapped 10% tidak mempunyai laluan keluar, jadi periksa firewall rangkaian pembekal anda dan peraturan egress anda sendiri: sudo ufw status verbose sepatutnya menunjukkan allow (outgoing) sebagai laluan lalai.

Dua nama penting mulai sekarang. Pakej ini menjalankan tor sebagai pengguna debian-tor, dan unit yang sedang berjalan ialah tor@default.service, memandangkan tor.service pada Debian dan Ubuntu merupakan pembungkus (wrapper) untuk instans tersebut. Minta status dan log mengikut nama instans dan anda akan sentiasa mendapat proses yang sebenar.

Konfigurasi onion service dalam torrc

Tambahkan dua baris berikut ke dalam /etc/tor/torrc:

HiddenServiceDir /var/lib/tor/onion_site/
HiddenServicePort 80 127.0.0.1:8080

HiddenServiceDir ialah lokasi Tor menyimpan kunci dan alamat untuk servis ini. Jangan cipta direktori ini sendiri. Tor akan menciptanya semasa permulaan dengan pemilik dan mod yang diperlukan. Direktori yang dicipta sebagai root akan menyebabkan kegagalan pertama dalam senarai kegagalan di bawah.

HiddenServicePort mempunyai dua bahagian, dan tertukar antara keduanya merupakan kesilapan pertama yang lazim berlaku. Nombor pertama ialah port yang disambungkan oleh pelawat di dalam tunnel, jadi 80 adalah apa yang dijangkakan oleh pengguna dan tiada sebab untuk mengubahnya. Bahagian kedua ialah alamat tempatan yang menjadi destinasi trafik yang diforward oleh Tor. HiddenServicePort 80 kosong akan memforward ke 127.0.0.1:80, jadi menulis alamat penuh dan menggunakan port tinggi memastikan vhost onion tidak bertindih dengan sebarang servis yang sedang mendengar pada port 80.

sudo systemctl restart tor@default
sudo ls -l /var/lib/tor/onion_site/

Penyenaraian tersebut sepatutnya mengandungi hostname, hs_ed25519_public_key, hs_ed25519_secret_key dan direktori authorized_clients yang kosong.

Baca alamat .onion anda

sudo cat /var/lib/tor/onion_site/hostname

Satu baris akan dipaparkan: 56 aksara base32 dan .onion. Rentetan tersebut merupakan identiti penuh tapak berkenaan. Tiada sesiapa yang menetapkannya, tiada sesiapa boleh memindahmilikkannya, dan tiada sesiapa boleh mengambilnya selagi anda memegang fail kunci tersebut. Salin alamat itu sekarang, kerana setiap konfigurasi di bawah memerlukannya. Selebih panduan ini akan merujuknya sebagai <your-address>.onion.

Hidangkan laman web daripada nginx yang terikat pada 127.0.0.1

sudo apt install -y nginx
sudo install -d -m 755 /srv/onion

Tulis /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 nginx

Sekarang, buktikan dua perkara daripada pelayan tersebut. Pertama, nginx menjawab untuk nama onion, yang merupakan pengepala Host tepat yang akan dihantar oleh tor:

curl -s -H 'Host: <your-address>.onion' http://127.0.0.1:8080/

Kedua, ia menjawab di sana dan tidak di tempat lain:

sudo ss -tlnp | grep 8080

Lajur alamat mesti memaparkan 127.0.0.1:8080. Jika ia memaparkan 0.0.0.0:8080 atau *:8080, laman onion anda juga berada di internet awam, yang merupakan perkara pertama dalam senarai kebocoran. Baris listen 8080; tanpa alamat akan mengikat setiap antara muka, dan itu adalah tetapan lalai.

Buka alamat tersebut dalam Tor Browser. Pemuatan pertama mengambil masa beberapa saat sementara klien mendapatkan deskriptor anda dan membina litar pertemuan (rendezvous circuit).

Dokumentasi rasmi The Tor Project lebih mengutamakan soket unix berbanding port loopback: HiddenServicePort 80 unix:/var/run/tor/onion_site.sock, dengan nginx mendengar pada laluan tersebut. Soket tidak boleh dicapai dari hos lain sama sekali, walaupun kotak tersebut kemudiannya mempunyai antara muka kedua. Kosnya ialah keizinan fail, memandangkan nginx mencipta soket tersebut dan tor menyambung kepadanya sebagai debian-tor, jadi kedua-dua pengguna perlu bersetuju mengenai direktori tersebut. Loopback dengan output ss yang disahkan adalah lebih mudah untuk dilakukan dengan betul, dan itulah yang diandaikan oleh panduan ini seterusnya.

Dengan laman web berada pada loopback, kotak tersebut tidak memerlukan sebarang peraturan masuk untuknya sama sekali. Pastikan 22 terbuka untuk kegunaan anda sendiri dan nafikan yang lain (tetapan lalai ufw yang perlu ditetapkan pada VPS). Ingat bahawa firewall tidak membatalkan servis yang terikat pada 0.0.0.0, ia hanya menapis paket yang sampai ke firewall. Kontena menjadikan perkara ini lebih kritikal, kerana menerbitkan port Docker menulis peraturan iptables sebelum ufw, jadi -p 8080:80 meletakkan backend onion anda pada IP awam sementara ufw masih melaporkan port tersebut sebagai dinafikan. Terbitkan port kontena sebagai -p 127.0.0.1:8080:80.

Kebocoran yang menyah-anonymkan onion site

Tor menyembunyikan lokasi pelayan. Tiada apa-apa dalam Tor yang menyembunyikan kandungan yang disampaikan oleh pelayan. Setiap perkara di bawah adalah maklumat yang diterbitkan oleh stack anda sendiri.

Tapak yang sama menjawab pada IP awam anda

Ini adalah perkara yang sering memerangkap pengguna. Pengimbas mengindeks respons HTTP bagi setiap alamat yang boleh dihalakan secara berterusan, dan hasil tersebut adalah awam serta boleh dicari. Jika anda menghidangkan halaman yang sama pada IP awam dan alamat onion anda, kedua-duanya boleh dikaitkan dengan satu pertanyaan: tajuk yang sama, hash favicon yang sama, ETag yang sama, dan susunan header yang sama. Baris listen 127.0.0.1:8080; di atas adalah penyelesaiannya. Sahkan perkara ini daripada mesin yang berbeza, bukan daripada pelayan itu sendiri:

curl -sv --max-time 5 http://<your-public-ip>:8080/

Connection refused atau timeout adalah hasil yang betul. Sebarang HTML bermakna tapak tersebut adalah awam. Jika kotak tersebut juga menjalankan tapak clearnet, berikan vhost tersebut root sendiri dan kekalkan blok default_server yang eksplisit pada listener awam, supaya header Host yang tidak sepadan tidak akan terlepas ke vhost onion.

curl -sI http://127.0.0.1:8080/ | grep -i '^server'

Nginx lalai akan menjawab Server: nginx/1.24.0. String versi tersebut, bersama dengan susunan tepat header lain, merupakan cap jari (fingerprint) yang memadankan onion anda dengan hos clearnet anda. server_tokens off; mengurangkannya kepada Server: nginx. Ia tidak membuang header tersebut, dan nginx tidak mempunyai direktif terbina dalam untuk membuangnya, jadi modul headers-more adalah jawapan biasa jika anda mahu ia dibuang. PHP menambah X-Powered-By sehingga anda menetapkan expose_php = Off. etag off; tergolong dalam senarai yang sama, kerana nginx membina ETag daripada masa pengubahsuaian dan saiz fail, jadi fail yang sama yang disalin ke dua pelayan akan memberikan ETag yang sama pada kedua-duanya.

URL mutlak yang menghala ke domain clearnet anda

Tag rel="canonical", og:url Open Graph, suapan RSS, sitemap, e-mel tetapan semula kata laluan, URL logo yang dikodkan secara keras (hardcoded). Mana-mana daripadanya menamakan tapak clearnet di dalam halaman yang dihidangkan melalui onion. Gunakan laluan relatif-root seperti /static/logo.svg, dan biarkan aplikasi membaca URL asasnya daripada hos permintaan dan bukannya pemalar. Redirect adalah pepijat yang sama di tempat lain: return 301 https://example.com$request_uri; dalam blok catch-all menghantar pelawat onion ke domain sebenar anda, dan header Location memberikan jawapan terus kepada mereka.

Sijil TLS yang dikongsi dengan tapak clearnet

Alamat onion mengesahkan dirinya sendiri, kerana alamat tersebut adalah kunci awam, jadi http:// melalui sambungan onion sudah disulitkan dari hujung ke hujung dan Tor Browser menganggapnya sebagai konteks selamat. Memasang sijil sedia ada anda pada vhost onion akan menerbitkan pautan antara kedua-duanya, kerana setiap sijil yang dipercayai secara awam direkodkan dalam log Certificate Transparency, dan log tersebut adalah awam, kekal, dan boleh dicari mengikut nama. Simpan sijil Let's Encrypt pada vhost clearnet dan biarkan vhost onion menggunakan HTTP biasa.

Fon dan analitik pihak ketiga

Fon daripada CDN (content delivery network), atau skrip analitik. Pelayar pelawat mengambil setiap satu secara terus, jadi pihak ketiga mengetahui bahawa seseorang memuatkan halaman anda dan biasanya halaman yang mana, dan tahap keselamatan Tor Browser yang lebih ketat akan menyekat permintaan tersebut, menyebabkan susun atur yang rosak. Lakukan self-host bagi setiap aset yang diperlukan oleh halaman tersebut.

Ketidakpadanan header Host

Jika server_name tidak sepadan dengan header Host yang dihantar oleh tor, nginx akan kembali kepada pelayan lalai untuk alamat listen tersebut. Pada kotak dengan satu vhost, ini tidak kelihatan, kerana satu-satunya blok pelayan juga merupakan blok lalai. Tambahkan vhost clearnet kemudian dan permintaan onion boleh mula mendarat di situ, lengkap dengan tag kanonikal dan redirectnya. Jalankan semula semakan curl -H 'Host: ...' selepas setiap perubahan nginx, dan grep hasilnya untuk domain sebenar anda:

curl -s -H 'Host: <your-address>.onion' http://127.0.0.1:8080/ | grep -o 'https\?://[^"]*' | sort -u

Mengetahui proses mana yang memiliki soket mana adalah sebahagian besar daripada tugas ini (bagaimana port dan soket pendengar berfungsi pada Linux).

Apa yang tertinggal dalam log

Setiap permintaan tiba daripada 127.0.0.1, jadi nginx tidak mempunyai alamat pelawat untuk direkodkan dan access_log off; tidak merugikan anda. Aplikasi di atasnya adalah perkara yang berbeza, kerana pesanan, alamat e-mel, atau metadata fail yang dimuat naik adalah tanggungjawab anda untuk menguruskannya. Tabiat anda sendiri juga penting: mentadbir kotak melalui log masuk yang tidak diperkukuh berada di luar perlindungan Tor, jadi anggap pengukuhan SSH pada VPS yang sama sebagai sebahagian daripada binaan ini.

Sandarkan kunci peribadi, kerana ia adalah alamatnya

/var/lib/tor/onion_site/hs_ed25519_secret_key ialah servis tersebut. Tiada pendaftar dan tiada pemulihan. Jika ia hilang, alamat tersebut akan lenyap. Salin kunci tersebut, dan sesiapa sahaja yang memegang salinannya boleh menghidangkan kandungan mereka sendiri pada alamat anda, tanpa cara untuk anda membatalkan apa-apa.

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@default

Suluhkan arkib tersebut (gpg -c onion-keys.tgz) dan pindahkannya keluar dari pelayan. Pemulihan pada VPS baharu memerlukan arkib tersebut berserta pemilikan yang dijangkakan oleh 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/hostname

Alamat yang sama akan kembali pada perkakasan baharu, seminit atau dua minit selepas tor menerbitkan semula deskriptor. Itulah keseluruhan proses migrasi: tiada perubahan DNS dan tiada pengeluaran semula sijil.

Onion-Location, apabila tapak tersebut juga wujud pada clearnet

Jika onion tersebut merupakan satu kemudahan dan bukannya rahsia, iklankan ia daripada vhost clearnet:

add_header Onion-Location http://<your-address>.onion$request_uri;

Tor Browser kemudian akan memaparkan butang .onion available pada bar alamat dan menawarkan pertukaran tersebut. Header ini hanya dihormati apabila halaman clearnet dihidangkan melalui HTTPS dan nilainya merupakan URL onion yang sah.

Satu peraturan nginx boleh menyebabkan masalah di sini. Arahan add_header diwarisi oleh blok location hanya apabila blok tersebut tidak mengisytiharkan arahannya sendiri, jadi location yang mempunyai add_header sendiri akan menggugurkan Onion-Location secara senyap. Ulangi arahan tersebut di sana, atau simpan semua response header di satu lokasi. Menerbitkan header ini secara sengaja menghubungkan kedua-dua tapak tersebut, yang mana adalah betul untuk cermin (mirror) tetapi salah untuk sebarang perkara yang sepatutnya kekal tidak terhubung.

Alamat vanity

mkp224o menjana pasangan kunci sehingga salah satu daripadanya menghasilkan alamat yang bermula dengan awalan yang anda minta. Ini merupakan carian brute force, jadi tiada apa yang perlu dikonfigurasikan selain awalan tersebut dan tempoh masa yang anda sanggup tunggu.

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 blog

Setiap padanan akan disimpan dalam onionkeys/<address>.onion/ yang mengandungi hostname dan hs_ed25519_secret_key. Pasang satu dengan menghentikan tor, menyalin direktori tersebut ke atas HiddenServiceDir anda, kemudian gunakan chown dan chmod 700 yang sama seperti proses pemulihan di atas.

Panjang awalan menentukan kos keseluruhannya. Alamat tersebut adalah dalam format base32, jadi setiap aksara tambahan yang anda minta akan mendarabkan jangkaan bilangan kunci sebanyak 32 kali ganda. Awalan yang pendek boleh diselesaikan pada komputer riba. Awalan yang panjang tidak akan selesai pada sebarang perkakasan yang anda miliki. Awalan vanity juga mengajar pembaca untuk mengecam beberapa aksara pertama dan bukannya keseluruhan alamat, dan itulah tabiat yang digunakan oleh laman onion palsu untuk tujuan pancingan data (phishing).

Mod kegagalan, berserta rentetan yang akan anda lihat

Tiada fail hostname selepas but semula. Tor tidak bermula, atau ia menolak direktori tersebut. sudo journalctl -u tor@default -n 50 menamakannya:

/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?

Begitulah rupa direktori yang dicipta secara manual. Betulkan pemilikan dan mod, atau padam direktori tersebut dan biarkan tor membinanya semula.

Tor Browser menunjukkan Onionsite Not Found (0xF0). Pelanggan tidak dapat mengambil deskriptor, jadi bagi pihak rangkaian, tiada apa-apa yang diterbitkan pada alamat tersebut. Sahkan tor sedang berjalan dan telah selesai melakukan bootstrap, bandingkan alamat yang anda taip dengan sudo cat /var/lib/tor/onion_site/hostname aksara demi aksara, kemudian periksa jam sistem. Tor memerlukan masa yang tepat untuk menerbitkan dan mengesahkan deskriptor, dan timedatectl sepatutnya melaporkan System clock synchronized: yes.

Alamat dapat diselesaikan tetapi halaman tidak pernah dimuatkan. Tor telah melengkapkan rendezvous dan kemudian gagal pada hop terakhir, dari tor ke nginx, dan hop tersebut adalah setempat jadi log tor kekal senyap. Jalankan curl -sI http://127.0.0.1:8080/ pada pelayan. Connection refused bermaksud nginx tidak aktif atau sedang mendengar pada alamat yang berbeza daripada yang ditunjukkan oleh HiddenServicePort.

Halaman dimuatkan dan setiap pautan menuju ke domain sebenar anda. URL mutlak dalam templat. Jalankan semakan grep -o 'https\?://[^"]*' di atas dan betulkan apa yang dicetaknya sebelum anda berkongsi alamat tersebut di mana-mana.

Ia berfungsi, kemudian berhenti selepas but semula. But semula kotak tersebut sekali dengan sengaja sebelum anda bergantung pada tapak tersebut, kemudian jalankan sudo systemctl status tor@default dan sudo systemctl status nginx. Servis yang dimulakan oleh seseorang secara manual kelihatan sama seperti servis yang didayakan sehingga mesin but semula.

FAQ

Adakah saya perlu membuka port dalam firewall untuk Tor onion service?

Tidak. Daemon tor hanya membuat sambungan keluar ke pelayan direktori, ke titik pengenalan (introduction points) dan ke setiap relay pertemuan (rendezvous relay), jadi tiada peraturan masuk diperlukan dan pelayan web itu sendiri mendengar pada 127.0.0.1. Pastikan ufw ditetapkan kepada default deny untuk trafik masuk dengan SSH dibenarkan. Sifat yang sama bermakna onion service berfungsi daripada mesin di sebalik NAT (network address translation) tanpa sebarang IP awam.

Mengapa saya tidak boleh mencapai alamat .onion saya dalam Tor Browser?

Periksa bermula dari pelayan ke luar. sudo journalctl -u tor@default -n 50 sepatutnya menunjukkan Bootstrapped 100% (done): Done, kemudian curl -sI http://127.0.0.1:8080/ pada pelayan sepatutnya mengembalikan baris status, kemudian bandingkan alamat yang anda taip dengan fail hostname, kerana satu aksara yang salah akan merujuk kepada servis yang berbeza. Onionsite Not Found (0xF0) bermakna tiada deskriptor ditemui untuk alamat tersebut, yang biasanya bermaksud tor tidak berjalan atau jam sistem tidak tepat.

Bolehkah saya memindahkan tapak onion saya ke pelayan baharu dan mengekalkan alamat yang sama?

Ya. Alamat tersebut diperoleh daripada hs_ed25519_secret_key, jadi salin keseluruhan HiddenServiceDir ke mesin baharu, tetapkan pemilikan kepada debian-tor dan mod 700, kemudian mulakan tor. Alamat tersebut akan aktif semula sebaik sahaja deskriptor diterbitkan semula, dan tiada rekod DNS yang perlu dikemas kini. Jika fail itu hilang, alamat tersebut tidak dapat dipulihkan, jadi buat sandaran yang disulitkan dan simpan di luar pelayan pada hari anda menciptanya.

Adakah tapak onion memerlukan sijil HTTPS?

Tidak. Alamat 56 aksara tersebut ialah kunci awam servis, jadi sambungan sudah pun disulitkan dan disahkan dari hujung ke hujung, dan Tor Browser menganggap http:// pada nama .onion sebagai konteks selamat. Menggunakan semula sijil clearnet anda pada vhost onion adalah lebih buruk daripada tidak melakukan apa-apa, kerana log Certificate Transparency adalah awam dan merekodkan secara kekal nama mana yang berkongsi sijil. Satu-satunya sebab untuk membeli sijil bagi nama .onion adalah untuk jaminan jenama daripada CA yang mengeluarkannya, dan pautan tersebut adalah awam mengikut reka bentuknya.