虚拟机多出口提供服务

背景

我在本地硬件服务器VM HOST中通过qemu创建一个虚拟机,并且在虚拟机VM1中部署了一个openvpn服务,它的IP地址是10.89.103.14;
因为硬件服务器配置了两个出口,但是呢虚拟机VM1的默认路由是走的其中一条线路,当通过另一条线路的公网IP访问进来的流量就没法路由了。
我的环境是:
VM HOST: Linux
VM1: Linux
我的拓扑如下:
Image

配置

我的配置如下仅仅做下记录,也是研究了很久才搞定的,大致的原理是通过iptables在VM HOST进行匹配特定IP和端口的流量然后将流量设置特定的tos,然后流量会流进到虚拟机VM1,VM1再通过匹配不同tos的流量将其进行mark;因为这个mark是链路级别的,当数据到达应用程序进行处理后出去的流量也会带上mark,后面再将mark的流量设置不同的tos;至于为什么还要设置tos,我的理解是tos是跨主机的标记,mark是当前机器链路级别的标记。当然如果没有匹配到tos的流量还是会走到默认路由的。
因为虚拟机VM1出去的流量也设置了tos,所以流量包到达VM HOST的时候就会进行匹配策略路由,将标记不同的tos的流量选择不同的路由表进行路由,至此就能做到多出口的提供服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
内部机器VM1(如果里面的机器还是DNAT,还得在DNAT的目标主机里添加规则进行标记):
iptables -t mangle -A PREROUTING -m tos --tos 0x02 -j MARK --set-mark 2
iptables -t mangle -A PREROUTING -m tos --tos 0x04 -j MARK --set-mark 4
iptables -t mangle -A PREROUTING -j CONNMARK --save-mark
iptables -t mangle -A OUTPUT -m mark ! --mark 0 -j RETURN
iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark
iptables -t mangle -A OUTPUT -m mark --mark 2 -j TOS --set-tos 0x02
iptables -t mangle -A OUTPUT -m mark --mark 4 -j TOS --set-tos 0x04

外面机器VM HOST:
iptables -t mangle -A PREROUTING -d 10.88.100.14 -p tcp --dport 9000 -j TOS --set-tos 0x02
iptables -t mangle -A PREROUTING -d 192.168.100.14 -p tcp --dport 9000 -j TOS --set-tos 0x04
iptables -t mangle -A PREROUTING -d 10.88.100.14 -p tcp --dport 6789 -j TOS --set-tos 0x02
iptables -t mangle -A PREROUTING -d 192.168.100.14 -p tcp --dport 6789 -j TOS --set-tos 0x04

ip rule add tos 0x02 table 10
ip rule add tos 0x04 table 20
ip route add default via 10.88.100.1 table 10
ip route add 10.89.103.0/24 dev virbr0 proto kernel scope link src 10.89.103.1 table 10
ip route add default via 192.168.100.1 table 20
ip route add 10.89.103.0/24 dev virbr0 proto kernel scope link src 10.89.103.1 table 20