28
2024
11
11:01:41

ocserv配合clash+dnsmasq解决国内外分流问题

nftables+clash打造透明代理时的dns处理问题

在ubuntu上启用一个透明代理,这样局域网设备或者基于ocserv的VPN拨入进来可以无缝的访问需要代理才能访问的网站,同时VPN拨入进来后只有需要代理的流量走VPN,从而避免本地的访问速度变慢。

考虑到对iptables实在不太熟悉,且觉得很多的配置过于繁琐也反人类,最终选择通过nftables劫持流量给到服务器上部署的clash端口。

关于详细的配置或者需要配置UDP的透明代理,可以参考如下文章

https://koswu.github.io/2019/08/19/tproxy-config-with-nftables/

ntables的配置参考:

root@clash:~# cat /etc/nftables.conf 
#!/usr/sbin/nft -f

flush ruleset

define lan = {
        0.0.0.0/8,
        10.0.0.0/8,
        127.0.0.0/8,
        169.254.0.0/16,
        172.16.0.0/12,
        192.168.0.0/16,
        224.0.0.0/4,
        240.0.0.0/4
}

table ip nat {
        chain proxy {
                ip daddr $lan return
                ip protocol tcp redirect to :7892
        }

        chain prerouting {
                type nat hook prerouting priority 0; policy accept;
                jump proxy
        }
}

其中7892端口是给到本地的clash的redir-port,clash上的配置参考:

root@clash:~# cat /etc/clash/config.yaml | head -n 10
tproxy-port: 7890
mixed-port: 7891
redir-port: 7892

allow-lan: true
bind-address: '*'

mode: rule
log-level: info

ocserv的配置省略,可以参考这个项目:

 GitHub
wppurking/ocserv-docker
用于初始化 ocserv 的 Dockfile 脚本

★ 609

正常来说到上面这步骤透明代理已经配置完成,但实际在应用过程中一步一步踩到了各种坑:

坑1:

正常来说,在现在的环境下,操作系统中使用代理软件无需考虑DNS解析的问题,但透明代理时部分网站访问不正常。

原因:当使用透明代理时存在DNS污染的问题。客户端拿到错误的IP后发起请求,会导致部分网站访问不正常。

解决方案内网存在一个不被污染的DNS服务器地址,直接配置给客户端即可解决问题。


坑2:

配置完DNS后,访问部分网站时,发现并没有完全按照clash定义的规则进行处置。尤其是访问ChatGPT时,没有走代理链。

原因:使用socks5代理时(socks4不支持),浏览器会将域名封装在流量中发往代理服务器。此时代理服务器可以使用domain类的命中规则对此次代理直接命中接管,或使用系统自带DNS解析出一个保留地址或国外IP后,命中国外规则走代理处理。无论哪种情况代理服务器是可以拿到域名信息的。

但使用透明代理时且使用第三方DNS时,代理服务器拿不到域名信息自然规则也就失效。

解决方案:在坑1的过程中并没有考虑到DNS的传递问题,当时简单的理解直接解决DNS污染问题了。

Surge/Clash(新版)都采用Fake IP功能,该定义出自RFC3089。简单的说就是客户端需要从代理软件进行域名解析,同时代理软件需要维护一个域名与IP对应的临时数据库。

增加的clash的配置文件参考:

dns:
  enable: true
  ipv6: false
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip
  nameserver:
    - 8.8.8.8
  fallback:
    - 8.8.8.8

坑3:

按如上的配置终于能正常进行运转了,但是使用vpn拨入内网的时候发现了一个新的问题,ocserv下发的no-route配置段不起作用了。所有的流量全部走VPN了。

原因:ocserv的no-route或者route字段只能对IP地址(段)起作用,无法针对域名。后续排查了很久后才找到原因是因为坑2新加的Fake IP功能导致所有的域名都在一个保留IP地址段下(198.18.0.0/24),客户端拿不到正确的IP地址,自然no-route是失效的。

解决方案:dns的前端还需要套一层dnsmasq或者其他的轻量dns服务器,同时对国内域名进行解析使得客户端拿到正确的IP地址,自然ocserv的no-route字段就生效了。

dnsmasq的国内域名解析列表可以参考这个项目,需要注意的是dnsmasq的上游需要指向clash的dns字段,clash的dns字段监听端口需要改成5353从而释放标准端口给dnsmasq使用:

 GitHub
felixonmars/dnsmasq-china-list
Chinese-specific configuration to improve your favorite DNS server. Best partner for chnroutes.

★ 5.6k

最终实现效果图:



https://hqyman.cn/zb_users/upload/2024/11/20241128112436_43570.png








ocserv配合clash+dnsmasq解决国内外分流问题


ocserv中通过route/no-route配置使得下发路由表到客户端,从而实现流量分流。大家一般通过该配置来选择哪些IP地址的路由需要到到服务端转发来解决路由流向的问题。

家庭宽带的上传一般来说比较小,或即使ocserv的服务端部署在大带宽服务器上,大家也希望尽量只有需要的流量才通过服务器中转,减少无用流量上VPN设备转发从而减少时延提升用户体验。但ocserv下发的路由表最多支持下发200条路由表。

为了尽可能的在200条路由表内塞下route或者no-route,大家发挥聪明才智通过合并cidr或者扩大cn的路由表范围等方式,有了很多优秀的no-route表,例如:

之前我也是通过这种方式进行分流,但使用中仍旧有很多不好的体验:

  • cn-no-route部分时候在openconnect中无效

  • 总容量200条,减去内网需要占用的条数,仍旧有较多路由重定向不准确

  • 在客户端无法有效的排错该路由是否走vpn隧道

  • 部分CN的IP如果想从vpn隧道通过,则改动非常大,且不一定能实现

我在部署本文引言中提到的透明代理时,突然想到,其实可以利用dnsmasq+clash的fake-ip功能一劳永逸解决分流的问题。

原理

Fake-IP定义可以参考 RFC3089,原理是客户端向clash服务端请求域名时,服务端会返回一个198.16.0.0/16的临时IP,并记录该IP与域名的对应关系用于后续发起请求时的访问。

有了这个原理,实现的过程就很简单了,只需要删除原来的所有no-route表,下发一个route表,涵盖内网IP段和198.16.0.0/16即可。

同时客户端的dns指向ocserv的dnsmasq的地址,设置需要调度到服务端的流量指向clash让其返回fake ip即可。

而dnsmasq分流没有ocserv的200条路由表(域名)限制,github上也有一个非常好的中国域名的解析列表。

使用方法为:dnsmasq的上游dns指定为clash的dns地址(若clash和dnsmasq在同一IP上,则需要修改clash的dns端口监听为非53端口,例如5353),配置文件使用如下仓库。

 GitHub
felixonmars/dnsmasq-china-list
Chinese-specific configuration to improve your favorite DNS server. Best partner for chnroutes.

★ 5.6k

ocserv的配置修改如下:

https://hqyman.cn/zb_users/upload/2024/11/20241128112441_88537.png

此时重启ocserv服务端后,客户端连接后则正确按照指定方式分流了。


使用该方法的缺点是只能通过dns解析的方式对流量进行调度,无法对直接访问IP的方式进行调度,不过可以在内网搭建一个xio解析服务变相的解决这个问题,

但以上仍然无法解决硬编码的IP地址问题,这种情况只能通过本地增加路由表解决。




推荐本站淘宝优惠价购买喜欢的宝贝:

image.png

以下内容需要兑换:

本文链接:https://hqyman.cn/post/8628.html 非本站原创文章欢迎转载,原创文章需保留本站地址!

分享到:
打赏





休息一下~~


« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

请先 登录 再评论,若不是会员请先 注册

您的IP地址是: