使用 sshuttle 經 SSH 遠端出口上網 (TCP/DNS代理)

sshuttle 可透過既有 SSH 連線攔截本機 TCP 與 DNS 流量,再由遠端主機對外連線。它的使用體驗接近 VPN,但不是傳統的 TUN/TAP VPN。

前置條件

  • 本機已安裝 sshuttle,並可使用 SSH 登入遠端主機。
  • 遠端主機具備正常的互聯網連線與 Python 環境。

啟動 sshuttle

sudo sshuttle \
  -r root@%%HOST%% \
  --dns \
  0.0.0.0/0 \
  ::/0

參數說明:

  • -e:指定底層使用的 SSH 命令與設定檔。
  • -r root@%%HOST%%:使用 SSH 設定中的 %%HOST%% 作為遠端出口。
  • --dns:一併轉送 DNS 查詢,減少 DNS 洩漏。
  • 0.0.0.0/0:代理所有 IPv4 目的網段。
  • ::/0:嘗試代理所有 IPv6 目的網段;實際支援取決於本機防火牆方法與遠端 IPv6 連線能力。
  • -v:顯示詳細的代理過程。

## 執行後終端機需保持開啟,按 Ctrl+C 即可停止。若 SSH 使用非預設使用者,請將 root 改成實際帳戶。

=== 本機 Chrome 設定 ===

1. 關閉安全 DNS(Secure DNS)

Chrome 的 DoH 查詢可能不使用系統 DNS,造成 DNS 流量未按預期經由 sshuttle。開啟以下頁面:

chrome://settings/security

找到「使用安全 DNS」,將其關閉。若只切換成「使用目前的服務供應商」,仍需實際確認 DNS 查詢是否經由系統解析器。

2. 停用 QUIC

QUIC 使用 UDP,而 sshuttle 主要代理 TCP;Chrome 可能因此繞過代理路徑。開啟:

chrome://flags/#enable-quic

將「Experimental QUIC protocol」設為 Disabled,再按「Relaunch」重新啟動 Chrome。新版 Chrome 若已移除此旗標,可改用管理政策停用 QUIC,或以瀏覽器開發者工具確認連線協定未使用 h3。

=== 遠端伺服器設定: IPv6 優先網路下的處理 ===

部分 4G/5G 網路會優先使用 IPv6。若遠端出口沒有可用的 IPv6,而應用程式取得 AAAA 記錄後優先連線,可能出現流量路徑不一致導致被Block/測出真實IP。

應先保留命令中的 ::/0,並確認遠端是否能連上 IPv6:

# 在遠端伺服器測試
curl -6 https://ifconfig.co
curl -4 https://ifconfig.co

若遠端完全沒有 IPv6,建議在遠端環境中讓 DNS 不回傳 AAAA 記錄,迫使用戶端選擇 IPv4。

使用 dnsmasq 過濾 AAAA 記錄(可選)

sudo apt update
sudo apt install -y dnsmasq

sudo vim /etc/dnsmasq.conf

加入:

filter-AAAA
server=1.1.1.1

檢查 53 埠是否已由 systemd-resolved 或其他 DNS 服務佔用:

sudo ss -lntup | grep ':53'
sudo dnsmasq --test

由 dnsmasq 接管本機 53 埠,停用 systemd-resolved。

sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
sudo systemctl restart dnsmasq

# 驗證 dnsmasq 正常回應,且未返回 AAAA 記錄
dig @127.0.0.1 example.com A
dig @127.0.0.1 example.com AAAA

限制:過濾 AAAA 後,僅提供 IPv6、沒有 A 記錄的網站將無法存取。若需要完整的 IPv6-to-IPv4 轉換,應部署 NAT64/DNS64,而不是使用 filter-AAAA。

驗證出口與 DNS

# 檢查 IPv4 出口 IP
curl -4 https://ifconfig.co

# 檢查 IPv6 是否可用及其出口
curl -6 https://ifconfig.co

# 查看目前 DNS 回應
dig example.com A
dig example.com AAAA

若 IPv4 出口顯示遠端伺服器的公網 IP,且瀏覽器不再使用 QUIC/外部 DoH,即表示主要流量已按預期經由 SSH 遠端出口。

=== 遠端伺服器開啟 IP Forwarding? ===

標準 sshuttle 模式不需要。遠端的 Python 程序會替每條 TCP 連線建立正常的對外 socket,因此不依賴 Linux 路由轉送,也不需要加入 POSTROUTING MASQUERADE。

以下設定屬於傳統路由器或 TUN/TAP VPN 閘道配置,如果不生效可以嘗試:

# 標準 sshuttle 不需要執行
sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

這些命令會修改主機的全域轉送與防火牆狀態,而且重啟後未必保留。

留言