实施指南
物品 规格要求 数量 备注 ------ ---------- ------ ------ NanoPi R4S 4GB 版本推荐 1 1GB 版本也可用 microSD 卡 32GB+ Class 10 1 用于刷入系统 读卡器 USB 3.0 1 刷机使用 网线 Cat 5e/6 2+ 连接路由器和设备 电源适配器 5V/3A Type-C 1 确保供电...
本章节提供完整的实施步骤,包括固件刷入、系统配置、软件安装以及故障回退配置。
环境准备
1.1 硬件清单
| 物品 | 规格要求 | 数量 | 备注 |
|---|---|---|---|
| NanoPi R4S | 4GB 版本推荐 | 1 | 1GB 版本也可用 |
| microSD 卡 | 32GB+ Class 10 | 1 | 用于刷入系统 |
| 读卡器 | USB 3.0 | 1 | 刷机使用 |
| 网线 | Cat 5e/6 | 2+ | 连接路由器和设备 |
| 电源适配器 | 5V/3A Type-C | 1 | 确保供电充足 |
1.2 软件准备
需要下载的文件:
-
OpenWrt 固件:
- 官网下载:https://firmware-selector.openwrt.org/
- 搜索:
nanopi-r4s - 选择:
squashfs-combined.img.gz
-
刷机工具:
- Windows: Rufus 或 balenaEtcher
- macOS/Linux:
dd命令
-
SSH 客户端:
- Windows: PuTTY 或 Windows Terminal
- macOS/Linux: 自带 Terminal
1.3 刷入固件
步骤 1:下载并解压固件
# Linux/macOS
gunzip openwrt-23.05.3-rockchip-armv8-friendlyarm_nanopi-r4s-squashfs-combined.img.gz
# Windows 使用 7-Zip 解压 .gz 文件
步骤 2:刷入 microSD 卡
# Linux/macOS (将 sdX 替换为实际设备名,注意数据会丢失!)
sudo dd if=openwrt.img of=/dev/sdX bs=4M status=progress
sync
# Windows 使用 Rufus:
# 1. 插入 microSD 卡
# 2. 打开 Rufus
# 3. 选择设备和固件 img 文件
# 4. 点击开始
步骤 3:启动 R4S
- 插入刷好固件的 microSD 卡
- 连接网线到 R4S 的 LAN 口(靠近 HDMI 的网口)
- 连接电源,等待启动(约 1-2 分钟)
- R4S 默认 IP:
192.168.1.1
OpenWrt 安装配置
2.1 初始配置
步骤 1:连接并登录
# SSH 登录(默认无密码)
ssh root@192.168.1.1
# 设置 root 密码
passwd
步骤 2:网络基础配置
将 R4S 配置为旁路由模式:
# 设置 LAN 口静态 IP(旁路由 IP)
uci set network.lan.ipaddr='192.168.1.2'
uci set network.lan.netmask='255.255.255.0'
# 设置网关指向主路由
uci set network.lan.gateway='192.168.1.1'
# 设置 DNS
uci set network.lan.dns='192.168.1.1'
# 提交配置
uci commit network
# 重启网络
/etc/init.d/network restart
注意:配置后 R4S 的 IP 变为 192.168.1.2,需要重新 SSH 连接。
2.2 软件源配置
步骤 1:更新软件源
# 连接互联网(此时 R4S 可通过主路由上网)
ping -c 3 223.5.5.5
# 更新软件列表
opkg update
步骤 2:安装必要工具
# 基础工具
opkg install vim curl wget htop iperf3
# 网络工具
opkg install iptables-mod-tproxy iptables-mod-extra
opkg install ipset dnsmasq-full
# 替换 dnsmasq 为完整版
opkg remove dnsmasq
opkg install dnsmasq-full
2.3 防火墙基础配置
# 允许 LAN 口转发(旁路由模式必需)
uci set firewall.@zone[0].forward='ACCEPT'
uci commit firewall
/etc/init.d/firewall restart
V2Ray 安装与配置
3.1 安装 V2Ray
方式 1:使用官方包(推荐)
# 安装 V2Ray
opkg install v2ray-core
# 或安装 Xray(性能更好)
opkg install xray-core
方式 2:手动安装最新版
# 下载最新版(ARM64)
cd /tmp
wget https://github.com/v2fly/v2ray-core/releases/latest/download/v2ray-linux-arm64-v8a.zip
unzip v2ray-linux-arm64-v8a.zip -d /usr/bin/
chmod +x /usr/bin/v2ray
3.2 V2Ray 配置文件
创建配置文件 /etc/v2ray/config.json:
{
"log": {
"loglevel": "warning",
"access": "/var/log/v2ray-access.log",
"error": "/var/log/v2ray-error.log"
},
"inbounds": [
{
"tag": "transparent",
"port": 12345,
"protocol": "dokodemo-door",
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy"
}
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls"]
}
}
],
"outbounds": [
{
"tag": "proxy",
"protocol": "vmess",
"settings": {
"vnext": [
{
"address": "your.server.address",
"port": 443,
"users": [
{
"id": "your-uuid-here",
"security": "auto",
"alterId": 0
}
]
}
]
},
"streamSettings": {
"network": "tcp",
"security": "tls"
}
},
{
"tag": "direct",
"protocol": "freedom"
},
{
"tag": "block",
"protocol": "blackhole"
}
],
"routing": {
"domainStrategy": "IPIfNonMatch",
"rules": [
{
"type": "field",
"ip": ["geoip:private", "geoip:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:cn"],
"outboundTag": "direct"
},
{
"type": "field",
"network": "udp",
"outboundTag": "direct"
},
{
"type": "field",
"domain": ["geosite:geolocation-!cn"],
"outboundTag": "proxy"
},
{
"type": "field",
"ip": ["geoip:!cn"],
"outboundTag": "proxy"
}
]
}
}
重要:将 your.server.address 和 your-uuid-here 替换为你的实际服务器配置。
3.3 启动 V2Ray
# 创建启动脚本 /etc/init.d/v2ray
cat > /etc/init.d/v2ray << 'EOF'
#!/bin/sh /etc/rc.common
START=99
STOP=10
USE_PROCD=1
start_service() {
procd_open_instance
procd_set_param command /usr/bin/v2ray -config /etc/v2ray/config.json
procd_set_param respawn
procd_set_param stdout 1
procd_set_param stderr 1
procd_close_instance
}
EOF
chmod +x /etc/init.d/v2ray
# 启动并设置开机自启
/etc/init.d/v2ray enable
/etc/init.d/v2ray start
# 检查状态
/etc/init.d/v2ray status
DHCP 服务器设置
4.1 配置 DHCP
# 启用 DHCP 服务器
uci set dhcp.lan.ignore='0'
# 设置 DHCP 范围
uci set dhcp.lan.start='100'
uci set dhcp.lan.limit='150'
uci set dhcp.lan.leasetime='12h'
# 关键:设置 DHCP Option 3,告知客户端使用 R4S 作为网关
uci add_list dhcp.lan.dhcp_option='3,192.168.1.2'
# 可选:设置 DNS 为 R4S
uci add_list dhcp.lan.dhcp_option='6,192.168.1.2'
uci commit dhcp
/etc/init.d/dnsmasq restart
4.2 关闭主路由 DHCP(重要)
为避免 DHCP 冲突,需要关闭主路由的 DHCP 服务:
- 登录主路由管理界面(通常是
192.168.1.1) - 找到 DHCP 服务器设置
- 关闭 DHCP 服务器
- 保存并重启主路由
注意:如果无法关闭主路由 DHCP,可以将 R4S DHCP 租期设短(如 2 分钟),作为辅助 DHCP。
透明代理配置
5.1 创建 iptables 规则脚本
创建 /etc/init.d/v2ray-setup-iptables:
cat > /etc/init.d/v2ray-setup-iptables << 'EOF'
#!/bin/sh /etc/rc.common
START=95
STOP=5
start() {
# 创建新链
iptables -t mangle -N V2RAY 2>/dev/null
iptables -t mangle -F V2RAY 2>/dev/null
# 绕过本地地址和私有网络
iptables -t mangle -A V2RAY -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A V2RAY -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A V2RAY -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A V2RAY -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY -d 240.0.0.0/4 -j RETURN
# 绕过已建立的连接
iptables -t mangle -A V2RAY -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
# 绕过 V2Ray 自身流量(避免环路)
iptables -t mangle -A V2RAY -m mark --mark 0xff -j RETURN
# 劫持 TCP 流量到 TPROXY
iptables -t mangle -A V2RAY -p tcp -j TPROXY --on-port 12345 --tproxy-mark 0x1/0x1
# 劫持 UDP 流量到 TPROXY(可选)
# iptables -t mangle -A V2RAY -p udp -j TPROXY --on-port 12345 --tproxy-mark 0x1/0x1
# 应用规则到 PREROUTING
iptables -t mangle -A PREROUTING -j V2RAY
# 为本地流量添加标记(OUTPUT 链)
iptables -t mangle -N V2RAY_MASK 2>/dev/null
iptables -t mangle -F V2RAY_MASK 2>/dev/null
iptables -t mangle -A V2RAY_MASK -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 192.168.0.0/16 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY_MASK -d 240.0.0.0/4 -j RETURN
iptables -t mangle -A V2RAY_MASK -m conntrack --ctstate ESTABLISHED,RELATED -j RETURN
iptables -t mangle -A V2RAY_MASK -m mark --mark 0xff -j RETURN
iptables -t mangle -A V2RAY_MASK -p tcp -j MARK --set-mark 0x1
# iptables -t mangle -A V2RAY_MASK -p udp -j MARK --set-mark 0x1
iptables -t mangle -A OUTPUT -j V2RAY_MASK
# 配置路由表
ip rule add fwmark 0x1 table 100 2>/dev/null
ip route add local 0.0.0.0/0 dev lo table 100 2>/dev/null
echo "V2Ray iptables rules applied"
}
stop() {
iptables -t mangle -D PREROUTING -j V2RAY 2>/dev/null
iptables -t mangle -D OUTPUT -j V2RAY_MASK 2>/dev/null
iptables -t mangle -F V2RAY 2>/dev/null
iptables -t mangle -F V2RAY_MASK 2>/dev/null
iptables -t mangle -X V2RAY 2>/dev/null
iptables -t mangle -X V2RAY_MASK 2>/dev/null
ip rule del fwmark 0x1 table 100 2>/dev/null
echo "V2Ray iptables rules cleared"
}
restart() {
stop
start
}
EOF
chmod +x /etc/init.d/v2ray-setup-iptables
5.2 启动透明代理
# 启动 iptables 规则
/etc/init.d/v2ray-setup-iptables start
# 设置开机自启
/etc/init.d/v2ray-setup-iptables enable
5.3 下载 GeoIP/GeoSite 数据库
# 创建数据目录
mkdir -p /usr/share/v2ray
# 下载 GeoIP 数据库
curl -L -o /usr/share/v2ray/geoip.dat \
"https://github.com/v2fly/geoip/releases/latest/download/geoip.dat"
# 下载 GeoSite 数据库
curl -L -o /usr/share/v2ray/geosite.dat \
"https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat"
# 重启 V2Ray 加载数据库
/etc/init.d/v2ray restart
故障回退配置
6.1 健康检查脚本
创建 /usr/bin/v2ray-health-check.sh:
cat > /usr/bin/v2ray-health-check.sh << 'EOF'
#!/bin/sh
# 配置
CHECK_INTERVAL=30
FAIL_THRESHOLD=3
LOG_FILE="/var/log/v2ray-health.log"
STATE_FILE="/var/run/v2ray-health.state"
# 获取当前失败计数
FAIL_COUNT=$(cat "$STATE_FILE" 2>/dev/null || echo 0)
# 检查 1:V2Ray 进程是否存在
V2RAY_PID=$(pgrep -f "v2ray.*config")
if [ -z "$V2RAY_PID" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: V2Ray process not found" >> "$LOG_FILE"
FAIL_COUNT=$((FAIL_COUNT + 1))
else
# 进程存在,检查是否响应
if ! kill -0 "$V2RAY_PID" 2>/dev/null; then
echo "$(date '+%Y-%m-%d %H:%M:%S') ERROR: V2Ray process not responding" >> "$LOG_FILE"
FAIL_COUNT=$((FAIL_COUNT + 1))
else
# 进程正常,重置失败计数
FAIL_COUNT=0
fi
fi
# 检查失败次数是否超过阈值
if [ "$FAIL_COUNT" -ge "$FAIL_THRESHOLD" ]; then
echo "$(date '+%Y-%m-%d %H:%M:%S') WARN: Fail threshold reached, enabling fallback" >> "$LOG_FILE"
/usr/bin/v2ray-fallback.sh enable
echo 0 > "$STATE_FILE"
else
# 确保代理模式启用
/usr/bin/v2ray-fallback.sh disable
echo "$FAIL_COUNT" > "$STATE_FILE"
fi
EOF
chmod +x /usr/bin/v2ray-health-check.sh
6.2 回退控制脚本
创建 /usr/bin/v2ray-fallback.sh:
cat > /usr/bin/v2ray-fallback.sh << 'EOF'
#!/bin/sh
ACTION=$1
LOCK_FILE="/var/run/v2ray-fallback.lock"
STATE_FILE="/var/run/v2ray-fallback.state"
LOG_FILE="/var/log/v2ray-health.log"
# 防止并发执行
exec 200>"$LOCK_FILE"
flock -n 200 || exit 0
current_state=$(cat "$STATE_FILE" 2>/dev/null || echo "disabled")
enable_fallback() {
if [ "$current_state" != "enabled" ]; then
# 清除代理规则
/etc/init.d/v2ray-setup-iptables stop 2>/dev/null
echo "$(date '+%Y-%m-%d %H:%M:%S') INFO: Fallback mode enabled" >> "$LOG_FILE"
echo "enabled" > "$STATE_FILE"
fi
}
disable_fallback() {
if [ "$current_state" != "disabled" ]; then
# 恢复代理规则
/etc/init.d/v2ray-setup-iptables start 2>/dev/null
echo "$(date '+%Y-%m-%d %H:%M:%S') INFO: Proxy mode restored" >> "$LOG_FILE"
echo "disabled" > "$STATE_FILE"
fi
}
case $ACTION in
enable)
enable_fallback
;;
disable)
disable_fallback
;;
status)
echo "Current state: $current_state"
;;
*)
echo "Usage: $0 {enable|disable|status}"
exit 1
;;
esac
EOF
chmod +x /usr/bin/v2ray-fallback.sh
6.3 配置定时任务
# 编辑 crontab
cat >> /etc/crontabs/root << 'EOF'
# V2Ray 健康检查(每 30 秒)
*/1 * * * * /usr/bin/v2ray-health-check.sh
*/1 * * * * sleep 30 && /usr/bin/v2ray-health-check.sh
EOF
# 启动 cron
/etc/init.d/cron enable
/etc/init.d/cron start
测试验证步骤
7.1 基础功能测试
测试 1:网络连通性
# 在客户端执行
ping 192.168.1.1 # 主路由
ping 192.168.1.2 # R4S
ping 223.5.5.5 # 公共 DNS
ping baidu.com # 国内网站
测试 2:DHCP 分配
# 查看客户端获取的 IP 和网关
ipconfig # Windows
ip addr # Linux
# 确认网关是 192.168.1.2
测试 3:透明代理生效
# 访问国外网站检查 IP
curl -s ipinfo.io
# 应显示代理服务器所在国家的 IP
7.2 故障回退测试
测试 1:V2Ray 进程停止
# 在 R4S 上执行
/etc/init.d/v2ray stop
# 在客户端测试
ping baidu.com # 应该正常
ping google.com # 可能超时(正常)
curl -s ipinfo.io # 应显示真实 IP
测试 2:恢复 V2Ray
# 在 R4S 上执行
/etc/init.d/v2ray start
# 等待 30 秒后测试
curl -s ipinfo.io # 应显示代理 IP
测试 3:查看日志
# 在 R4S 上查看回退日志
tail -f /var/log/v2ray-health.log
# 查看 iptables 规则状态
iptables -t mangle -L -n -v
7.3 性能测试
# 内网带宽测试(R4S 到客户端)
iperf3 -s # 在 R4S 运行
iperf3 -c 192.168.1.2 # 在客户端运行
# 外网速度测试
speedtest-cli
7.4 验证清单
- R4S 正常启动,可 SSH 登录
- 客户端通过 DHCP 获取 IP 和网关
- 网关指向 192.168.1.2
- 国内网站访问正常
- 国外网站通过代理访问
- V2Ray 停止后,国内网站仍可访问
- V2Ray 恢复后,代理自动生效
- 带宽达到预期(500Mbps+)
故障排查
常见问题
问题 1:客户端无法获取 IP
# 检查 DHCP 服务
/etc/init.d/dnsmasq status
logread | grep dnsmasq
# 检查防火墙
iptables -L -n | grep 67
问题 2:透明代理不生效
# 检查 V2Ray 运行状态
/etc/init.d/v2ray status
logread | grep v2ray
# 检查 iptables 规则
iptables -t mangle -L V2RAY -n -v
# 检查路由表
ip rule show
ip route show table 100
问题 3:国内网站走代理
# 检查 GeoIP 数据库是否存在
ls -la /usr/share/v2ray/geoip.dat
# 检查 V2Ray 配置中的路由规则
cat /etc/v2ray/config.json | grep -A5 geoip
日志查看
# 系统日志
logread -f
# V2Ray 日志
tail -f /var/log/v2ray-error.log
tail -f /var/log/v2ray-access.log
# 回退日志
tail -f /var/log/v2ray-health.log
参考资料
- OpenWrt 用户指南 - 官方用户文档
- V2Ray 配置指南 - 官方配置文档
- Linux TPROXY 教程 - TPROXY 内核文档
- iptables 透明代理 - Netfilter 官方文档