Qubes OS Tor 配置(在使用 WebTunnel 时非常有用)

场景 —— Whonix 并未提供完整的 Tor 解决方案

作为一款以安全为核心的操作系统,Qubes OS 集成了 Whonix 来支持 Tor 连接。然而,由于 lyrebird 仍未被纳入 Debian 官方仓库,Whonix 并不支持 WebTunnel 桥接。

在某些国家,obfs4 桥接无法使用,因为网络审查非常严格。此时,WebTunnel 桥接可能是唯一的选择。因此,我们可以使用最新版本的 Tor,为其他 qube 提供一个具备 Tor 接入能力的 NetVM。

第一步:为 Tor 守护进程准备一个 qube

这一步我们将创建一个用于运行 Tor 守护进程的 qube。创建一个 qube —— 本例中我们使用 fedora-41-xfce 模板创建一个名为 tor-daemon 的 StandaloneVM。启用自动启动。创建完成后打开终端。

安装 Tor:

 $ sudo dnf install tor

编译下载 lyrebird,将其放入 /usr/local/bin,然后运行:

 $ sudo chown root\:root /usr/local/bin/lyrebird
 $ sudo chmod +x /usr/local/bin/lyrebird
 $ sudo ln -s /usr/local/bin/lyrebird /usr/bin/lyrebird
 $ sudo semanage fcontext -a -t tor\_exec\_t '/usr/local/bin/lyrebird'
 $ sudo restorecon -v /usr/local/bin/lyrebird

然后配置 /etc/tor/torrc 文件。你可以添加如下内容:

UseBridges 1
ClientTransportPlugin webtunnel exec /usr/local/bin/lyrebird managed
Bridge webtunnel ...
Bridge webtunnel ...
...

注意 managed 非常关键,它确保了 systemd 可以同时启用 Tor 守护进程和 lyrebird

然后启用并启动 Tor 守护进程:

 $ sudo systemctl enable --now tor

验证运行是否正常:

 $ torsocks curl myip.wtf

如果能显示 IP 地址,说明已成功。继续下一步。

第二步:准备一个用于路由的 qube

克隆 fedora-41-xfce 模板。我使用的是这个模板,但你也可以使用 fedora-41-minimal 来节省磁盘空间 —— 不过我未验证其是否可行。这里我们将克隆命名为 fedora-41-pt

克隆后,临时将其连接到网络(例如 sys-firewall),然后打开终端并运行:

 $ sudo dnf install qubes-core-agent-networking iproute clash-meta dnscrypt-proxy torsocks
 $ sudo systemctl disable dnscrypt-proxy

然后关闭该 qube,并断开其网络连接。

使用刚刚创建的模板创建一个 AppVM,命名为 sys-tor。也为其启用自动启动。接着,在 dom0 的终端中运行:

 $ sudo -s
 # echo sys-tor @default allow,target=tor-daemon >> /etc/qubes-rpc/policy/qubes.ConnectTCP
 # exit
 $ qvm-firewall sys-tor del --rule-no 0
 $ qvm-firewall sys-tor add drop
 $ qvm-firewall sys-tor add --before 0 drop proto=icmp
 $ qvm-firewall sys-tor add --before 0 drop specialtarget=dns

然后,在 sys-tor 中打开终端。创建目录 /rw/proxy/dns/rw/proxy/clash

打开 /rw/proxy/dns/dnscrypt-proxy.toml 并添加:

listen_addresses = ['127.0.0.1:5353']
max_clients = 250
proxy = 'socks5://127.0.0.1:7891'
timeout = 5000
keepalive = 30
ignore_system_dns = true
netprobe_timeout = 0
cache = true
[static]
  [static.quad9_doh]
    stamp = 'sdns://AgMAAAAAAAAABzkuOS45LjkgKhX11qy258CQGt5Ou8dDsszUiQMrRuFkLwaTaDABJYoSZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk'
  [static.mullvad_doh]
    stamp = 'sdns://AgcAAAAAAAAAAAAPZG9oLm11bGx2YWQubmV0Ci9kbnMtcXVlcnk'

打开 /rw/proxy/clash/config.yaml 并添加:

socks-port: 7891
redir-port: 7892

mode: rule

allow-lan: true
bind-address: '*'

dns:
  enable: false

proxies:
  - name: "socks_proxy"
    type: socks5
    server: 127.0.0.1
    port: 9050

rules:
  - MATCH,socks_proxy

打开 /rw/config/rc.local 并添加:

qvm-connect-tcp 9050:@default:9050
sysctl -w net.ipv4.conf.all.route_localnet=1
nft 'add rule ip qubes custom-forward oifname "eth0" drop'
nft 'add rule ip6 qubes custom-forward oifname "eth0" drop'
nft 'add rule ip qubes custom-forward iifname "eth0" drop'
nft 'add rule ip6 qubes custom-forward iifname "eth0" drop'
nft flush chain ip qubes dnat-dns
nft 'add rule ip qubes dnat-dns ip daddr 10.139.1.1 udp dport 53 dnat to 127.0.0.1:5353'
nft 'add rule ip qubes dnat-dns ip daddr 10.139.1.1 tcp dport 53 dnat to 127.0.0.1:5353'
nft 'add rule ip qubes dnat-dns ip daddr 10.139.1.2 udp dport 53 dnat to 127.0.0.1:5353'
nft 'add rule ip qubes dnat-dns ip daddr 10.139.1.2 tcp dport 53 dnat to 127.0.0.1:5353'
nft 'add rule ip qubes custom-input iifname "vif*" tcp dport 7892 accept'
nft 'add rule ip qubes custom-input iifname "vif*" udp dport 7892 accept'
nft 'add rule ip qubes custom-input iifname "vif*" tcp dport 5353 accept'
nft 'add rule ip qubes custom-input iifname "vif*" udp dport 5353 accept'
nft 'add chain ip qubes redir { type nat hook prerouting priority -99 ; policy accept; }'
nft 'add rule ip qubes redir iifname "vif*" ip protocol udp redirect to :7892'
nft 'add rule ip qubes redir iifname "vif*" ip protocol tcp redirect to :7892'
nft 'add chain ip qubes output { type filter hook output priority filter ; policy drop; }'
nft 'add rule ip qubes output ct state related,established accept'
nft 'add rule ip qubes output oifname "lo" accept'
nft 'add rule ip qubes output ip daddr 127.0.0.1 accept'
clash-meta -d /rw/proxy/clash >/dev/null 2>&1 &
sleep 0.5
dnscrypt-proxy -config /rw/proxy/dns/dnscrypt-proxy.toml >/dev/null 2>&1 &

下载 此文件(专有许可,但实际上不会使用;我稍后会尝试用一个随机文件)到 /rw/proxy/clash/Country.mmdb

重启 sys-tor

第三步:连接到 Tor 网络

选择你希望用于连接 Tor 网络的 qube。将其 NetVM 设置为 sys-tor

打开浏览器并访问 此网站。如果页面显示 You are using Tor! —— 搞定!

如果没有,请检查配置,并参考社区支持。

如果遇到 OCSP 问题,可以临时在浏览器设置中禁用 OCSP 查询,尽管我目前没有更好的解决方法。

另外,你也可以尝试重启电脑,确保配置在重启后仍然有效。

参考资料

  1. 通过代理 qube 透明路由 qube 流量(Qubes R4.1 与 R4.2)