这里就不介绍原理和细节问题了,直接上操作,如果感兴趣可以看文末的原文
配置dnsmasq
在dnsmasq的配置文件里面加上一句
conf-dir=/etc/dnsmasq.d/,*.conf
把下面的文件放到/etc/dnsmasq.d/这个路径下
https://cokebar.github.io/gfwlist2dnsmasq/dnsmasq_gfwlist_ipset.conf
配置路由表
在/etc/iproute2/rt_tables文件内加上一句
#前面的数字不能和已经存在的表目标号重合
99 gfwtable
配置防火墙
给防火墙加上配置
ipset -N gfwlist iphash
iptables -t mangle -N fwmark
iptables -t mangle -C OUTPUT -j fwmark || iptables -t mangle -A OUTPUT -j fwmark
iptables -t mangle -C PREROUTING -j fwmark || iptables -t mangle -A PREROUTING -j fwmark
- 第一行增加新的 iphash 类型的名为
gfwlist
的 ipset; - 第二行在 iptables 的
mangle
表中新增fwmark
链; - 第三和第四行分别在 iptables 的
mangle
表的OUTPUT
和PREROUTING
链中增加fwmark
target,为了避免重复,增加之前都用了 iptables 命令判断原有规则是否已经存在; - 后面三条规则有些 OpenWRT 系统里已经自带了,这里为了保险还是加上了。
给防火墙添加分流规则
ip route add 8.8.8.8 dev $1
iptables -t mangle -A fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
ip rule add fwmark 0xffff table gfwtable
ip route add default dev $1 table gfwtable
iptables -I FORWARD -o $1 -j ACCEPT
iptables -t nat -I POSTROUTING -o $1 -j MASQUERADE
- 首先将
8.8.8.8
DNS 解析服务器设置为从 OpenConnect 走防止域名污染; - 使用 iptables
mangle
表中的fwmark
链为所有目标为 gfwlist ipset 中 IP 地址的数据包打标记,这里标记号用的是 0xffff; - 所有标记号为 0xffff 的数据包都使用上面新增的
gfwtable
路由表; gfwtable
路由表固定使用OpenConnect 线路;- 最后两条 iptables 规则也非常重要,允许路由器下的其它设备访问被封锁域名时走 OpenConnect 线路。
从防火墙移除分流规则
ip rule del table gfwtable
iptables -t mangle -D fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
iptables -D FORWARD -o $1 -j ACCEPT
iptables -t nat -D POSTROUTING -o $1 -j MASQUERADE
代码集成联动
OpenWrt下OpenConnect默认使用/lib/netifd/vpnc-script联动控制,那么我们就可以在这上面发挥创造力
run_vpn_up() {
ipset -N gfwlist iphash
iptables -t mangle -N fwmark
iptables -t mangle -A OUTPUT -j fwmark
iptables -t mangle -A PREROUTING -j fwmark
ip route add 8.8.8.8 dev $1
iptables -t mangle -A fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
ip rule add fwmark 0xffff table gfwtable
ip route add default dev $1 table gfwtable
iptables -I FORWARD -o $1 -j ACCEPT
iptables -t nat -I POSTROUTING -o $1 -j MASQUERADE
}
run_vpn_down() {
ip rule del table gfwtable
iptables -t mangle -D fwmark -m set --match-set gfwlist dst -j MARK --set-mark 0xffff
iptables -D FORWARD -o $1 -j ACCEPT
iptables -t nat -D POSTROUTING -o $1 -j MASQUERADE
}
上面我们就自定义了两个函数,也可以理解为两个命令,看着vpnc-script的case字段把run_vpn_up和run_vpn_down这两个函数加进去,vpn-iepl表示虚拟网卡名称,例如:
case "$reason" in
pre-init)
run_hooks pre-init
;;
connect)
run_hooks connect
do_connect
run_hooks post-connect
run_vpn_up vpn-iepl
;;
disconnect)
run_hooks disconnect
do_disconnect
run_hooks post-disconnect
run_vpn_down vpn-iepl
;;
reconnect)
run_hooks reconnect
;;
attempt-reconnect)
run_hooks attempt-reconnect
;;
*)
logger -t openconnect "unknown reason '$reason'. Maybe vpnc-script is out of date" 1>&2
exit 1
;;
esac
流程简述
1、让8.8.8.8的流量走OpenConnect创建的虚拟网卡vpn-iepl,获取到纯净ip
2、根据dnsmasq的规则,把dnsmasq_gfwlist_ipset.conf中域名解析到的ip添加到gfwlist这个列表中
3、把gfwlist列表中的ip添加到gfwtable这张路由表,这张路由表的默认网关是vpn-iepl
最后不懂得可以看看原文
评论