我有一个带有 VPN 的自定义容器,容器内有以下 iptables 规则:
# Flush all existing rules and chains
iptables -F
iptables -X
# Set default policies to DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP
# Allow loopback traffic (localhost)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# allow vpn to be connected
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
while IFS=' ' read -r host port; do
iptables -A OUTPUT -o eth0 -p udp --dport $port -d $host -j ACCEPT
done < "/tmp/entries"
iptables -A OUTPUT -o ${VPN_DEVICE} -j ACCEPT
# allow vnc to be connected
iptables -A INPUT -i eth0 -p tcp --dport 5800 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 5800 -m state --state ESTABLISHED -j ACCEPT
# allow deluge to be connected
iptables -A INPUT -i eth0 -p tcp --dport 8112 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 8112 -m state --state ESTABLISHED -j ACCEPT
# allow deluge to access external world
iptables -A INPUT -i ${VPN_DEVICE} -p tcp --dport 6881:6891 -j ACCEPT
iptables -A OUTPUT -o ${VPN_DEVICE} -p tcp --dport 6881:6891 -j ACCEPT
iptables -A INPUT -i ${VPN_DEVICE} -p udp --dport 6881:6891 -j ACCEPT
iptables -A OUTPUT -o ${VPN_DEVICE} -p udp --dport 6881:6891 -j ACCEPT
整个想法是默认丢弃所有进/出流量;仅允许 eth0 的 vpn 服务器输出流量;允许 eth0 公开端口 5800 和 8112 以访问我的服务;通过 VPN 设备将 torrent 客户端公开到外部世界。
此外,我还有以下撰写文件来启动上述带有 iptables 规则的容器:
version: "2.1"
services:
vpn:
build: ./
cap_add:
- NET_ADMIN
devices:
- /dev/net/tun
volumes:
- ./volumes/vpn-config:/vpn-config
- ./volumes/deluge-config:/deluge-config
- ./volumes/downloads:/downloads
- ./volumes/firefox-profile:/config
- ./volumes/downloads:/config/downloads
ports:
- 40001:5800
- 40002:8112
restart: unless-stopped
这里的主要问题 - 端口 40001 和 40002 在主机上运行良好,但在来自同一网络的其他机器上无法运行。而其他容器的暴露端口则正常(使用 nginx hello-world 容器进行测试)。
这里有什么可疑的地方我可以更改或注意以确保端口 40001 和 40002 可以从其他机器访问吗?
答案1
好的,原始问题与 iptables 无关,一切都与路由有关。假设我有192.168.31.0/24
主机外部网络。
默认情况下,docker 添加这样的路由:
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
然后 Openvpn 添加类似这样的内容,通过 vpn 的默认路由:
0.0.0.0/1 via 1.2.3.4 dev tun0 # this comes from openvpn
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link src 172.17.0.2
在第一种情况下,所有数据包都192.168.31.0/24
将发往172.17.0.1
主机,主机会将其重新路由到适当的位置。
VPN 连接后,所有这些流量都将转到1.2.3.4
。它仍然适用于主机,因为172.17.0.0/16
存在来自 docker 的路由。
不幸的是,我不知道优雅的路由/iptables 解决方案可以自动解决此问题。
简单的解决方案是启动代理服务器(通过附加的docker-compose服务; http或TCP,或任何合适的服务)以代理暴露给外界的端口。