# qBittorrent 透明代理 + BT 入站转发配置文档 ## 架构总览 ``` 出站(透明代理) qBittorrent(192.168.1.200) 互联网 ↓ nftables TPROXY 劫持 ↑ ↓ mihomo:7893 │ ↓ SRC-IP-CIDR → PT-BT → Beijing-Direct │ ↓ Reality(VLESS, SNI=news.apple.com) │ ↓ 北京VPS:443 → Nginx分流 │ ↓ proxy_from_lan:9445 → direct(freedom) ─────────────────┘ 入站(端口转发) Peer → 北京VPS:51413 → external_qbit → portal → bridge隧道 → 旁路由 → to_qbit → 192.168.1.200:51413 ``` --- ## 设备清单 | 设备 | IP | 角色 | |---|---|---| | 北京VPS | `salmonstill.cn` / `49.232.242.90` | 公网出口 + 入站入口 | | 旁路由 | `192.168.1.199` | TPROXY 透明代理 + Xray 桥接 | | NAS | `192.168.1.188` | Docker 宿主机 | | qBittorrent 容器 | `192.168.1.200` | macvlan 独立 IP,PT 专用 | --- ## 第一部分:北京 VPS 配置 ### 1.1 Nginx Stream SNI 分流 `beijing-vps-stream.conf` 新增 `news.apple.com` SNI 映射(用于旁路由 Mihomo 直连代理): ```nginx stream { map $ssl_preread_server_name $backend { www.apple.com xray; # 旁路由反向代理隧道 www.microsoft.com mihomo; # 外部客户端代理 → 东京出口 news.apple.com xray_lan; # 旁路由 Mihomo 北京直连代理 drive.salmonstill.cn nas; # 绿联云服务 default npm; # Nginx Proxy Manager } upstream xray { server 127.0.0.1:9443; } upstream mihomo { server 127.0.0.1:9444; } upstream xray_lan { server 127.0.0.1:9445; } # 新增 upstream nas { server 127.0.0.1:38653; } upstream npm { server 127.0.0.1:8443; } server { listen 443 reuseport; listen [::]:443 reuseport; ssl_preread on; proxy_pass $backend; } } ``` ### 1.2 Xray 配置 `xray-北京vps-config.json` #### 新增入站 `proxy_from_lan`(北京直连出口) ```json { "tag": "proxy_from_lan", "listen": "127.0.0.1", "port": 9445, "protocol": "vless", "settings": { "clients": [ { "id": "113e167a-a2be-4b46-9010-60020108626c", "flow": "xtls-rprx-vision" } ], "decryption": "none" }, "streamSettings": { "network": "raw", "security": "reality", "realitySettings": { "show": false, "target": "www.apple.com:443", "serverNames": ["news.apple.com"], "privateKey": "GGT9LfN_2JdQG68cwrULgUK-adfT6wIokLzWjaB0fXs", "shortIds": ["7c947a71b94f369e"] } } } ``` > Reality 公私钥复用已有的 `interconn` 入站 keypair,`serverNames` 用新的 `news.apple.com` 与 Nginx 对应。 > `target` 设为 `www.apple.com:443`,Reality 从此地址偷取真实 TLS 证书用于伪装。 #### 新增入站 `external_qbit`(BT 入站端口) ```json { "tag": "external_qbit", "listen": "0.0.0.0", "port": 51413, "protocol": "dokodemo-door", "settings": { "address": "127.0.0.1", "port": 51413, "network": "tcp" } } ``` > 仅 TCP——Xray portal 反向代理对 UDP 支持不完善,BT 的 μTP(UDP) 走不了,需要在 qBittorrent 里关闭。 #### 新增路由规则 ```json { "type": "field", "inboundTag": ["proxy_from_lan"], "outboundTag": "direct" }, { "type": "field", "inboundTag": ["external_qbit"], "outboundTag": "portal" } ``` ### 1.3 腾讯云防火墙 新开端口: | 端口 | 协议 | 用途 | |---|---|---| | 51413 | TCP | BT 入站 | --- ## 第二部分:旁路由 Mihomo 透明代理 ### 2.1 配置 `旁路由的mihomo config.yaml` #### 关键设置 ```yaml # TPROXY 透明代理入口(替代 TUN 模式) tproxy-port: 7893 ``` #### 北京直连代理节点 ```yaml proxies: - name: Beijing-Direct type: vless server: salmonstill.cn port: 443 uuid: "113e167a-a2be-4b46-9010-60020108626c" udp: true flow: xtls-rprx-vision packet-encoding: xudp tls: true servername: news.apple.com skip-cert-verify: true # Reality 下必须跳过证书 SAN 校验 client-fingerprint: chrome reality-opts: public-key: "62y5gDjPrdeuePGl-D2IW4C9wKb8_bSBBTmArvL7Nhs" short-id: "7c947a71b94f369e" network: tcp ``` > `skip-cert-verify: true` 必须加——Reality 返回的是 `www.apple.com` 的证书(来自 target),但 SNI 是 `news.apple.com`,Mihomo 的 TLS 验证会因为 SAN 不匹配而拒绝。 #### PT-BT 策略组 ```yaml proxy-groups: - name: PT-BT type: select proxies: [Beijing-Direct, 直连] ``` #### qBittorrent 透明代理规则 ```yaml rules: # 防死循环:北京 VPS 和东京 VPS 的 IP 必须直连 - IP-CIDR,49.232.242.90/32,直连 - IP-CIDR,43.165.178.10/32,直连 # ... 其他防死循环规则 ... - SRC-IP-CIDR,192.168.1.200/32,PT-BT,no-resolve # qBittorrent 全部流量走代理 ``` > `SRC-IP-CIDR` 匹配**来源 IP**,不是目的 IP。所有从 192.168.1.200 发出的流量都会被 PT-BT 策略组接管。 > `no-resolve` 防止 DNS 解析阶段误触发。 --- ## 第三部分:旁路由 nftables TPROXY 规则 ### 3.1 规则文件 `/etc/nftables.d/50-mihomo-tproxy.nft` ```nft #!/usr/sbin/nft -f table inet mihomo_tproxy { chain prerouting { type filter hook prerouting priority mangle; policy accept; # 不劫持本地/私有地址 ip daddr 127.0.0.0/8 return ip daddr 10.0.0.0/8 return ip daddr 172.16.0.0/12 return ip daddr 192.168.0.0/16 return ip daddr 224.0.0.0/4 return # 不劫持到北京/东京 VPS 的流量(防死循环) ip daddr 49.232.242.90 return ip daddr 43.165.178.10 return # 劫持 192.168.1.200 的全部流量到 TPROXY ip saddr 192.168.1.200 meta mark set 1 tproxy to :7893 accept } } ``` > ImmortalWrt 使用 fw4(nftables),放在 `/etc/nftables.d/` 下会被自动加载。 ### 3.2 策略路由 `/etc/rc.local` ```bash # 让被 fwmark=1 标记的包走本地回环(TPROXY 要求) ip rule add fwmark 1 table 100 2>/dev/null ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null # 加载 nftables 规则(如果 fw4 reload 没自动加载) sleep 5 nft add table inet mihomo_tproxy 2>/dev/null nft -f /etc/nftables.d/50-mihomo-tproxy.nft exit 0 ``` ### 3.3 验证 TPROXY ```bash # 确认 nftables 规则 nft list chain inet mihomo_tproxy prerouting | grep 192.168 # 确认策略路由 ip rule show | grep "fwmark 1" # 确认端口监听 ss -tlnp | grep 7893 ``` --- ## 第四部分:旁路由 Xray 51413 转发 ### 4.1 配置 `xray-旁路由-config.json` #### 新增加出站 `to_qbit` ```json { "tag": "to_qbit", "protocol": "freedom", "settings": { "redirect": "192.168.1.200:51413" } } ``` #### 新增路由规则 ```json { "type": "field", "inboundTag": ["bridge"], "port": "51413", "outboundTag": "to_qbit" } ``` > 放在 bridge 下——从北京 VPS 的 portal 通过反向隧道过来的 BT 入站流量,由 bridge 接收后按端口 51413 匹配到此规则,转发到 qBittorrent 容器。 --- ## 第五部分:NAS qBittorrent Docker ### 5.1 创建 macvlan 网络 ```bash docker network create -d macvlan \ --subnet=192.168.1.0/24 \ --gateway=192.168.1.199 \ --ip-range=192.168.1.200/32 \ -o parent=eth0 \ qbit_macvlan ``` > `--gateway=192.168.1.199`:qBittorrent 的默认网关设为旁路由,确保流量经过 TPROXY。 > `--ip-range=192.168.1.200/32`:固定 IP,对应 nftables 劫持规则。 ### 5.2 启动容器 ```bash docker run -d \ --name qbittorrent \ --network qbit_macvlan \ --ip 192.168.1.200 \ -e WEBUI_PORT=8090 \ -p 8090:8090 \ -v /path/to/downloads:/downloads \ lscr.io/linuxserver/qbittorrent:latest ``` ### 5.3 qBittorrent 设置 | 设置项 | 值 | |---|---| | 监听端口 | `51413` | | UPnP/NAT-PMP | **禁用** | | SOCKS5 代理 | **清空(不使用)** | | 连接协议 | **仅 TCP**(关闭 μTP) | | DHT | 可选(建议开) | | PEX | 可选(建议开) | > 关闭 μTP(UDP):Xray portal 反向代理不支持 UDP,BT 的 μTP 走 UDP 会导致入站失败。 ### 5.4 定时做种调度(crontab) 让 qBittorrent 只在夜间(01:00-07:00)做种,白天暂停以节省带宽: ```bash crontab -e ``` 添加以下两行(在 NAS 或任意可访问 192.168.1.200 的设备上): ``` 0 1 * * * curl -s -X POST "http://192.168.1.200:8888/api/v2/torrents/start" --data "hashes=all" 0 7 * * * curl -s -X POST "http://192.168.1.200:8888/api/v2/torrents/stop" --data "hashes=all" ``` | 时间 | 操作 | 含义 | |---|---|---| | 凌晨 01:00 | `/torrents/start` `hashes=all` | 启动全部种子开始做种 | | 早上 07:00 | `/torrents/stop` `hashes=all` | 停止全部种子 | --- ## 第六部分:部署顺序 ``` 1. 腾讯云防火墙 → 开放 51413/tcp 2. scp beijing-vps-stream.conf → 北京VPS /etc/nginx/stream.conf.d/ 3. scp xray-北京vps-config.json → 北京VPS /usr/local/etc/xray/config.json 4. 北京VPS: nginx -t && systemctl reload nginx 5. 北京VPS: systemctl restart xray 6. scp 旁路由的mihomo config.yaml → 旁路由 /opt/mihomo/config.yaml 7. scp xray-旁路由-config.json → 旁路由 /etc/xray/config.json 8. 旁路由: 创建 nftables 规则文件 + rc.local 策略路由 9. 旁路由: /etc/init.d/mihomo restart 10. 旁路由: /etc/init.d/xray restart 11. 旁路由: fw4 reload 或 nft -f /etc/nftables.d/50-mihomo-tproxy.nft 12. NAS: 创建 macvlan 网络 + 启动 qBittorrent 容器 13. NAS: 配置 qBittorrent 监听端口 51413,关闭 μTP ``` --- ## 第七部分:验证 ### 7.1 TPROXY 透明代理出站 ```bash # 在 NAS 上执行,应返回北京 VPS 的公网 IP docker exec qbittorrent curl https://ip.sb # 确认不是东京 VPS 的 IP docker exec qbittorrent curl https://ifconfig.io ``` ### 7.2 Mihomo 面板查看 浏览器打开 `http://192.168.1.199:9090` → 连接 → 应能看到大量通过 `Beijing-Direct` 的连接。 ### 7.3 BT 入站验证 ```bash # 北京 VPS 上确认端口监听 ss -tlnp | grep 51413 # 从外部测试端口可达 nc -zv salmonstill.cn 51413 ``` ### 7.4 端到端 BT 测试 下载一个热门 Ubuntu torrent 种子,观察: - qBittorrent WebUI → 连接 → 应显示 DHT 节点数增长 - 跟踪器页面 → 应显示 "Working" - 下载速度应有上传来确认入站工作 --- ## 第八部分:故障排查 | 现象 | 排查 | |---|---| | qBittorrent curl ip.sb 返回真实 IP | nftables 规则未生效,检查 `nft list chain inet mihomo_tproxy prerouting` | | Beijing-Direct 连不上 | 确认 `servername: news.apple.com` + `skip-cert-verify: true` | | 入站无上传 | 检查北京 VPS ufw/腾讯云安全组已放行 51413/tcp | | xray 报错 `reverse-proxy.xray.internal` | portal/bridge 域名不匹配,两边必须一致 | | 旁路由自身网络异常 | nftables 规则漏了 `ip daddr 192.168.0.0/16 return`,检查私有地址排除 | | 下载有速度、无上传 | μTP 没关或 portal UDP 不支持,qBittorrent 设置仅 TCP | --- ## 第九部分:文件清单 | 文件 | 位置 | 作用 | |---|---|---| | `beijing-vps-stream.conf` | 北京VPS `/etc/nginx/stream.conf.d/` | Nginx SNI分流(含 news.apple.com → 9445) | | `xray-北京vps-config.json` | 北京VPS `/usr/local/etc/xray/config.json` | Xray 入站+路由(含 proxy_from_lan + external_qbit) | | `旁路由的mihomo config.yaml` | 旁路由 `/opt/mihomo/config.yaml` | Mihomo TPROXY + Beijing-Direct + PT-BT 规则 | | `xray-旁路由-config.json` | 旁路由 `/etc/xray/config.json` | Xray bridge + to_qbit(51413) + socks-lan(1080) | | `/etc/nftables.d/50-mihomo-tproxy.nft` | 旁路由 | nftables TPROXY 劫持规则 | | `/etc/rc.local` | 旁路由 | 策略路由 + nft 加载(持久化) |