目录

利用Docker、iptables、路由表搭建校园网代理

起因

因为疫情无法进入学校实验室,而学校实验室机房里的服务器被吊销了公网访问权限,只能使用学校的vpn进行访问。学校提供两种vpn,forticlient和深信服。这俩默认的vpn模式都是全局代理(tun模式),问题是学校对内网访问外网做了限速,只有30Mbps,所以就算家里是1000Mbps的光纤,连了vpn也只有30Mbps的公网带宽了。

为了解决这个问题,就需要分流,只将访问校内的流量导向vpn。

方案

如标题所说,最终选用docker作为容器(其实起初用docker是因为深信服的客户端简直毒瘤,不信的话可以看看deb包,解包开来的脚本里甚至还有gb2312编码的中文注释。。。希望以后可以改进,毕竟用的政企客户应该不少),使用openfortivpn作为管道,glider作为http转换,其实只要访问内网的话使用github现成的docker image就行

我最终没有选择这个方案的原因如下

  1. 校内的服务器需要http代理访问公网
  2. 我不希望在一个docker容器里面启动多个不相干的进程
  3. 顺便学习一下docker的网络

最后的方案是三个容器:

  1. forti:openfortivpn容器,会创建ppp0设备作为来往内网的隧道
  2. tunnel_to:使用glider监听8443,配合路由表实现本机的流量走容器8443穿透到学校内网
  3. tunnel_back:使用glider监听8443,配合forti的iptables做端口转发,实现内网机器访问vpn内网ip的8443端口能代理外网流量

openfortivpn在建立ppp设备后默认会更改默认路由表和dns,如果同时需要访问docker的dns 的话可能会有问题,因此需要仔细查看iptables和路由表的内容(2022年了docker还是只能用iptables,不能用nftables)

tunnel_to使用default路由导流所有流量去openforti容器时注意将docker内网的默认127.0.0.11路由规则否则默认的容器hostname解析就没有了。openforti容器接受tunnel_to来的流量后使用MASQURADE算法按照默认路由发出。

tunnel_back接受流量钱需要先经过openforti的iptables,因此不仅要做DNAT也要做SNAT否则tunnel_back不知道把响应数据包还给谁

成果

参见Github repo