2079 字
10 分钟
家庭网络折腾

家庭网络环境介绍#

  • PVE服务器: 天钡 GEM12 8845HS 32G-2T 双2.5G网口
  • 天翼网关:中兴 7015TV3 无无线,一个2.5G网口三个千兆口
  • 路由器:小米AX9000

过年回家了,找电信师傅改的桥接;通过小主机PVE中的ROS虚拟机PPPOE拨号、DHCP,结合ADG虚拟机和TProxy虚拟机组成基础的网络架构;小主机的另一个网口连接小米AX9000路由器,路由器关闭DHCP功能,仅作为WIFI接入的功能

PVE安装及优化#

参考 狐狸 Nomad./PVE_Toss_Notes

PVE温度风扇监控

https://github.com/KoolCore/Proxmox_VE_Status

RouterOS#

参考 狐狸 Nomad./RouterOS_Toss_Notes

注意,RouterOS的DNS设置为公共DNS不要使用内网DNS,不然DNS服务器和RouterOS互指,重启后你网会不通

TProxy#

TProxy不是必要步骤,我是自建的科学,如果你是购买的机场直接用佛跳墙内科学软件就行

但是我用op的passwall2的分流规则有点问题,佛跳墙和QWRT都试了,遂自己部署tproxy

CAUTION

如果不是自建节点,请跳过此章节!

如果不是自建节点,请跳过此章节!

如果不是自建节点,请跳过此章节!

自建TProxy的步骤

1. 安装Xray-core#

bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install -u root

2. 客户端的config.json#

/usr/local/etc/xray/config.json
{
// 1_日志设置
"log": {
3 collapsed lines
"access": "/var/log/xray/access.log",
"error": "/var/log/xray/error.log",
"loglevel": "warning"
},
// 2_DNS设置
"dns": {
20 collapsed lines
"servers": [
// 2.1 国外域名使用国外DNS查询
{
"address": "1.1.1.1",
"domains": ["geosite:geolocation-!cn"]
},
// 2.2 国内域名使用国内DNS查询,并期待返回国内的IP,若不是国内IP则舍弃,用下一个查询
{
"address": "172.16.1.2",
"domains": ["geosite:cn"],
"expectIPs": ["geoip:cn"]
},
// 2.3 作为1.2的备份,对国内网站进行二次查询
{
"address": "114.114.114.114",
"domains": ["geosite:cn"]
},
// 2.4 最后的备份,上面全部失败时,用本机DNS查询
"localhost"
]
},
// 3_分流设置
// 所谓分流,就是将符合否个条件的流量,用指定`tag`的出站协议去处理(对应配置的5.x内容)
"routing": {
54 collapsed lines
"domainMatcher": "mph",
"domainStrategy": "IPIfNonMatch",
"rules": [
// 3.1 广告域名屏蔽
{
"domain": ["geosite:category-ads-all"],
"outboundTag": "block"
},
// 3.2 Google play store下载
{
"domain": ["geosite:google","geosite:google-cn"],
"outboundTag": "proxy"
},
// 3.3 ntp 123放行
{
"inboundTag": ["all-in"],
"port": 123,
"network": "udp",
"outboundTag": "direct"
},
// 3.4 dns 53 放行
{
"inboundTag": ["all-in"],
"port": 53,
"network": "udp",
"outboundTag": "dns-out"
},
// 3.5 阻断 udp 443
{
"port": "443",
"network": "udp",
"outboundTag": "block"
},
// 3.6 绕过 BT 下载
{
"protocol": "bittorrent",
"outboundTag": "direct"
},
// 3.7 国内域名直连
{
"domain": ["geosite:cn","geosite:geolocation-cn","geosite:apple-cn","geosite:google-cn","geosite:tld-cn","geosite:category-games@cn"],
"outboundTag": "direct"
},
// 3.8 国内IP直连
{
"ip": ["geoip:cn", "geoip:private"],
"outboundTag": "direct"
},
// 3.9 国外域名代理
{
"domain": ["geosite:geolocation-!cn"],
"outboundTag": "proxy"
}
]
},
// 4_入站设置
"inbounds": [
32 collapsed lines
// 4.1 一般都默认使用socks5协议作本地转发
{
"tag": "all-in",
"protocol": "dokodemo-door",
"port": 12345,
"settings": {
"network": "tcp,udp",
"followRedirect": true
},
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
},
"streamSettings": {
"sockopt": {
"tproxy": "tproxy"
}
}
},
// 4.2 为偶尔需要手动配置科学监听的SOCKS端口
{
"port": 10000,
"protocol": "socks",
"sniffing": {
"enabled": true,
"destOverride": ["http", "tls", "quic"]
},
"settings": {
"auth": "noauth",
"udp": true
}
}
],
// 5_出站设置
"outbounds": [
39 collapsed lines
// 5.1 默认转发VPS
{
"tag": "proxy",
"protocol": "vless",
"settings": {
//省略,你自建的settings
},
"streamSettings": {
//省略,你自建的streansettings
},
"sockopt": {
"mark": 255 // 必须对应 nftables 中的 meta mark 0xff return
}
}
},
// 5.2 用`freedom`协议直连出站,即当routing中指定'direct'流出时,调用这个协议做处理
{
"tag": "direct",
"protocol": "freedom",
"streamSettings": {
"sockopt": {
"mark": 255 // 必须对应 nftables 中的 meta mark 0xff return
}
}
},
{
"tag": "dns-out",
"protocol": "dns",
"streamSettings": {
"sockopt": {
"mark": 255
}
}
},
// 5.3 用`blackhole`协议屏蔽流量,即当routing中指定'block'时,调用这个协议做处理
{
"tag": "block",
"protocol": "blackhole"
}
]
}

3.重启xray#

systemctl restart xray

4. nftables和策略路由#

4.1 安装并启动nftables#
dnf install nftables;systemctl enable --now nftables
4.2 创建nftables.rulesv46#
/etc/systemd/system/nftables.rulesv46
#!/usr/sbin/nft -f
flush ruleset
table inet xray {
chain prerouting {
type filter hook prerouting priority filter; policy accept;
ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return
meta l4proto tcp ip daddr 172.16.0.0/16 return
ip daddr 172.16.0.0/16 udp dport != 53 return
ip6 daddr { ::1, fe80::/10 } return
meta l4proto tcp ip6 daddr fdac::/8 return
ip6 daddr fdac::/8 udp dport != 53 return
meta mark 0x000000ff return
meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip to 127.0.0.1:12345 accept
meta l4proto { tcp, udp } meta mark set 0x00000001 tproxy ip6 to [::1]:12345 accept
}
chain output {
type route hook output priority filter; policy accept;
ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return
meta l4proto tcp ip daddr 172.16.0.0/16 return
ip daddr 172.16.0.0/16 udp dport != 53 return
ip6 daddr { ::1, fe80::/10 } return
meta l4proto tcp ip6 daddr fdac::/8 return
ip6 daddr fdac::/8 udp dport != 53 return
meta mark 0x000000ff return
meta l4proto { tcp, udp } meta mark set 0x00000001 accept
}
chain divert {
type filter hook prerouting priority mangle; policy accept;
meta l4proto tcp socket transparent 1 meta mark set 0x00000001 accept
}
}

根据你的IPv4和IPv6网关进行更改,替换掉172.16.0.0/16fdac::/8

4.3 创建tproxy.service#
/etc/systemd/system/tproxy.service
[Unit]
Description=Tproxy rules for Side Gateway
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
# 确保网关连通后再加载
ExecStartPre=/bin/sh -c "until ping -c1 172.16.1.1 >/dev/null 2>&1; do sleep 1; done"
ExecStart=/bin/sh -c "\
ip rule add fwmark 1 table 100 2>/dev/null || true; \
ip -6 rule add fwmark 1 table 106 2>/dev/null || true; \
ip route replace local default dev lo table 100; \
ip -6 route replace local default dev lo table 106; \
/usr/sbin/nft -f /etc/systemd/system/nftables.rulesv46"
ExecStop=/bin/sh -c "\
ip rule del fwmark 1 table 100 2>/dev/null || true; \
ip -6 rule del fwmark 1 table 106 2>/dev/null || true; \
nft flush ruleset"
[Install]
WantedBy=multi-user.target
4.4 设置tproxy自启动#
systemctl enable --now tproxy
4.5 如何使用tproxy#
  • pve中的服务器,通过cloudinit将网关和DNS指向TProxy服务器的IP,我的即172.16.1.3

  • 需要科学的设备,需要使用设备mac,不要使用随机mac,通过RouterOS 的DHCP Server设置静态IP,设置Option Sets将需要科学的设备网关和DNS指向 TProxy服务器

    • # ROS终端中添加
      /ip dhcp-server option
      add code=6 name=tproxy-dns value="'172.16.1.3'"
      add code=3 name=tproxy-gw value="'172.16.1.3'"
      /ip dhcp-server option sets
      add name=tproxy options=tproxy-dns,tproxy-gw
  • 偶尔需要科学的设备,设置代理指向 TProxy监听的socks端口,即socks://172.16.1.3:10000

5.自动更新xray和geo分流文件#

5.1 update-xray.sh#
/opt/update-xray.sh
#!/bin/bash
# 配置路径
XRAY_BIN="/usr/local/bin/xray"
LOG_FILE="/var/log/xray_update.log"
# --- 版本提取 ---
# 提取本地版本: Xray 26.2.6 -> 26.2.6
LOCAL_VER=$($XRAY_BIN --version 2>/dev/null | head -n 1 | awk '{print $2}')
# 提取远程版本: "tag_name": "v26.2.6" -> 26.2.6
# 增加 --connect-timeout 和 --retry 提高稳定性
REMOTE_VER=$(curl -s --connect-timeout 10 --retry 3 https://api.github.com/repos/XTLS/Xray-core/releases/latest | grep '"tag_name":' | sed -E 's/.*"v?([^"]+)".*/\1/')
echo "-------------------------------------------" >> $LOG_FILE
echo "$(date '+%Y-%m-%d %H:%M:%S') 检查 Xray-Core 更新..." >> $LOG_FILE
# 检查远程版本是否获取成功
if [ -z "$REMOTE_VER" ]; then
echo "错误: 无法获取远程版本,可能是 GitHub API 访问受限或网络连接失败。" >> $LOG_FILE
exit 1
fi
echo "当前本地版本: ${LOCAL_VER:-未知}" >> $LOG_FILE
echo "当前远程版本: ${REMOTE_VER}" >> $LOG_FILE
# --- 核心判断逻辑 ---
if [ "$LOCAL_VER" == "$REMOTE_VER" ]; then
echo "结果: 已经是最新版本,跳过更新。" >> $LOG_FILE
else
echo "结果: 发现新版本 ${REMOTE_VER},准备开始升级..." >> $LOG_FILE
# 执行官方安装/更新脚本
if bash -c "$(curl -L -s --connect-timeout 10 https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install -u root >> $LOG_FILE 2>&1; then
echo "$(date '+%Y-%m-%d %H:%M:%S') 升级完成!" >> $LOG_FILE
else
echo "$(date '+%Y-%m-%d %H:%M:%S') 升级脚本执行失败,请检查上方日志。" >> $LOG_FILE
exit 1
fi
fi
5.2 update-geo.sh#
/opt/update-geo.sh
#!/bin/bash
# 配置变量
DEST_DIR="/usr/local/share/xray"
TMP_DIR="/tmp"
MAX_RETRIES=3
FILES=("geoip.dat" "geosite.dat")
BASE_URL="https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download"
# 确保目标目录存在
mkdir -p "$DEST_DIR"
download_and_verify() {
local file=$1
local retry=0
local success=false
while [ $retry -lt $MAX_RETRIES ]; do
((retry++))
echo "正在下载 $file (尝试 $retry/$MAX_RETRIES)..."
# 下载文件和对应的 sha256sum
curl -L -s -o "$TMP_DIR/$file" "$BASE_URL/$file"
curl -L -s -o "$TMP_DIR/$file.sha256sum" "$BASE_URL/$file.sha256sum"
# 进入 tmp 目录执行校验
# 因为校验文件内容是 "hash filename",需要 cd 过去确保文件名匹配
cd "$TMP_DIR" || exit 1
if sha256sum -c "$file.sha256sum" > /dev/null 2>&1; then
echo "$file 校验通过!"
success=true
break
else
echo "$file 校验失败,正在重试..."
rm -f "$TMP_DIR/$file" "$TMP_DIR/$file.sha256sum"
fi
done
if [ "$success" = false ]; then
echo "错误: $file$MAX_RETRIES 次尝试后仍下载失败或校验不匹配,退出脚本。"
exit 1
fi
}
# 1. 处理两个文件
for f in "${FILES[@]}"; do
download_and_verify "$f"
done
# 2. 如果运行到这里,说明全部校验通过,开始移动文件
echo "所有文件校验成功,正在移动到 $DEST_DIR..."
for f in "${FILES[@]}"; do
mv -f "$TMP_DIR/$f" "$DEST_DIR/$f"
rm -f "$TMP_DIR/$f.sha256sum"
done
# 3. 重启 xray 服务
echo "正在重启 Xray 服务..."
systemctl restart xray
if [ $? -eq 0 ]; then
echo "完成!规则已更新并重启服务。"
else
echo "服务重启失败,请检查 systemctl status xray。"
exit 1
fi
5.3 定时任务#
  • 每天凌晨两点更新geo文件
  • 每周六凌晨三点检查xray-core最新版,如有更新则更新xray-core
crontab -l
00 02 * * * /opt/update-geo.sh >> /var/log/update-geo.log 2>&1
00 03 * * 6 /opt/update_xray.sh

AdGuardHome#

一个开源的过滤广告和追踪的DNS服务器

配置Adg服务器的cloudinit,将网关和DNS指向RouterOS

可以参考我之前的配置

https://v0nl1.com/posts/adguardhome

参考资料#

狐狸 Nomad./PVE_Toss_Notes

https://github.com/KoolCore/Proxmox_VE_Status

狐狸 Nomad./RouterOS_Toss_Notes

https://github.com/XTLS/Xray-install

https://xtls.github.io/document/level-2/tproxy_ipv4_and_ipv6.html

家庭网络折腾
https://v0nl1.com/posts/home-network-record/
作者
V0nl1
发布于
2026-02-14
许可协议
CC BY-NC-SA 4.0