Docker容器中基于端口的路由

时间:2016-03-25 07:34:24

标签: ssh docker iptables

我有一个docker应用程序容器(node:latest image),它有两个网络接口:

  • eth1:这是默认界面,是服务中所有容器之间的桥接网络。 (由pipework管理,但我无法更改该级别的任何内容)
  • eth0:这是一个常规的docker0界面,可以访问eth1以外的所有地方。

这是默认的路由表:

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.25.88.254    0.0.0.0         UG    0      0        0 eth1
10.25.88.0      0.0.0.0         255.255.255.0   U     0      0        0 eth1
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 eth0

如您所见,有必要将eth1作为默认界面,但它会导致我出现问题:我的应用程序需要ssh访问其他一些无法通过{{1}访问的远程服务器但eth1有权访问。所以我需要改变这个请求的路由。我的第一个解决方案是:

eth0

这种方法很好用,我可以访问route add -net 10.20.33.0/24 gw 172.17.42.1 范围内的那些地址。但它会阻止从这些主机访问应用程序本身。应用程序在端口80上提供,并且在添加此路由后,来自范围10.20.33.0/24中的主机的所有请求都将失败。

所以我认为该路由是如此全局并且影响对该IP范围的所有输入/输出请求。我搜索了一种方法,只是在stackoverflow上路由输出ssh请求,到目前为止这就是我所拥有的:

10.20.33.0/24

但它不起作用。我试图通过# Initialize route table echo 1 p.ssh > /etc/iproute2/rt_tables ip route add table p.ssh default via 172.17.42.1 # Mark Packet with matching D.Port iptables -A PREROUTING -t mangle -p tcp --dport 22 -j MARK --set-mark 1 iptables -A POSTROUTING -t nat -o eth0 -p tcp --dport 22 -j SNAT --to 172.17.42.1 #IP Route ip rule add fwmark 1 table p.ssh ip route flush cache #IP Stack #This is the missing part from the guide echo 1 > /proc/sys/net/ipv4/ip_forward for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $f ; done echo 0 > /proc/sys/net/ipv4/route/flush 记录标记的包,所以也许我可以在流程中发现任何问题,但iptables没有在容器内运行,所以我安装了它syslog并添加了这条规则:

apt-get install rsyslog

但它也没有记录任何东西。

1 个答案:

答案 0 :(得分:3)

几天后我就能解决这个问题了。我使用了以下tcpdump来查看流量是否通过eth0接口进行路由:

tcpdump -i eth0 port ssh

事实证明,第一个问题来自iptables标记命令。因此,我不是在PREROUTING链上标记请求,而是在OUTPUT链上标记它们,如下所示:

iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 1

现在我能够在eth0上看到ssh请求,但仍然无法连接。事实证明,这些请求需要伪装才能正常运行:

iptables --table nat --append POSTROUTING -o eth0 -p tcp --dport 22 -j MASQUERADE

最终的脚本现在就像:

REMOTE_HOSTS=10.20.33.0/24
HOSTS_ADDR=172.17.42.1

# Add table
echo 1 p.ssh >> /etc/iproute2/rt_tables
# Add route
ip rule add fwmark 1 table p.ssh
ip route add $REMOTE_HOSTS via $HOSTS_ADDR dev eth0 table p.ssh

# Sets mark correctly
iptables -t mangle -A OUTPUT -p tcp --dport 22 -j MARK --set-mark 1
iptables --table nat --append POSTROUTING -o eth0 -p tcp --dport 22 -j MASQUERADE

#IP Stack
echo 1 > /proc/sys/net/ipv4/ip_forward     # Default in debian/ubuntu
for f in /proc/sys/net/ipv4/conf/*/rp_filter ; do echo 0 > $f ; done