LXC – Netzwerkbrücke

LXC war mir ja schon ein Beitrag wert. Da ich sehr gerne damit arbeite gibt es noch einen.
Diesmal wird die Einrichtung ohne „libvirt“ beschrieben. Mich haben die Firewall-Regeln genervt deshalb wollte ich das Paket loswerden da ich auf meinem Cubie keinen weiteren Hypervisor o.ä. nutze.

Als erstes braucht man eine Netzwerkbrücke die die Daten von der „echten“ Netzwerkschnittstelle an  die Container übergibt. Hier kann man sich entscheiden zwischen einer richtigen Bridge oder ob man das ganze „DNAT-tet“ also ein weiteres Netzwerk welches die Container benutzen.

Vorteil der echten Bridge ist das es ohne iptables-geraffel auskommt. Die Container haben direkten Zugriff auf euer LAN, bekommen also z.b. einen IP von eurem DHCP-Server. Um von einem Client auf einen Container zugreifen zu wollen braucht man nirgens Einstellungen vornehmen zu müssen.

Wollt ihr hingegen das die Container ein eigenes Netzwerk benutzen kann man dies „NAT-ten“ um Zugriff von den Containern in die Welt zu bekommen. Soll hingegen ein Client Zugriff auf ein Container haben muss hier die route im Client zum Container eingetragen sein oder ihr fügt eine route in eurem Standard-Gateway hinzu wo hin er das Netz routen soll.

Der vollständigkeit möchte ich noch erwähnen das man auch mit VLAN arbeiten kann doch das ist selbst mir zu übertrieben bzw. habe ich einfach keine Lust darauf.

Kommen wir zur Konfiguration. Ich gehe von einer Netzwerkschnittstelle aus wie z.b. beim Cubie.

Für eine echte Bridge sollte eure /etc/network/interfaces wie folgt aussehen:

auto lo
iface lo inet loopback

# kann man weglassen - ich gehe lieber auf nummer sicher
iface eth0 inet manual

# für DHCP:
auto lxc-br0
iface lxc-br0 inet dhcp
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

# für statische adresse:
auto lxc-br0
iface lxc-br0 inet static
    address <ip-adresse>
    netmask <subnet>
    gateway <gateway>
    bridge_ports eth0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

Nach einem Neustart solltet ihr mit ifconfig oder ip a u.a. das Device „lxc-br0“ mit einer IP sehen.

Für eine „NAT-Bridge“ editiert eure /etc/network/interfaces so:

auto lo
iface lo inet loopback

# kann man weglassen - ich gehe lieber auf nummer sicher
iface eth0 inet manual

auto lxc-br0
iface lxc-br0 inet static
address <ip-adresse>
netmask <subnet>
bridge_ports none
bridge_stp off

post-up echo 1 > /proc/sys/net/ipv4/ip_forward
post-up iptables -t nat -F POSTROUTING
post-up iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

pre-down echo 0 > /proc/sys/net/ipv4/ip_forward
pre-down iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

In einem anderen Beitrag habe ich beschrieben wie ein lx-container erzeugt wird. Um die Netzwerkschnittstellen im Container als auch auf dem Host besser lesbar zu gestalten und vor allem zuordnen zu können könnt ihr folgendes zu der „config“ des Containers hinzufügen:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = lxc-br0
lxc.network.name = eth0
lxc.network.veth.pair = veth-webserver2
lxc.network.ipv4 = <ip-adresse/subnet>
lxc.network.ipv4.gateway = <gateway>
lxc.network.hwaddr = 00:1E:CH:AN:GE:ME

Zeile 3: brücke zur Virtuelle Schnittstelle (veth-*)
Zeile 4: Netzwerkschnittstellenname im Container
Zeile 5: Netzwerkschnittstellenname im Host

So hat man etwas Überblick.

Möchtet ihr jetzt Zugriff von außen auf den Container zugreifen kann man im Client eine route setzen wohin der Client die Verbindung aufbauen soll z.b.:

Host-IP: 192.168.0.1
Container-IP: 192.168.254.10
Client: 192.168.0.13

So würde die route wie folgt aussehen: route add -net 192.168.254.0/24 gw 192.168.0.1

Eine andere Möglichkeit ist es mit iptables auf dem Host eine Port-Weiterleitung einzurichten. Man gibt also nicht die IP-Adresse des Containers an sondern die des Host und die Firewall erkennt das ihr eigentlich woanders hinwollt. Dies nennt sich Destination-NAT. Um dies an ein Beispiel festzumachen, ihr habt einen Container in dem ein Webserver läuft den ihr erreichen wollt.

Folgendes Beispiel verwendet die gleichen Daten wie im obigen.
Gebt im Host folgende Zeilen ein und der Client kann eine Verbindung aufbauen:

iptables -t nat -A PREROUTING -d 192.168.0.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.254.10
iptables -t nat -A OUTPUT -d 192.168.0.1 -p tcp --dport 80 -j DNAT --to-destination 192.168.254.10

Und ihr erreicht euren Webserver.