SSH qua Tor onion service, không mở cổng inbound
Đặt sshd sau Tor onion service để VPS không nhận cổng inbound. Làm đúng thứ tự cấu hình, client authorisation v3 và giữ đường console để tránh lockout.
SSH thông qua Tor onion service thay đổi điều gì
SSH thông qua Tor onion service cho phép bạn quản trị một VPS không chấp nhận kết nối inbound trên bất kỳ cổng nào. Server chủ động kết nối ra mạng Tor và duy trì kết nối đó. Phiên SSH của bạn đi ngược trở lại qua kết nối này, nên không có tiến trình nào phải listening trên địa chỉ IP public.
Tác động lên log thể hiện ngay lập tức. Một máy chủ có cổng SSH public thường nhận hàng nghìn lần thử password thất bại mỗi ngày từ các scanner. Đưa sshd ra sau onion service và chặn traffic inbound tại firewall, khi đó /var/log/auth.log chỉ ghi nhận các phiên do bạn khởi tạo.
Đổi lại, tor nằm trên đường đi của mọi phiên admin. Đây là một userspace daemon phải khởi động và bootstrap sau mỗi lần reboot trước khi bạn có thể đăng nhập. Hãy tính đến điều này trước khi đóng cổng, vì lỗi ở đây có thể khiến bạn mất quyền truy cập vào một máy mà bạn không thể tiếp cận trực tiếp.
Tạo đường quay lại trước khi thay đổi bất cứ thứ gì
Không bắt đầu cho đến khi bạn có một đường khôi phục không dùng SSH.
Mở console của nhà cung cấp ngay bây giờ, tức VNC hoặc serial console trong control panel, rồi đăng nhập bằng console đó. Nếu không biết mật khẩu root, trước tiên hãy reset mật khẩu root từ panel và xác nhận mật khẩu hoạt động. Một console chưa từng được kiểm tra không phải là đường khôi phục.
Thứ tự bên dưới rất quan trọng. Mỗi bước phải được xác nhận trước khi chạy bước tiếp theo, và cổng 22 vẫn phải mở cho đến khi onion route hoạt động.
- Cài tor và xác nhận tor bootstrap thành công.
- Khai báo onion service và đọc địa chỉ.
- Kết nối qua onion khi cổng 22 vẫn đang mở.
- Thêm client authorisation, rồi kết nối lại.
- Bind
sshdvào loopback và đóng cổng 22. - Reboot, rồi kết nối lại qua onion.
Giữ nguyên SSH session hiện tại trong suốt quá trình. Một session đã thiết lập vẫn tồn tại khi thay đổi firewall chặn các kết nối mới, vì vậy đây là tuyến cứu hộ đầu tiên của bạn.
Cài đặt tor trên server
Ubuntu có sẵn tor trong repository riêng, nhưng bản này thường cũ hơn. Repository của Tor Project chứa phiên bản được mô tả trong tài liệu của họ. Thêm repository bằng các lệnh trong hướng dẫn apt repository của họ.
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/nullGhi /etc/apt/sources.list.d/tor.sources. Suites lấy codename của bản release, được lsb_release -cs in ra (noble trên 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.gpgsudo apt update
sudo apt install -y tor deb.torproject.org-keyring
sudo journalctl -u tor@default -n 20 --no-pagerLog phải kết thúc bằng Bootstrapped 100% (done). Nếu bị dừng trước đó, tor không thể kết nối đến network. Nguyên nhân gần như luôn là rule outbound của firewall hoặc clock bị sai nghiêm trọng.
Tên unit dễ gây nhầm. systemctl status tor báo Active: active (exited) ngay cả khi mọi thứ vẫn hoạt động bình thường, vì Debian và Ubuntu đóng gói tor dưới dạng một master unit chạy nhiều instance. Nhiệm vụ duy nhất của unit này là gọi instance thực tế. Daemon thực sự chạy dưới tên tor@default.service. Dùng tên đó cho status và journalctl. Các thao tác start, stop và reload với tor vẫn được chuyển đến instance, vì vậy sudo systemctl reload tor hoạt động như bạn mong đợi.
Định nghĩa onion service cho port 22
Thêm 2 dòng vào /etc/tor/torrc.
HiddenServiceDir /var/lib/tor/ssh/
HiddenServicePort 22 127.0.0.1:22Dòng thứ 2 yêu cầu tor chấp nhận virtual port 22 trên onion address và kết nối đến 127.0.0.1:22 trên máy chủ. Tor kết nối đến sshd qua loopback. Vì vậy, sau này sshd có thể ngừng listening trên địa chỉ public. Trỏ dòng thứ 2 đó đến web server trên 127.0.0.1:80, và 2 directive tương tự sẽ public một site trên onion address. Đây là service thứ 2 hữu ích để chạy sau khi cài tor.
sudo systemctl reload tor
sudo cat /var/lib/tor/ssh/hostnameLệnh này in ra 56 ký tự base32, theo sau là .onion. Các ký tự đó là public key của service ở dạng encoded. Trong toàn bộ quy trình này không có certificate authority và cũng không có name registration.
Để tor tự tạo /var/lib/tor/ssh/. Nếu tự tạo bằng tay với owner sai hoặc mode rộng hơn 0700, tor sẽ từ chối sử dụng. Journal sẽ ghi directory có quyền truy cập quá rộng. Các file bên trong là identity của service: hs_ed25519_secret_key chính là address. Sao lưu directory đó với mode 600 và lưu bản sao ngoài máy chủ, vì mất directory này sẽ khiến bạn phải dùng address mới và sửa config trên mọi client.
Kết nối từ workstation
Workstation của bạn cần một tor client. Client này không cần cấu hình gì. Trên Debian hoặc Ubuntu, đó là sudo apt install -y tor netcat-openbsd. Sau đó Tor lắng nghe trên 127.0.0.1:9050 dưới dạng SOCKS5 proxy. SOCKS là một proxy protocol chung. Version 5 có thể truyền hostname thay cho địa chỉ IP. Đây là phần quan trọng trong trường hợp này.
OpenSSH không có SOCKS client riêng, nên cần một chương trình hỗ trợ để tạo kết nối. Thêm dòng này vào ~/.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 chọn SOCKS5 và -x 127.0.0.1:9050 trỏ đến tor đang chạy cục bộ. %h truyền onion name cho tor dưới dạng hostname, để tor phân giải tên đó bên trong network. Lệnh này phải dùng OpenBSD netcat. GNU netcat không có option -X và sẽ dừng với lỗi nc: invalid option -- 'X'.
ssh myvpsKết nối đầu tiên sẽ chậm vì tor phải xây dựng circuit trước khi thực hiện các thao tác khác. Chấp nhận host key fingerprint như khi kết nối ở nơi khác. Từ đây, cách xử lý SSH key thông thường vẫn áp dụng như cũ. Chỉ transport thay đổi. Cơ chế authentication không thay đổi.
Nếu chỉ cần kết nối một lần, bạn có thể bỏ qua mục cấu hình: torsocks ssh admin@xxxxx.onion thực hiện cùng tác vụ.
Thêm cơ chế cấp quyền cho client v3
Hiện tại, bất kỳ ai biết địa chỉ đều có thể truy cập banner SSH và bắt đầu đoán. Địa chỉ onion không thể bị liệt kê từ hệ thống directory, nên địa chỉ hoạt động như một bí mật. Tuy nhiên, nó vẫn có thể bị lộ theo những cách thông thường như shell history hoặc các file cấu hình đã commit vào git repository. Cơ chế cấp quyền cho client khắc phục lỗ hổng này. Service mã hóa descriptor khi publish bằng key của client. Vì vậy, người có địa chỉ nhưng không có key thậm chí không thể locate service.
Tạo một cặp key x25519 trên client. Đây là pipeline từ hướng dẫn cấp quyền cho client của Tor Project, với một thay đổi.
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.keyPhiên bản được publish của các dòng lệnh đó dùng base64pem -d, nhưng bản Ubuntu cài mặc định không có công cụ này. Sau đó command dừng với base64pem: command not found. GNU base64 -d giải mã được cùng phần thân PEM, nên hãy dùng công cụ này thay thế.
Trên server, cài public key.
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 torChỉ các file có phần mở rộng kết thúc bằng .auth mới được đọc. Lưu file này thành laptop.auth.txt. tor sẽ bỏ qua file không có lỗi được in ra, và service vẫn âm thầm mở cho bất kỳ ai có địa chỉ.
Trên client, cài private key. Trên Ubuntu, tor daemon chạy với user debian-tor và không thể đọc các file trong home directory của bạn. Vì vậy, hãy đặt directory ở nơi user đó có thể truy cập.
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_privateThêm ClientOnionAuthDir /var/lib/tor/onion_auth vào /etc/tor/torrc của client rồi reload tor. Nếu bạn chạy tor bằng user của mình, chẳng hạn bản Homebrew trên macOS, hãy trỏ ClientOnionAuthDir đến ~/.tor/onion_auth với mode 0700.
Địa chỉ trong file đó có 56 ký tự không bao gồm hậu tố .onion. Xóa /tmp/k1.prv.pem và /tmp/k1.prv.key khi hoàn tất.
Bây giờ hãy kiểm tra cả hai chiều. ssh myvps vẫn phải kết nối được. Từ một máy không có key, cùng địa chỉ đó phải kết nối thất bại. Đây là bằng chứng cho thấy cơ chế cấp quyền đã hoạt động.
Đóng cổng 22 theo thứ tự này
Trước tiên hãy đặt cơ chế an toàn. Lệnh này sẽ hoàn tác cả hai thay đổi bên dưới sau mười lăm phút nếu bạn tự khóa mình khỏi máy chủ.
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'Hủy lệnh này bằng sudo systemctl stop ssh-rescue.timer sau khi đã xác nhận route onion vẫn hoạt động.
Tiếp theo, dừng sshd lắng nghe trên địa chỉ public. Ubuntu 24.04 kích hoạt SSH thông qua socket unit, nên ListenAddress trong sshd_config bị bỏ qua: ssh.socket sở hữu listening socket, không phải sshd. Hãy kiểm tra bạn đang ở trường hợp nào.
systemctl is-enabled ssh.socketNếu lệnh đó in ra enabled, hãy chạy sudo systemctl edit ssh.socket và thêm nội dung sau.
[Socket]
ListenStream=
ListenStream=127.0.0.1:22ListenStream= rỗng sẽ xóa giá trị kế thừa từ unit do package cung cấp. Nếu bỏ dòng đó, bạn sẽ thêm một listener thứ hai nhưng vẫn giữ listener public. Đây là nguyên nhân phổ biến nhất khiến bước này thất bại mà không báo lỗi rõ ràng.
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
ss -tlnp | grep ':22'ss phải hiển thị 127.0.0.1:22 và không hiển thị gì trên 0.0.0.0:22. Nếu ssh.socket bị disable, hãy thêm ListenAddress 127.0.0.1 vào /etc/ssh/sshd_config.d/10-onion.conf, chạy sudo systemctl restart ssh, rồi kiểm tra bằng chính dòng ss. Kết quả đó là bằng chứng trong cả hai trường hợp.
Tiếp theo là firewall, cụ thể là quản lý rule ufw trên VPS thông thường. Trước tiên chạy sudo ufw status numbered và xóa rule SSH mà lệnh liệt kê.
sudo ufw status numbered
sudo ufw delete allow OpenSSH
sudo ufw default allow outgoing
sudo ufw default deny incoming
sudo ufw status verboseHãy để lưu lượng outbound được phép. Tor kết nối ra các relay trên những cổng như 443 và 9001, nên policy mặc định deny outbound sẽ ngăn Tor bootstrap và đồng thời loại bỏ cách truy cập duy nhất còn lại của bạn. Hầu hết nhà cung cấp cũng có một network firewall riêng trong control panel. Hãy đóng cổng 22 ở đó, nếu không cổng này vẫn có thể truy cập được dù ufw báo gì.
Nếu Docker chạy trên máy này, hãy kiểm tra các port đã publish trước khi kết thúc. Docker tự ghi rule vào cùng các bảng đó và publish port của container đi thẳng qua ufw, nên policy deny của ufw không phản ánh toàn bộ cấu hình.
Khởi động lại trước khi bạn tin tưởng cấu hình
systemctl is-enabled tor@default
sudo rebootNếu lệnh đầu tiên không báo service đã được enable, hãy chạy sudo systemctl enable tor@default trước khi khởi động lại. Chờ 2 phút, rồi chạy ssh myvps. Tor cần bootstrap sau khi boot, nên địa chỉ onion sẽ bắt đầu phản hồi một thời gian sau khi máy đã khởi động.
Nếu service không hoạt động trở lại, hãy mở console và đọc sudo journalctl -u tor@default -b. Lỗi cú pháp torrc hoặc vấn đề quyền trên thư mục sẽ được in ở đó. Bạn cũng có thể kiểm tra thay đổi trong torrc trước khi áp dụng.
sudo -u debian-tor tor --verify-configChi phí của cách này so với một tunnel WireGuard
So với WireGuard VPN trên VPS của bạn, onion service chậm hơn và khó dự đoán hơn. Hãy đánh giá trung thực sự đánh đổi này trước khi quyết định sử dụng.
Độ trễ. Circuit của client đi qua 3 relay và phía service thêm 3 relay nữa. Vì vậy, mỗi phím bạn gõ phải đi qua khoảng 6 máy được chọn ngẫu nhiên trên toàn thế giới. Thao tác nhập tương tác sẽ có độ trễ rõ rệt và việc copy file sẽ chậm. WireGuard chỉ thêm 1 hop. Hãy tự đo trường hợp của bạn bằng time ssh myvps 'echo ok', vì con số này phụ thuộc vào circuit mà tor vừa tạo và sẽ thay đổi khi tor tạo circuit khác.
Userspace daemon nằm trên đường đi quan trọng. WireGuard chạy trong kernel và khởi động cùng network. Tor là một process phải khởi động, bootstrap và kết nối đến một guard relay thì mọi thứ mới hoạt động. Khi nó lỗi, bạn phải dùng console của provider.
Độ chính xác của clock. Descriptor của onion service được publish theo các khoảng thời gian. Vì vậy, clock sai nhiều sẽ làm hỏng việc tra cứu địa chỉ mà không có thông báo lỗi rõ ràng ở bất kỳ đâu. timedatectl phải báo cáo System clock synchronized: yes.
Đổi lại, bạn không còn phải phụ thuộc vào việc một firewall rule có được cấu hình đúng hay không. Không có port để scan hoặc banner để lấy, và bản thân địa chỉ là một public key. Vì vậy, endpoint xác minh được danh tính trước khi SSH bắt đầu.
Câu trả lời thực tế thường là dùng cả hai. Dùng WireGuard làm đường truy cập hằng ngày và giữ onion service làm route vẫn hoạt động khi cấu hình WireGuard bị sai. Như vậy, bạn chỉ cần mở 1 UDP port thay vì public SSH port. Không cách nào trong số này thay thế cho việc hardening chính ssHd: vẫn cần xác thực chỉ dùng key và đăng nhập bằng tài khoản không phải root, vì onion service chỉ bảo vệ network path, không bảo vệ những phần bên ngoài đó.
Các tình huống lỗi và thông báo bạn sẽ thấy
Tor không bao giờ vượt qua Bootstrapped 0%. Lưu lượng outbound bị chặn hoặc đồng hồ hệ thống bị lệch nhiều. Kiểm tra policy outbound bằng sudo ufw status verbose, sau đó chạy timedatectl.
systemctl status tor báo active (exited). Đây là trạng thái bình thường trên Debian và Ubuntu. Đọc tor@default thay vào đó.
Không tìm thấy descriptor. Tor trả về lỗi mở rộng SOCKS F0, "Onion Service Descriptor Can Not be Found". Descriptor có thể chưa được publish; việc này mất một khoảng thời gian ngắn sau khi reload. Cũng có thể tor trên server chưa chạy.
F4, "Onion Service Missing Client Authorization". Client không có .auth_private tương ứng để tor sử dụng. Kiểm tra ClientOnionAuthDir có trong torrc, directory có mode 0700, filename có đuôi .auth_private và debian-tor có quyền đọc file đó.
F5, "Onion Service Wrong Client Authorization". Private key không khớp với file .auth trên server. Một = ở cuối hoặc newline thừa bên trong chuỗi base32 có thể gây ra lỗi này.
nc: invalid option -- 'X'. GNU netcat được cài đặt thay vì bản OpenBSD. Chạy sudo apt install -y netcat-openbsd.
Could not resolve hostname. ssh đã thử DNS thông thường. DNS không có câu trả lời cho .onion, nên ProxyCommand chưa bao giờ chạy. Pattern Host trong ~/.ssh/config không khớp với tên bạn đã nhập.
Permission denied (publickey). Tunnel đã hoạt động và tor đã hoàn tất phần việc của mình. Hãy xử lý đây như lỗi permission denied publickey thông thường và không quy lỗi cho tor.
FAQ
Onion service có thực sự có nghĩa là VPS không mở cổng nào không?
Có, sau khi sshd bind vào 127.0.0.1 và firewall drop lưu lượng inbound. Tor tạo kết nối TCP outbound đến một relay, rồi session của bạn đi ngược qua relay đó. Vì vậy, không có tiến trình nào trên máy chấp nhận kết nối tại địa chỉ public. Hãy xác minh bằng ss -tlnp trên server và quét cổng từ một máy khác. Đừng quên network firewall riêng của nhà cung cấp trong control panel. Đây là một lớp kiểm soát tách biệt với ufw và cũng phải được đóng.
Địa chỉ .onion có đủ bảo mật cho SSH không?
Không. Địa chỉ này dài 56 ký tự và không thể bị đoán hoặc liệt kê từ hệ thống directory, nên có tính chất như một secret. Tuy nhiên, nó vẫn có thể lộ qua shell history và các file cấu hình. Hãy bật client authorisation v3. Khi đó, service descriptor được mã hóa bằng client key của bạn. Người chỉ có địa chỉ sẽ nhận lỗi mở rộng F4 và không bao giờ đến được sshd.
Điều gì xảy ra nếu tor không khởi động sau khi reboot?
Bạn mất hoàn toàn quyền truy cập SSH vì onion address khi đó là cách duy nhất để truy cập vào máy. Vì vậy, phải kiểm tra provider console trước khi đóng port 22. Tor cũng cần thời gian bootstrap sau khi boot, nên địa chỉ sẽ phản hồi muộn hơn thời điểm máy bắt đầu trả lời ping. Nếu địa chỉ không bao giờ phản hồi, hãy đăng nhập qua console và đọc sudo journalctl -u tor@default -b. Lỗi cú pháp torrc hoặc lỗi quyền trên /var/lib/tor/ssh sẽ được ghi tại đó.
SSH qua Tor có chậm hơn WireGuard không?
Có, chậm hơn rất nhiều. Kết nối đến onion service đi qua khoảng sáu relay được chọn ngẫu nhiên, trong khi WireGuard chỉ có một encrypted hop trực tiếp đến server. Thao tác nhập lệnh sẽ có độ trễ và việc truyền file sẽ chậm. Cấu hình phổ biến là dùng WireGuard cho công việc hằng ngày, đồng thời giữ onion service làm tuyến khẩn cấp để vẫn truy cập được khi cấu hình VPN bị lỗi.