部署透明代理服务器
最近需要手动Building一个vSonic,但默认环境无法访问外网,很多依赖关系无法解决,所以打算安装一个透明代理,让Building时走代理服务器。其实很早之前我就想在家里安装一个linux,用它来实现代理功能,这样干净好用。想法很简单,实现起来发现涉及很多问题,最终还是通过OpenWRT来实现这个需求。这里梳理下涉及的几种方法:
- 直接在Building Server上安装代理服务器,然后让流量走代理,具体可以参考这篇文章。这种方法如果只是实现HTTP,HTTPS代理,那没什么问题,但如果需要考虑APT,Docker,Docker Building等相关程序,那就需要在每个程序中单独指定代理,不同程序方法也不一样,不推荐。下面是参考文章中的几个关键步骤:
- 在ubuntu上安装了xxx Client,去连接外网的kvm,此时是Socket5的代理;
- HTTP无法使用Socket5的代理,因此通过Privoxy把Socket5转成HTTP的代理;
- 最后把HTTP和HTTPS代理设置成Privoxy的端口;
- 同上面类似,但需要通过IPtables指向Privoxy的代理端口,这里有很多需要注意的地方,方法同第3种;
- 如果好几台Server都需要访问外网,那么都需要配置IPtables,这样会非常麻烦,可以把IPtables的配置挪到一台单独的代理服务器上,类似于家用的旁路由场景(后面单独一个章节介绍这种方法,虽然没成功,有时间了可以继续研究);
- 最后一种最简单,直接使用OpenWRT来完成繁琐的IPtables操作,由于OpenWRT已经非常成熟,很多配置都会默认自动加载,通过这个来完成此需求(后面单独一个章节介绍这种方法,成功);
Topology
本Blog只讨论独立Proxy的部署方式,Building Server只需要把GW指向Proxy Server:

Proxy Server by IPtables
注意:
- 这种方法没尝试成功,当时的现象:在Building Server上,DNS无法解析域名;
- Building Server GW设置成Proxy的IP地址;
# 删除IPtables 默认Chain,NAT Chain以及Mangle Chain
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -t mangle -F
# 查看这3个Chain的详细信息
sudo iptables -nvL --line-number
sudo iptables -t nat -nvL --line-number
sudo iptables -t mangle -nvL --line-number
# 建立一个VRF路由1,标记123
sudo ip rule add fwmark 123 table 1
# 在Mangle中建立一个table xxx
sudo iptables -t mangle -N xxx
# 目的地址为四大私网,组网,以及UDP报文,均不在此Table中执行,防止无限loop
sudo iptables -t mangle -A xxx -d 0.0.0.0/8 -j RETURN
sudo iptables -t mangle -A xxx -d 127.0.0.0/8 -j RETURN
sudo iptables -t mangle -A xxx -d 10.0.0.0/8 -j RETURN
sudo iptables -t mangle -A xxx -d 172.16.0.0/12 -j RETURN
sudo iptables -t mangle -A xxx -d 192.168.0.0/16 -j RETURN
sudo iptables -t mangle -A xxx -d 169.254.0.0/16 -j RETURN
sudo iptables -t mangle -A xxx -d 224.0.0.0/4 -j RETURN
sudo iptables -t mangle -A xxx -d 240.0.0.0/4 -j RETURN
sudo iptables -t mangle -A xxx -p udp -j RETURN
# 所有TCP流量会使用透明代理TPPROXY功能,并指向端口8118,并送到VRF中
sudo iptables -t mangle -A xxx -p tcp -j TPROXY --on-port 8118 --tproxy-mark 123
# 在VRF路由中,把流量指向lo,这样相当于送到主机上,让代理处理流量
sudo ip route add local 0.0.0.0/0 dev lo table 1
# 在Mangel的PREROUTING chain上调用此策略
sudo iptables -t mangle -A PREROUTING -j xxx
Proxy Server by OpenWRT
从这里https://openwrt.ai下载EXSI x86版本的OpenWRT,然后转换成qcow2(注意不要选择efi-flat,要选择那个比较小的vmdk文件),放入Image文件夹中,直接使用即可,即可正常boot:
# qemu-img convert -f vmdk -O qcow2 openwrt-11.19.2023-x86-64-generic-squashfs-combined-efi.vmdk hda.qcow2
# ll
total 1128096
-rw-r--r-- 1 root root 84541440 Jan 20 13:51 hda.qcow2
-rw-r--r-- 1 root root 1070628352 Dec 30 16:17 openwrt-11.19.2023-x86-64-generic-squashfs-combined-efi-flat.vmdk
-rw-r--r-- 1 root root 10240 Dec 30 16:17 openwrt-11.19.2023-x86-64-generic-squashfs-combined-efi.vmdk
# mv hda.qcow2 /opt/unetlab/addons/qemu/linux-openwrt/
Openwrt的配置,我就不在这里详细说明了,简单列了下:
- 配置旁路由模式,选择手动配置IP相关信息;
- 关闭DHCPv4服务,其他均默认;
- 订阅海外节点,选择对应节点;
下面是几张截图,方便查阅:


下面是OpenWRT Iptables的配置备份:
注意:把Building Server的GW改成OpenWRT后,你会发现从外面无法SSH,是因为“外网 -> 内网”,“内网 -> 外网”,路径不一致。如果走了旁路由,原地址就被改变了,所以3次握手无法达成,需要用下面方法把SSH的报文单独走另一个网关,这样就解决此问题了:
$ sudo ip route add default via 10.22.1.1 table 11
$ sudo iptables -t mangle -A OUTPUT -p tcp --sport 22 -j MARK --set-mark 1
$ sudo ip rule add fwmark 1 table 11
下面是端口及默认路由配置:
$ more /etc/netplan/00-installer-config.yaml
network:
ethernets:
ens3:
dhcp4: no
addresses:
- 10.22.1.223/24
routes:
- to: 0.0.0.0/0
via: 10.22.1.227
nameservers:
addresses:
- 10.22.1.227
version: 2