高性能旁路由分流方案
常规软路由方案拓扑
下图为常规软路由拓扑,网上的旁路由方案基本上都是采用“网关互指”的方式,这种方案看似简单,但因为所有流量都经过旁路由,所以问题很多:
性能差
不稳定
精确配置很难
影响智能家居组网
BT被出海浪费流量等等
理想方案🍚
正常流量应直接走主路由,而不经过旁路由,只有特定流量,才走旁路由。
本文的目标是不改变网络结构的前提下,以最小的代价让网络高效透明,对主网络以最小影响。
因为众所周知的原因,本文只讲核心原理,具体操作点到为止。
实现步骤
旁路由
安装基础插件
opkg update
opkg install wget sed coreutils-base64
工具选择
第一步当然是在旁路OpenWrt上安装科学工具,这个在网上有大把的文章,这里面就不展开了,具体是什么样的工具,这个不重要,本方案对此也没有什么要求,总之你喜欢就好,能用就行。
开启功能
工具支持并开启全局代理,即旁路OpenWrt上的所有流量都走工具过滤分流;(一定得开启全局)
工具支持并开启域名嗅探;
按上述要求配置并保证在OpenWrt上能正常上外网就行,可以用以下命令在OpenWrt命令行里验证:
curl https://www.外网.com/
有正常内容响应即可
指定DNS服务器
由于目前我们的OpenWrt是通过DHCP客户端的方式上网的,所以上游DNS是通过主路由的DHCP分配的,后面我们会修改主路由的DHCP DNS参数,所以这里我们需要将OpenWrt的上游DNS固定下来,这里面我们将上游DNS改为主路由的地址。
dnsmasq配置
OpenWrt默认安装了dnsmasq,dnsmasq承担了dhcp和dns解析的工具,这里我们需要对dnsmasq配置稍做改动,让其支持额外的配置文件,在命令行中执行以下命令即可:
mkdir /etc/dnsmasq.d
uci set dhcp.@dnsmasq[0].confdir='/etc/dnsmasq.d'
uci commit
service dnsmasq restart
完成上述操作后,dnsmasq则会将/etc/dnsmasq.d/目录下所有文件当作额外配置加载,在这里面我们可以对特定域名指定特定的dns服务器,也可以对特定域名做特定解析,做特定解析可以实现内网域名,或者做dns污染。
比如我们在/etc/dnsmasq.d/新增加域名test.conf,输入以下内容并执行命令重启dnsmasq(service dnsmasq restart),就可以实现将内网域名http://xxx.myhome.com指向OpenWrt软路由了。
address=/.my.com/192.168.200.1
污染dns
到这一步,大佬都知道是啥思路了,这边就不解释了,总结的时候再解释
我这边准备了使用deepseek写的脚本,完成这功能,其中自定义域名数组就是可以自定义的规则,开箱即用
#!/bin/bash
#--------------- 用户配置区 ---------------
DNS_IP="3.3.3.3" # 目标解析IP
TARGET_DIR="/etc/dnsmasq.d" # 配置目录
CONF_FILE="${TARGET_DIR}/dnsmasq_gfw.conf" # 最终配置文件
# 自定义域名数组 (直接在此处添加)
CUSTOM_DOMAINS=(
"docker.io"
)
#-----------------------------------------
# 强制root权限
[[ $(id -u) -ne 0 ]] && echo -e "\033[31m错误:必须使用root权限运行!\033[0m" >&2 && exit 1
# 创建临时文件
tmpfile=$(mktemp /tmp/gfwlist.XXXXXX) || exit 1
# 下载生成工具
if ! wget -qO /tmp/gfwlist2dnsmasq.sh \
https://raw.githubusercontent.com/cokebar/gfwlist2dnsmasq/master/gfwlist2dnsmasq.sh; then
echo -e "\033[31m错误:脚本下载失败\033[0m" >&2
rm -f "$tmpfile"
exit 1
fi
chmod +x /tmp/gfwlist2dnsmasq.sh
# 生成基础规则
if ! /tmp/gfwlist2dnsmasq.sh -l -o "$tmpfile"; then
echo -e "\033[31m错误:规则生成失败\033[0m" >&2
rm -f "$tmpfile"
exit 1
fi
# 格式转换
sed -i 's/^/address=\/./; s/$/\/'"$DNS_IP"'/' "$tmpfile"
# 添加自定义域名
echo -e "\n# 自定义域名规则" >> "$tmpfile"
for domain in "${CUSTOM_DOMAINS[@]}"; do
# 防御性处理:移除所有逗号和空格
domain=${domain//[ ,]/}
# 跳过空项和注释项
[[ -z "$domain" || "$domain" == "#"* ]] && continue
echo "address=/.${domain}/$DNS_IP" >> "$tmpfile"
done
# 确保目录存在
mkdir -p "$TARGET_DIR" || {
echo -e "\033[31m错误:无法创建目录 $TARGET_DIR\033[0m" >&2
exit 1
}
# 原子化部署
if mv -f "$tmpfile" "$CONF_FILE"; then
echo -e "\033[32m配置部署成功\033[0m"
else
echo -e "\033[31m错误:配置文件移动失败\033[0m" >&2
exit 1
fi
# 重载服务
if service dnsmasq restart; then
echo -e "服务状态:\033[36m$(service dnsmasq status)\033[0m"
echo -e "总规则数:\033[33m$(wc -l < "$CONF_FILE")\033[0m"
else
echo -e "\033[31m错误:dnsmasq重启失败\033[0m" >&2
exit 1
fi
创建完,赋予权限执行即可
到这里旁路OpenWrt的配置就完成了,上述操作可以制作成脚本定时执行以更新列表。
如果一切顺利,在OpenWrt上ping任何外网域名都会解析成3.3.3.3(可以改为其他任意外网ip),此时可以再次验证下OpenWrt上上网是否正常,如果不正常,则是科学工具不支持或者没有开启域名嗅探:
另外可在局域网任意机器上执行以下命令验证dns配置是否成功
主路由
配置静态路由
核心要将自定义解析出来的IP能过旁路由一遍
DHCP
将DNS设置为旁路由地址,网关依旧为主路由
总结
通过维护一些需要学习的顶级域名,通过脚本自动转换解析为dnsmaq能识别的格式,并且将DNS设置为旁路由,这样的话所有域名都会经过旁路由去解析,如果需要学习的域名呢就会返回3.3.3.3,访问时主路由有这个静态路由就会走旁路由,即可学习,否则其他就正常走主路由出去了,少了一层。
缺点
只能维护域名,IP只能在主路由添加静态路由
踩坑
学习工具一定要全局模式!
- 感谢你赐予我前进的力量