我有一个正在运行的 Debian Wheezy 设置,我将其精确复制到 Ubuntu 12.04
虽然 Debian 的设置运行完美,但 Ubuntu 版本在预路由到容器时失败了(或者看起来如此)
简而言之:
- lxc 工作原理
- 容器工作并运行
- 从主机连接到容器正常(包括混合端口和服务)
- 从容器连接到外界是可以的
不起作用的是从另一个盒子通过应该被 NAT 到容器的端口连接到主机。
设置:
/etc/rc.local
CMD_BRCTL=/sbin/brctl
CMD_IFCONFIG=/sbin/ifconfig
CMD_IPTABLES=/sbin/iptables
CMD_ROUTE=/sbin/route
NETWORK_BRIDGE_DEVICE_NAT=lxc-bridge
HOST_NETDEVICE=eth0
PRIVATE_GW_NAT=192.168.42.1
PRIVATE_NETMASK=255.255.255.0
PUBLIC_IP=192.168.13.100
${CMD_BRCTL} addbr ${NETWORK_BRIDGE_DEVICE_NAT}
${CMD_BRCTL} setfd ${NETWORK_BRIDGE_DEVICE_NAT} 0
${CMD_IFCONFIG} ${NETWORK_BRIDGE_DEVICE_NAT} ${PRIVATE_GW_NAT} netmask ${PRIVATE_NETMASK} promisc up
因此 lxc 网络是 192.168.42.0/24 并且主机 eth0 ip 是 192.168.13.100;通过网络管理器设置为静态地址。
iptables:
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT
*filter
:FORWARD ACCEPT [0:0]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
# Accept traffic from internal interfaces
-A INPUT -i lo -j ACCEPT
# accept traffic from lxc network
-A INPUT -d 192.168.42.1 -s 192.168.42.0/24 -j ACCEPT
# Accept internal traffic Make sure NEW incoming tcp connections are SYN
# packets; otherwise we need to drop them:
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
# Packets with incoming fragments drop them. This attack result into Linux server panic such data loss.
-A INPUT -f -j DROP
# Incoming malformed XMAS packets drop them:
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# Incoming malformed NULL packets:
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# Accept traffic with the ACK flag set
-A INPUT -p tcp -m tcp --tcp-flags ACK ACK -j ACCEPT
# Allow incoming data that is part of a connection we established
-A INPUT -m state --state ESTABLISHED -j ACCEPT
# Allow data that is related to existing connections
-A INPUT -m state --state RELATED -j ACCEPT
# Accept responses to DNS queries
-A INPUT -p udp -m udp --dport 1024:65535 --sport 53 -j ACCEPT
# Accept responses to our pings
-A INPUT -p icmp -m icmp --icmp-type echo-reply -j ACCEPT
# Accept notifications of unreachable hosts
-A INPUT -p icmp -m icmp --icmp-type destination-unreachable -j ACCEPT
# Accept notifications to reduce sending speed
-A INPUT -p icmp -m icmp --icmp-type source-quench -j ACCEPT
# Accept notifications of lost packets
-A INPUT -p icmp -m icmp --icmp-type time-exceeded -j ACCEPT
# Accept notifications of protocol problems
-A INPUT -p icmp -m icmp --icmp-type parameter-problem -j ACCEPT
# Respond to pings, but limit
-A INPUT -m icmp -p icmp --icmp-type echo-request -m state --state NEW -m limit --limit 6/s -j ACCEPT
# Allow connections to SSH server
-A INPUT -p tcp -m tcp --dport 22 -m state --state NEW -m limit --limit 12/s -j ACCEPT
COMMIT
*nat
:OUTPUT ACCEPT [0:0]
:PREROUTING ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -d 192.168.13.100 -p tcp -m tcp --dport 2221 -m state --state NEW -m limit --limit 12/s -j DNAT --to-destination 192.168.42.11:22
-A PREROUTING -d 192.168.13.100 -p tcp -m tcp --dport 80 -m state --state NEW -m limit --limit 512/s -j DNAT --to-destination 192.168.42.11:80
-A PREROUTING -d 192.168.13.100 -p tcp -m tcp --dport 443 -m state --state NEW -m limit --limit 512/s -j DNAT --to-destination 192.168.42.11:443
-A POSTROUTING -d 192.168.42.0/24 -o eth0 -j SNAT --to-source 192.168.13.100
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT
系统控制:
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.all.mc_forwarding = 0
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.mc_forwarding = 0
net.ipv4.ip_forward = 1
我已经在容器上设置了完整的 iptables 日志;所有发往 192.168.13.100、端口 80 的数据包都无法到达容器。
我甚至尝试了不同的内核(服务器内核、raring lts 内核等),modprobe 所有与 iptables 和 nat 相关的东西,都没有用。有什么想法吗?
答案1
好吧,那是一个令人讨厌的“错误”。默认情况下,lxc 根据 255.0.0.0 网络掩码设置内部网络。因此,内部 lxc 网络也会尝试在 lxc 网络内查找 192.168.13.0 的主机,但永远不会返回该主机。
修复:在容器配置文件中,IP 地址应该是 192.168.42.10/24,而不是 192.168.42.10。
tcpdump 是一个方便的工具。
答案2
您的 *nat 表中有“-m limit --limit x/s”。遗憾的是,诸如限制和删除之类的功能在 *nat 中不起作用。您需要对 192.168.42.11 lxc 的 iptables INPUT 设置限制。
有一种方法是可行的,如果你有在它到达 DNAT 之前将其阻止。
-A PREROUTING -d 192.168.13.100 -p tcp -m tcp --dport 2221 -m state --state NEW -m connlimit --connlimit-above 10 --connlimit-mask 32 -j DNAT --to-destination 127.0.0.1
-A PREROUTING -d 192.168.13.100 -p tcp -m tcp --dport 2221 -m state --state NEW -j DNAT --to-destination 192.168.42.11:22