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

422 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 旁路由部署与使用教程
> 用一台 Ubuntu 机器做旁路由,实现全家翻墙 + DNS 去广告。基于 sing-boxVLESS + 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` 兼容。