基于iptables+ipset实现内网透明代理
ipset
借助ipset来区分大陆和海外IP
wget -P . http://www.ipdeny.com/ipblocks/data/countries/cn.zone
ipset create chnroute hash:net
for i in $(cat /jffs/configs/cn.zone ); do ipset -A chnroute $i; done > /dev/null 2>&1 &
iptables
graph TD
START((START)) --> A
A(内网终端) -->|发起请求| B(路由器/网关)
B --> B1(CLASH链)
B1 --> B2(流量打标)
B2 --> C{内网IP段?}
C -->|yes| END((END))
C -->|no| D{有标签 & 目标是代理服务器?}
D -->|yes| END
D -->|no| E{大陆IP?}
E -->|yes| END
E --> G(redir-port)
- 创建一个新的链CLASH, 也可命名其它
- 跳过目标是内网IP段的流量
- 这里有一个点需要关注, 经过代理转发的流量还会重新进入CLASH链, 产生循环, 故对刚进入CLASH链的流量进行打标
iptables -t nat -I CLASH 1 -p tcp -j CONNMARK --set-mark 5
, 并且在CLASH链中忽略目标是代理服务器IP且有标的流量, 这样就能避免循环 - 通过
ipset
匹配并忽略大陆IP - 将CLASH链的流量转发到代理服务器, 这个服务器可以是
redir-port
, 或者其它 - 将tcp流量全部转发到CLASH链
iptables -t nat -N CLASH
# tag for redir-port
iptables -t nat -I CLASH 1 -p tcp -j CONNMARK --set-mark 5
iptables -t nat -A CLASH -d 0.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 10.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 127.0.0.0/8 -j RETURN
iptables -t nat -A CLASH -d 169.254.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 172.16.0.0/12 -j RETURN
iptables -t nat -A CLASH -d 192.168.0.0/16 -j RETURN
iptables -t nat -A CLASH -d 224.0.0.0/4 -j RETURN
iptables -t nat -A CLASH -d 240.0.0.0/4 -j RETURN
# check tag for redir-port
iptables -t nat -A CLASH -d 127.0.0.1 -p tcp -m tcp --dport 7892 -m connmark ! --mark 5 -j RETURN
iptables -t nat -A CLASH -d 10.33.30.1 -p tcp -m tcp --dport 7892 -m connmark ! --mark 5 -j RETURN
iptables -t nat -A CLASH -d 127.0.0.1 -p udp -m udp --dport 7892 -m connmark ! --mark 5 -j RETURN
iptables -t nat -A CLASH -d 10.33.30.1 -p udp -m udp --dport 7892 -m connmark ! --mark 5 -j RETURN
# domestic ip
iptables -t nat -A CLASH -p tcp -m set --match-set chnroute dst -j RETURN
iptables -t nat -A CLASH -p icmp -m set --match-set chnroute dst -j RETURN
# redirect to clash
iptables -t nat -A CLASH -p tcp -j REDIRECT --to-ports 7892
iptables -t nat -A PREROUTING -p tcp -j CLASH
启动脚本 & 定期更新
iptables和ipset会在重启后丢失, 可将以上代码封装到proxy.sh
中, 在系统启动时执行, 也可以保存iptables规则, 笔者选择前者.
欢迎关注公众号(代码如诗)
推荐阅读
- 开放API网关实践(一) ——设计一个API网关
- 开放API网关实践(二) —— 重放攻击及防御
- 开放API网关实践(三) —— 限流
- Kubernetes(一) 跟着官方文档从零搭建K8S
- Kubernetes(二) 应用部署
- Kubernetes(三) 如何从外部访问服务