Files
server/qbittorrent流量转发.md
T

12 KiB
Raw Blame History

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 独立 IPPT 专用

第一部分:北京 VPS 配置

1.1 Nginx Stream SNI 分流 beijing-vps-stream.conf

新增 news.apple.com SNI 映射(用于旁路由 Mihomo 直连代理):

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(北京直连出口)

{
  "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 入站 keypairserverNames 用新的 news.apple.com 与 Nginx 对应。 target 设为 www.apple.com:443,Reality 从此地址偷取真实 TLS 证书用于伪装。

新增入站 external_qbitBT 入站端口)

{
  "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 里关闭。

新增路由规则

{ "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

关键设置

# TPROXY 透明代理入口(替代 TUN 模式)
tproxy-port: 7893

北京直连代理节点

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.comMihomo 的 TLS 验证会因为 SAN 不匹配而拒绝。

PT-BT 策略组

proxy-groups:
  - name: PT-BT
    type: select
    proxies: [Beijing-Direct, 直连]

qBittorrent 透明代理规则

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

#!/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 使用 fw4nftables),放在 /etc/nftables.d/ 下会被自动加载。

3.2 策略路由 /etc/rc.local

# 让被 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

# 确认 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

{
  "tag": "to_qbit",
  "protocol": "freedom",
  "settings": {
    "redirect": "192.168.1.200:51413"
  }
}

新增路由规则

{
  "type": "field",
  "inboundTag": ["bridge"],
  "port": "51413",
  "outboundTag": "to_qbit"
}

放在 bridge 下——从北京 VPS 的 portal 通过反向隧道过来的 BT 入站流量,由 bridge 接收后按端口 51413 匹配到此规则,转发到 qBittorrent 容器。


第五部分:NAS qBittorrent Docker

5.1 创建 macvlan 网络

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.199qBittorrent 的默认网关设为旁路由,确保流量经过 TPROXY。 --ip-range=192.168.1.200/32:固定 IP,对应 nftables 劫持规则。

5.2 启动容器

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 反向代理不支持 UDPBT 的 μTP 走 UDP 会导致入站失败。

5.4 定时做种调度(crontab

让 qBittorrent 只在夜间(01:00-07:00)做种,白天暂停以节省带宽:

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 透明代理出站

# 在 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 入站验证

# 北京 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 加载(持久化)