Daniels Blog

Debian Jessie LXC networking. Containers with public and NATed IPs

It took me some time to get this working so it's time for a blog post:

This was a setup for a server in a data center with a public IP address. The server has one physical interface with a public routable IP address. Additionaly I ordered another public IP address for the server to be used in one of the LXC containers.

I have two containers.

Container A
"A" gets a public routable IP-address to be reachable from the internet without NATing

Container B
"B" gets a private IP address and can only be reached thru NAT and port-mappings

Host has as main public IP
Container A has as "virtual" IP
Container B has as NATed private IP



auto lo
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet manual
   pre-up   ifconfig eth0 up
   pre-down ifconfig eth0 down

auto  br0
iface br0 inet static
  broadcast broadcast.ip
  netmask   netmask.ip
  gateway   gateway.ip
  bridge_ports eth0
  bridge_fd 0
  bridge_maxwait 0

auto  br1
iface br1 inet static
  bridge_fd 0
  bridge_maxwait 0
  pre-up brctl addbr br1
  up iptables -t nat -F POSTROUTING

  # Exclude boxes with static IPs from Natting
  up iptables -A PREROUTING -t nat -i br0 -p tcp -s -j ACCEPT

  # Enable Forwarding for NATed boxes
  up iptables -t nat -A POSTROUTING -s -o br0 -j MASQUERADE

  # example PORT FORWARDINGS FOR Mailserver
  up iptables -A PREROUTING -t nat -i br0 -p tcp --dport 25 -j DNAT --to
  up iptables -A PREROUTING -t nat -i br0 -p tcp --dport 465 -j DNAT --to
  up iptables -A PREROUTING -t nat -i br0 -p tcp --dport 587 -j DNAT --to

  # example PORT FORWARDINGS FOR Webserver
  up iptables -A PREROUTING -t nat -i br0 -p tcp --dport 80 -j DNAT --to
  up iptables -A PREROUTING -t nat -i br0 -p tcp --dport 443 -j DNAT --to

  post-down iptables -F
  post-down iptables -t nat -F
  post-down brctl delbr br1

#IP forwarding must be enabled in the kernel as well (don't forget reboot)

CONTAINER A Setup (static virtual public IP):

lxc.utsname = containershostname
lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0

# This is the MAC for the public IP i got from my provider
# container gets IP by providers DHCP
lxc.network.hwaddr = 00:11:22:33:44:55

CONTAINER B Setup (static NATed private IP):

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br1
lxc.network.ipv4.gateway =

Keep it simple – Very basic iptables

Iptables können ziemlich verwirrend sein. Deshalb habe ich, um einen Grundstock zu schaffen, ein ganz simples Skript gebastelt. Standardmässig sind keine Ports von außen erreichbar, gewünschte Ports müssen explizit freigegeben werden. Von innen initiierte Verbindungen funktionieren, Verbindungen mit den freigegebenen Ports auch. Kann man es noch weiter vereinfachen?


# alle bestehenden Regeln löschen
iptables -F

# Standardmässig eingehende Verbindungen verbieten
iptables -P INPUT DROP

# Standardmässig ausgehende Verbindungen erlauben

# Nicht routen
iptables -P FORWARD DROP

# localhost darf alles
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# Eingehende Verbindungen für SSH und HTTP erlauben
iptables -A INPUT -j ACCEPT -p tcp --dport 22
iptables -A INPUT -j ACCEPT -p tcp --dport 80

# Eingehende Verbindungen erlauben, die sich auf bestehende Verbindungen
# beziehen. (Damit es nach dem Verbindungsrequest eines Clients auch weitergeht)
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT