422 lines
12 KiB
Markdown
422 lines
12 KiB
Markdown
# 旁路由部署与使用教程
|
||
|
||
> 用一台 Ubuntu 机器做旁路由,实现全家翻墙 + DNS 去广告。基于 sing-box(VLESS + Reality)和 AdGuard Home。
|
||
|
||
---
|
||
|
||
## 概述
|
||
|
||
旁路由是指:不替换主路由器,而是在局域网里加一台设备(这里是一台 Ubuntu 24.04 主机),让它承担**代理翻墙**和 **DNS 去广告**两个职责。各终端设备把网关或 DNS 指向这台设备即可。
|
||
|
||
```mermaid
|
||
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 变化。
|
||
|
||
```bash
|
||
# 查看当前连接名
|
||
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"
|
||
```
|
||
|
||
- **IP**:`192.168.31.112`(根据你实际网段修改)
|
||
- **网关**:`192.168.31.1`(主路由器 IP)
|
||
- **DNS**:`127.0.0.1`(指向自己,后续由 AdGuard Home 接管)
|
||
|
||
#### 开启 IP 转发
|
||
|
||
旁路由需要转发来自其他设备的流量:
|
||
|
||
```bash
|
||
# 临时开启
|
||
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
|
||
|
||
```bash
|
||
# 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 密钥
|
||
|
||
```bash
|
||
# 在 VPS 上生成密钥对
|
||
sing-box generate reality-keypair
|
||
# 输出示例:
|
||
# PrivateKey: gDCMbKDExVbifaHQl4X7Qt94dY3G-lyXLENaAajdtV4
|
||
# PublicKey: mtRLJrO5Y364oQqYZIj6LJ5Dy9eioJdxd70NW8YNVEs
|
||
```
|
||
|
||
保留这些密钥,服务端用私钥,客户端用公钥。同时生成一个 ShortID(8 位十六进制):
|
||
|
||
```bash
|
||
openssl rand -hex 8
|
||
# 输出示例:f8a121da7c465aa8
|
||
```
|
||
|
||
#### 服务端配置
|
||
|
||
`/etc/sing-box/config.json`:
|
||
|
||
```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" }
|
||
]
|
||
}
|
||
```
|
||
|
||
启动并设为开机自启:
|
||
|
||
```bash
|
||
sudo systemctl enable --now sing-box
|
||
sudo systemctl status sing-box
|
||
```
|
||
|
||
### 1.4 步骤三:部署本机 sing-box 客户端
|
||
|
||
在旁路由上安装 sing-box,配置为客户端连接 VPS。
|
||
|
||
#### 客户端配置
|
||
|
||
`/etc/sing-box/config.json`:
|
||
|
||
```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(局域网)直连,其余走代理。这样国内网站不受影响。
|
||
|
||
启动:
|
||
|
||
```bash
|
||
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 并过滤广告。
|
||
|
||
#### 创建目录结构
|
||
|
||
```bash
|
||
mkdir -p /opt/adguard/{conf,work}
|
||
```
|
||
|
||
#### 初次启动
|
||
|
||
```bash
|
||
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 host`**:Docker 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 步骤五:各设备接入
|
||
|
||
部署完成后,各终端设备需要配置 DNS 和代理才能使用旁路由。每个平台的设置方式不同,详见各平台使用指南:
|
||
|
||
| 平台 | 文档 |
|
||
|------|------|
|
||
| 🐧 Linux | [Linux 使用指南](旁路由使用/Linux.md) |
|
||
| 🪟 Windows | [Windows 使用指南](旁路由使用/Windows.md) |
|
||
| 🍎 macOS | [macOS 使用指南](旁路由使用/macOS.md) |
|
||
| 🤖 Android | [Android 使用指南](旁路由使用/Android.md) |
|
||
| 📱 iPhone / iPad | [iPhone 使用指南](旁路由使用/iPhone.md) |
|
||
|
||
---
|
||
|
||
## 二、使用教程
|
||
|
||
### 2.1 日常管理
|
||
|
||
```bash
|
||
# 翻墙代理
|
||
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:
|
||
|
||
```bash
|
||
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 重启后恢复
|
||
|
||
正常情况下大部分服务会自动恢复。如果翻墙或去广告挂了,依次检查:
|
||
|
||
```bash
|
||
# 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 查询是否到达 AdGuard**:`docker logs adguardhome | tail -20` 查看有无查询日志
|
||
3. **设备 DNS 是否指向旁路由**:在 Windows 上 `nslookup google.com` 看返回的服务器是谁
|
||
4. **浏览器是否开了 DNS over HTTPS**:Chrome/Edge 关闭此功能
|
||
5. **路由器是否劫持了 DNS**:有些运营商/路由器会强制劫持 53 端口,设备需直接设 DNS 为旁路由 IP 绕过
|
||
|
||
#### AdGuard DNS 查询超时
|
||
|
||
症状:偶尔 DNS 查询卡住几秒才返回。原因:Docker bridge 模式下 UDP DNS 不稳定。
|
||
|
||
解决:确保使用 `--network host` 模式运行 AdGuard Home(如步骤 1.5 所示)。如果已经用 bridge 模式部署:
|
||
|
||
```bash
|
||
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` 兼容。
|