Files
notebook/docs/技术/旁路由部署.md
T

12 KiB
Raw Blame History

旁路由部署与使用教程

用一台 Ubuntu 机器做旁路由,实现全家翻墙 + DNS 去广告。基于 sing-boxVLESS + Reality)和 AdGuard Home。


概述

旁路由是指:不替换主路由器,而是在局域网里加一台设备(这里是一台 Ubuntu 24.04 主机),让它承担代理翻墙DNS 去广告两个职责。各终端设备把网关或 DNS 指向这台设备即可。

graph TD
    subgraph 公网
        VPS["☁️ 香港 VPS<br/>sing-box 服务端<br/>VLESS + Reality"]
    end

    subgraph 局域网["🏠 家庭局域网"]
        Router["📶 主路由器<br/>192.168.31.1<br/>小米 Redmi RM2100"]
        Bypass["🖥️ 旁路由<br/>Ubuntu 24.04<br/>静态 IP"]
        PC["💻 本机 Ubuntu"]
        Win["🪟 Windows"]
        Phone["📱 手机"]

        subgraph Bypass_Internal["旁路由内部服务"]
            SB["sing-box 客户端<br/>SOCKS5 :7890"]
            AG["AdGuard Home<br/>DNS :53 | Web :8080"]
        end
    end

    VPS <--"VLESS + Reality<br/>加密隧道"--> SB
    SB --> AG
    Router --- Bypass
    PC -.->|"DNS → 旁路由"| AG
    Win -.->|"DNS + SOCKS5 → 旁路由"| AG
    Win -.->|"DNS + SOCKS5 → 旁路由"| SB
    Phone -.->|"DNS + HTTP 代理 → 旁路由"| AG
    Phone -.->|"DNS + HTTP 代理 → 旁路由"| SB
    Bypass_Internal --- Bypass

两个核心服务:

服务 作用 端口
sing-box 客户端 连接远端 VPS 建立加密隧道,提供本地代理 SOCKS5/HTTP :7890
AdGuard Home DNS 过滤,屏蔽广告和跟踪域名 DNS :53、Web 管理 :8080

一、部署教程

1.1 前置条件

  • 一台 24 小时开机的 Linux 设备(本例 Ubuntu 24.04),已接入局域网
  • 一台境外 VPS(本例香港 CentOS Stream 9
  • 一个域名(用于 Reality 伪装,本例 www.microsoft.com 作为 SNI

1.2 步骤一:配置旁路由本机网络

设置静态 IP

通过 NetworkManager 把本机 IP 固定下来,避免 DHCP 租约过期后 IP 变化。

# 查看当前连接名
nmcli con show

# 设置静态 IP(根据实际连接名和网段修改)
nmcli con mod "有线连接 1" ipv4.addresses 192.168.31.112/24
nmcli con mod "有线连接 1" ipv4.gateway 192.168.31.1
nmcli con mod "有线连接 1" ipv4.dns 127.0.0.1
nmcli con mod "有线连接 1" ipv4.method manual
nmcli con up "有线连接 1"
  • IP192.168.31.112(根据你实际网段修改)
  • 网关192.168.31.1(主路由器 IP
  • DNS127.0.0.1(指向自己,后续由 AdGuard Home 接管)

开启 IP 转发

旁路由需要转发来自其他设备的流量:

# 临时开启
sudo sysctl -w net.ipv4.ip_forward=1

# 永久开启
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-bypass.conf
sudo sysctl -p /etc/sysctl.d/99-bypass.conf

1.3 步骤二:部署 VPS 服务端

在境外 VPS 上安装并配置 sing-box 服务端。

安装 sing-box

# VPS 上执行(CentOS Stream 9 示例)
# 官方安装脚本
curl -fsSL https://sing-box.app/gpg.key | sudo gpg --dearmor -o /etc/apt/keyrings/sing-box.gpg
# 具体安装方式参见 https://sing-box.sagernet.org/installation/

生成 Reality 密钥

# 在 VPS 上生成密钥对
sing-box generate reality-keypair
# 输出示例:
# PrivateKey: gDCMbKDExVbifaHQl4X7Qt94dY3G-lyXLENaAajdtV4
# PublicKey:  mtRLJrO5Y364oQqYZIj6LJ5Dy9eioJdxd70NW8YNVEs

保留这些密钥,服务端用私钥,客户端用公钥。同时生成一个 ShortID(8 位十六进制):

openssl rand -hex 8
# 输出示例:f8a121da7c465aa8

服务端配置

/etc/sing-box/config.json

{
  "log": { "level": "info" },
  "inbounds": [
    {
      "type": "vless",
      "tag": "vless-in",
      "listen": "::",
      "listen_port": 8443,
      "users": [
        {
          "uuid": "<生成一个 UUID>",
          "flow": "xtls-rprx-vision"
        }
      ],
      "tls": {
        "enabled": true,
        "server_name": "www.microsoft.com",
        "reality": {
          "enabled": true,
          "private_key": "<VPS 上生成的私钥>",
          "short_id": ["<8 位 ShortID>"]
        }
      }
    }
  ],
  "outbounds": [
    { "type": "direct", "tag": "direct" }
  ]
}

启动并设为开机自启:

sudo systemctl enable --now sing-box
sudo systemctl status sing-box

1.4 步骤三:部署本机 sing-box 客户端

在旁路由上安装 sing-box,配置为客户端连接 VPS。

客户端配置

/etc/sing-box/config.json

{
  "log": { "level": "info" },
  "inbounds": [
    {
      "type": "mixed",
      "tag": "mixed-in",
      "listen": "::",
      "listen_port": 7890
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    },
    {
      "type": "vless",
      "tag": "proxy",
      "server": "<VPS 公网 IP>",
      "server_port": 8443,
      "uuid": "<与服务端相同的 UUID>",
      "flow": "xtls-rprx-vision",
      "tls": {
        "enabled": true,
        "server_name": "www.microsoft.com",
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
        },
        "reality": {
          "enabled": true,
          "public_key": "<VPS 生成的公钥>",
          "short_id": "<ShortID>"
        }
      }
    }
  ],
  "route": {
    "rules": [
      {
        "type": "logical",
        "mode": "and",
        "rules": [
          { "domain_suffix": [".cn"] },
          { "domain_keyword": ["cn"] }
        ],
        "outbound": "direct"
      },
      {
        "ip_is_private": true,
        "outbound": "direct"
      }
    ],
    "final": "proxy"
  }
}

路由规则说明.cn 域名和私有 IP(局域网)直连,其余走代理。这样国内网站不受影响。

启动:

sudo systemctl enable --now sing-box
sudo systemctl status sing-box

# 验证代理是否可用
curl --socks5 127.0.0.1:7890 https://www.google.com -o /dev/null -s -w '%{http_code}'
# 返回 200 或 301/302 即成功

1.5 步骤四:部署 AdGuard Home

用 Docker 启动 AdGuard Home,统一管理局域网 DNS 并过滤广告。

创建目录结构

mkdir -p /opt/adguard/{conf,work}

初次启动

docker run -d \
  --name adguardhome \
  --restart unless-stopped \
  --network host \
  -v /opt/adguard/conf:/opt/adguardhome/conf \
  -v /opt/adguard/work:/opt/adguardhome/work \
  adguard/adguardhome

为什么用 --network hostDocker bridge 模式下 UDP 53 端口偶发超时,host 模式直接使用宿主机网络栈,DNS 查询更稳定。

初始配置

浏览器打开 http://<旁路由IP>:8080,按向导完成初始化:

  1. Web 管理端口8080
  2. DNS 监听端口53(所有网络接口)
  3. 设置管理员账号(牢记)

添加过滤规则

进入 过滤器 → DNS 过滤清单,推荐添加:

规则 数量 用途
AdGuard DNS filter ~16 万 综合广告过滤
AdAway Default Blocklist ~6,500 移动端广告
Malicious URL Blocklist ~1.7 万 恶意网站
Peter Lowe's Blocklist ~8.1 万 通用跟踪器
AdRules DNS Filter ~18.5 万 中国广告专项

DNS 上游设置

设置 → DNS 设置 → 上游 DNS 服务器,建议配置多个:

223.5.5.5
119.29.29.29
https://dns.quad9.net/dns-query

1.6 步骤五:各设备接入

Ubuntu 本机

系统设置 → 网络代理 → 手动:

  • SOCKS5 代理:127.0.0.1:7890
  • DNS:系统会自动使用 AdGuard(因为旁路由 DNS 设为 127.0.0.1

Windows

  • DNS:网络设置 → IPv4 → DNS 手动设为旁路由 IP(如 192.168.31.112),备用 223.5.5.5
  • 代理:需要翻墙时开系统代理 SOCKS5 旁路由IP:7890
  • 重要Chrome/Edge 设置 → 关闭「使用安全 DNS」(DNS over HTTPS),否则会绕过 AdGuard

手机(连 WiFi 时)

  • DNS:WiFi 设置 → IP 设为静态 → DNS 填旁路由 IP
  • 代理WiFi 设置 → HTTP 代理 → 手动 → 服务器 旁路由IP,端口 7890

手机(出门 4G/5G

需要使用客户端 App 直连 VPS

  • ShadowrocketiOS,美区 $2.99
  • Hiddify Next(免费,iOS/Android 都支持)

配置:VLESS + Reality,参数与 VPS 服务端一致。


二、使用教程

2.1 日常管理

# 翻墙代理
sudo systemctl restart sing-box     # 重启
sudo systemctl status sing-box      # 查看状态
sudo journalctl -u sing-box -f      # 实时日志

# 去广告 DNS
docker restart adguardhome          # 重启
docker logs adguardhome -f           # 实时日志
docker ps | grep adguardhome         # 是否在运行

# VPS 服务端
ssh -p <SSH端口> root@<VPS IP> 'systemctl status sing-box'

2.2 添加自定义广告域名

当你遇到漏网的广告域名,可以用脚本快速添加到 AdGuard Home

sudo python3 << 'PYEOF'
import yaml

DOMAIN = '||新域名.com^'   # 修改为实际域名

with open('/opt/adguard/conf/AdGuardHome.yaml') as f:
    cfg = yaml.safe_load(f)

if 'user_rules' not in cfg:
    cfg['user_rules'] = []
cfg['user_rules'].append(DOMAIN)

with open('/opt/adguard/conf/AdGuardHome.yaml', 'w') as f:
    yaml.dump(cfg, f, default_flow_style=False)

print(f'已添加规则:{DOMAIN}')
PYEOF

docker restart adguardhome

2.3 重启后恢复

正常情况下大部分服务会自动恢复。如果翻墙或去广告挂了,依次检查:

# 1. 检查本机两个服务
sudo systemctl status sing-box
docker ps | grep adguardhome

# 2. 检查 VPS 服务端是否在线
ssh -p <SSH端口> root@<VPS IP> 'systemctl status sing-box'

# 3. 检查本机 IP 是否还是静态 IP(没有被 DHCP 覆盖)
ip addr show | grep 192.168

2.4 常见问题排查

翻墙不通

  1. sing-box 是否在运行sudo systemctl status sing-box
  2. VPS 是否可达ssh -p <SSH端口> root@<VPS IP> 尝试连接
  3. 本地代理端口是否监听ss -tlnp | grep 7890
  4. 测试代理是否可用curl --socks5 127.0.0.1:7890 https://www.google.com -o /dev/null -s -w '%{http_code}'
  5. VPS 防火墙:确认 8443 端口已在安全组/防火墙放行

去广告不生效

  1. AdGuard 容器是否运行docker ps | grep adguardhome
  2. DNS 查询是否到达 AdGuarddocker logs adguardhome | tail -20 查看有无查询日志
  3. 设备 DNS 是否指向旁路由:在 Windows 上 nslookup google.com 看返回的服务器是谁
  4. 浏览器是否开了 DNS over HTTPSChrome/Edge 关闭此功能
  5. 路由器是否劫持了 DNS:有些运营商/路由器会强制劫持 53 端口,设备需直接设 DNS 为旁路由 IP 绕过

AdGuard DNS 查询超时

症状:偶尔 DNS 查询卡住几秒才返回。原因:Docker bridge 模式下 UDP DNS 不稳定。

解决:确保使用 --network host 模式运行 AdGuard Home(如步骤 1.5 所示)。如果已经用 bridge 模式部署:

docker stop adguardhome
docker rm adguardhome
# 重新用 --network host 模式启动(见步骤 1.5)

三、架构决策记录

这里记录几个踩坑经验,避免后人重复:

为什么不用 TProxy 透明代理

TProxy 可以让局域网设备无需手动配代理就能翻墙,但在本环境中与 Docker 网络有冲突(回包路由异常)。结论:用 SOCKS5/HTTP 手动代理,虽然多一步设置,但稳定可靠。

为什么不用路由器改 DNS

小米路由器 + 电信大内网环境下,运营商会强制劫持所有出站 53 端口流量。即使路由器 WAN 口改了 DNS,实际查询仍被运营商接管。结论:各终端设备手动设 DNS 为旁路由 IP,直接绕过路由器 DNS 转发。

Sing-box 废弃字段兼容

当前配置使用了 sing-box 旧版 DNS 和 inbound 格式。如果 sing-box 升级到 1.14+,需要迁移到新格式,或设置环境变量 ENABLE_DEPRECATED_LEGACY_DNS_SERVERS=true 兼容。