前言
本文记录了将一台搭载Debian系统的R2S设备配置为高性能旁路网关的过程。最终目标是实现一个可以为局域网内所有设备提供WireGuard VPN服务的透明网关,同时支持IPv4和IPv6,并具备智能DNS分流功能。
最终方案的核心组件包括:
- Debian 12: 作为主操作系统。
- WireGuard: 用于建立VPN连接。
- uog: 一个流量混淆工具,用于将WireGuard的UDP流量伪装成其他协议(本文为HTTPS),以适应复杂的网络环境。
- dnsproxy: AdGuard出品的高性能DNS代理,用于实现DNS-over-HTTPS (DoH)以及基于域名的DNS分流。
- iptables/ip6tables: 用于配置网络地址转换(NAT),实现VPN共享。
准备工作
1. 安装系统与基础软件
首先,为R2S安装最新版本的Debian系统。您可以从FriendlyELEC的官方Wiki获取镜像和相关说明:
- 官方镜像下载: NanoPi R2S - Official Image
- Debian系统使用指南: NanoPi R2S - Work with Debian Core
安装过程略过,系统启动后,请执行以下操作:
# 更新系统并安装必要工具
sudo apt update && sudo apt upgrade -y
sudo apt install -y zsh wireguard-tools dnsutils
# (可选) 更换为您喜欢的shell
chsh -s /bin/zsh
2. 启用IP转发
作为旁路网关,设备需要能够转发网络包。编辑 /etc/sysctl.conf 文件:
sudo vim /etc/sysctl.conf
找到并取消以下两行的注释(如果它们被注释了的话),确保值为 1:
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
保存文件后,应用设置:
sudo sysctl -p
核心服务配置
我们将使用 systemd 来管理 dnsproxy 和 uog 这两个核心服务,以确保它们能开机自启并保持稳定运行。建议将二进制文件存放在 /home/pi/bin 目录下。
mkdir -p /home/pi/bin
1. 配置 dnsproxy
dnsproxy 负责处理所有DNS请求。它的关键任务是:
- 将用于
uog连接的特定域名解析请求,转发给主路由,避免DNS污染和路由循环。 - 将其余所有DNS请求通过DoH发送,保护隐私。
下载 dnsproxy:
从 dnsproxy的GitHub Releases页面 下载最新的 linux-arm64 版本,解压后将 dnsproxy 二进制文件放入 /home/pi/bin。
创建 systemd 服务:
创建 /etc/systemd/system/dnsproxy.service 文件:
sudo vim /etc/systemd/system/dnsproxy.service
写入以下内容:
[Unit]
Description=dnsproxy
After=network-online.target network.target
Wants=network-online.target
[Service]
Restart=always
ExecStart=/home/pi/bin/dnsproxy -u "[/*.your_domain.com/]192.168.31.1:53" -u https://dns0.eu/dns-query -u https://open.dns0.eu/dns-query --http3 --cache --cache-min-ttl=600 --edns --edns-addr=<your_public_ip_for_cdn>
ExecReload=/bin/kill $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=5s
PrivateTmp=true
PrivateDevices=true
ProtectHome=false
ProtectSystem=full
[Install]
WantedBy=multi-user.target
配置说明:
- 请将
your_domain.com替换为您uog服务实际使用的域名。 192.168.31.1是我局域网的主路由地址,请根据您的实际情况修改。<your_public_ip_for_cdn>是一个用于优化CDN解析的公网IP地址,您可以填写一个您所在地区的IP,或者直接移除--edns和--edns-addr参数。
启动 dnsproxy:
sudo systemctl daemon-reload
sudo systemctl enable dnsproxy --now
2. 配置 uog
uog 负责将WireGuard的流量伪装后转发到真实的VPN服务器。
下载 uog:
从 uog的GitHub Releases页面 下载最新的 linux-arm64 版本,将 uog 二进制文件放入 /home/pi/bin。
创建启动脚本:
为了方便管理,我们创建一个包装脚本 /home/pi/uog.sh:
vim /home/pi/uog.sh
内容如下:
#!/bin/bash
/home/pi/bin/uog 0.0.0.0:2928 https://uog.your_domain.com:443 <your_password>
0.0.0.0:2928:uog的本地监听地址和端口,WireGuard将连接到这里。https://uog.your_domain.com:443:uog远端服务器的地址,请替换为您的实际地址。<your_password>: 连接密码。
给脚本添加执行权限:
chmod +x /home/pi/uog.sh
创建 systemd 服务:
创建 /etc/systemd/system/uog.service 文件:
sudo vim /etc/systemd/system/uog.service
写入以下内容:
[Unit]
Description=uog client
After=network-online.target network.target
Wants=network-online.target
[Service]
Restart=always
ExecStart=/home/pi/uog.sh
ExecReload=/bin/kill $MAINPID
KillMode=mixed
KillSignal=SIGTERM
TimeoutStopSec=5s
PrivateTmp=true
PrivateDevices=true
ProtectHome=false
ProtectSystem=full
[Install]
WantedBy=multi-user.target
启动 uog:
sudo systemctl daemon-reload
sudo systemctl enable uog --now
配置 WireGuard
这是所有配置的核心,它将所有组件串联起来。
1. 创建动态路由脚本
为了防止 uog 的流量被WireGuard错误地捕获,我们需要在WireGuard启动时,动态地为 uog 服务器的IP添加一条静态路由,让它直连主路由。
创建目录:
mkdir -p /home/pi/wg
创建 wgup.sh 脚本:
vim /home/pi/wg/wgup.sh
#!/bin/bash
STATE_FILE="/home/pi/wg/uog_server.ip"
DEST_IP=$(host -t A uog.your_domain.com | awk '/has address/ {print $4}')
if [ -n "$DEST_IP" ]; then
# 为 uog 服务器 IP 添加静态路由,强制经由主路由
ip route add $DEST_IP/32 via 192.168.31.1 dev eth0
echo "$DEST_IP" > "$STATE_FILE"
echo "Route added for uog.your_domain.com -> $DEST_IP"
fi
创建 wgdown.sh 脚本:
vim /home/pi/wg/wgdown.sh
#!/bin/bash
STATE_FILE="/home/pi/wg/uog_server.ip"
if [ -f "$STATE_FILE" ]; then
DEST_IP=$(cat "$STATE_FILE")
# 删除对应的静态路由
ip route del $DEST_IP/32 via 192.168.31.1 dev eth0
rm "$STATE_FILE"
echo "Route removed for uog.your_domain.com -> $DEST_IP"
fi
给脚本添加执行权限:
chmod +x /home/pi/wg/wgup.sh /home/pi/wg/wgdown.sh
记得将脚本中的 uog.your_domain.com 和 192.168.31.1 替换为您的配置。
2. 编写 wg0.conf
创建 /etc/wireguard/wg0.conf 文件:
sudo vim /etc/wireguard/wg0.conf
写入以下配置:
[Interface]
PrivateKey = <your_wireguard_private_key>
Address = 192.168.9.2/24, fd00:9:28::28/128
DNS = 192.168.9.2
MTU = 1280
# IPv4 NAT and Forwarding Rules
PostUp = iptables -A FORWARD -i eth0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostDown = iptables -D FORWARD -i eth0 -j ACCEPT; iptables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
# IPv6 NAT and Forwarding Rules
PostUp = ip6tables -A FORWARD -i eth0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostDown = ip6tables -D FORWARD -i eth0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o wg0 -j MASQUERADE
# Dynamic route for uog server
PostUp = /home/pi/wg/wgup.sh
PostDown = /home/pi/wg/wgdown.sh
# (Optional) Add static routes for IPs that should bypass the VPN
# PostUp = ip route add 114.114.114.114/32 via 192.168.31.1 dev eth0
# PostDown = ip route del 114.114.114.114/32 via 192.168.31.1 dev eth0
[Peer]
PublicKey = <your_wireguard_server_public_key>
AllowedIPs = ::/0, 0.0.0.0/5, 8.0.0.0/7, 11.0.0.0/8, 12.0.0.0/6, 16.0.0.0/4, 32.0.0.0/3, 64.0.0.0/2, 128.0.0.0/3, 160.0.0.0/5, 168.0.0.0/6, 172.0.0.0/12, 172.32.0.0/11, 172.64.0.0/10, 172.128.0.0/9, 173.0.0.0/8, 174.0.0.0/7, 176.0.0.0/4, 192.0.0.0/9, 192.128.0.0/11, 192.160.0.0/13, 192.169.0.0/16, 192.170.0.0/15, 192.172.0.0/14, 192.176.0.0/12, 192.192.0.0/10, 193.0.0.0/8, 194.0.0.0/7, 196.0.0.0/6, 200.0.0.0/5, 208.0.0.0/4, 192.168.9.0/24
Endpoint = 127.0.0.1:2928
PersistentKeepalive = 25
配置说明:
PrivateKey和PublicKey: 替换为您自己的密钥。Address: R2S在VPN网络中的地址,192.168.9.2也是它作为DNS服务器的地址。DNS: 将DNS指向设备自身,由dnsproxy提供服务。PostUp/PostDown: 核心部分,负责添加/删除防火墙NAT规则和执行动态路由脚本。eth0是我的R2S的LAN口,请根据您的设备接口名称修改。AllowedIPs: 这是实现国内/外流量分流的关键。这个列表排除了大部分私有地址,使得访问这些地址的流量直连,其余流量走VPN。您可以根据自己的需求调整。Endpoint: 关键点,指向本地uog服务的监听地址。
防火墙规则 (iptables/ip6tables) 详解:
PostUp 中的两对 iptables 和 ip6tables 命令是实现VPN共享的关键,它们的作用如下:
iptables -A FORWARD -i eth0 -j ACCEPT:- 这条规则被添加到
FORWARD链中,用于处理需要被转发的数据包。 -i eth0指定了规则应用于从eth0(LAN口) 进入的数据包。-j ACCEPT表示接受并允许这些数据包被转发。- 作用: 允许来自局域网设备的数据包通过R2S。
- 这条规则被添加到
iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE:-t nat表示操作nat表,用于网络地址转换。-A POSTROUTING规则被添加到POSTROUTING链,在数据包即将离开本机时进行处理。-o wg0指定了规则应用于即将从wg0(WireGuard接口) 出去的数据包。-j MASQUERADE(伪装) 是一个特殊的NAT操作。它会自动将所有来自局域网的数据包的源IP地址,修改为wg0接口的IP地址。- 作用: 这就是“共享VPN”的核心。它将所有局域网设备的流量“伪装”成来自R2S本身,这样VPN服务器看到的就是一个客户端,而当返回流量到达R2S时,它能根据记录自动将流量转发回正确的局域网设备。
ip6tables 的命令与 iptables 完全相同,只是它们分别用于处理IPv6和IPv4的流量。而 PostDown 中的命令则使用 -D (Delete) 来移除这些规则,确保在VPN断开后网络恢复原状。
3. 启动 WireGuard
现在,可以启动WireGuard服务了:
sudo systemctl enable wg-quick@wg0 --now
检查服务状态:
sudo wg
sudo systemctl status wg-quick@wg0
如果一切正常,您应该能看到与Peer的握手信息。
验证
将局域网内的一台设备的网关和DNS服务器地址都设置为R2S的IP地址(例如 192.168.31.64,请根据您的R2S的实际LAN口IP修改)。
然后在该设备上:
- 访问
ip.sb或类似网站,检查公网IP是否为VPN服务器的IP。 - 尝试访问国内网站,确认速度正常。
ping局域网内其他设备,确认内网通信正常。
至此,您的R2S旁路网关就搭建完成了。