Ubuntu 12.04 LXC nat 预路由不起作用

Ubuntu 12.04 LXC nat 预路由不起作用

我有一个正在运行的 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

相关内容