Problembeschreibung
Ein Serversystem mit öffentlicher IP virtualisiert mehrere Gast(Server)systeme welche HTTP, MAIL, SVN(SSH) usw. bereitstellen. Als Virtualisierungslösung verwenden wir kvm mit libvirt. Als Netzwerkmodus wird "nat" verwendet, da die Gäste keine öffentlichen Adressen bekommen sollen. Die Standardkonfiguration lässt in diesen Modus die Kommunikation des Gasts nach aussen hin zu (MASQUERADING), schirmt diesen jedoch beim Zugriff auf ihn selbst ab. Dieses Problem können wir durch den gezielten Einsatz von Einträgen in den PREROUTING und FORWARDING Bereichen von iptables lösen.Im folgenden heisst unser Gastsystem "ssh-server" und hat die Gast-IP im privaten Subnetz von "192.168.100.10". Auf den Gast läuft ein SSH Server auf Port 22 dieser soll von aussen über Port 10000 über die öffentliche IP erreichbar sein.
Lösungsansatz
Libvirt unterstützt seit Version 0.8.0 hook Scripte. Diese werden bspw. beim starten/beenden/usw. des libvirt deamons oder auch beim starten/beenden/usw. von virtuellen Maschinen über qemu aufgerufen. Diese Funktionalität werden wir nutzen um die Gast spezifischen Firewall regeln zu realisieren.Als erstes erstellen wir also ein qemu hook Script und machen dies ausführbar.
touch /etc/libvirt/hooks/qemuLibvirt ruft dann später das Script u.a. beim Starten und Stoppen von Gästen mit folgenden Parametern auf
chmod +rx /etc/libvirt/hooks/qemu
- Objekt (z.B. Name des Gasts)
- Operation (z.B. start, stopped, reconnect, etc.)
- Unter-Operation oder "-"
- Extra-Argument oder "-"
Wir editieren nundas Script folgendermassen.
#!/bin/bashNun stoppen wir ggf. den Gast und machen das Script durch Neustarten des libvirt Deamons bekannt.
Guest="ssh-server"
Guest_ip="192.168.100.10"
if [[ $1 = $Guest ]]
then
if [[ $2 = "stopped" || $2 = "reconnect" ]]
then
iptables -t nat -D PREROUTING -p tcp --dport 10000 -j DNAT --to $Guest_ip:22
iptables -D FORWARD -d $Guest_ip/32 -p tcp -m state --state NEW -m tcp \
--dport 22 -j ACCEPT
fi
if [[ $2 = "start" || $2 = "reconnect" ]]
then
iptables -t nat -I PREROUTING -p tcp --dport 10000 -j DNAT --to $Guest_ip:22
iptables -I FORWARD -d $Guest_ip/32 -p tcp -m state --state NEW -m tcp \
--dport 22 -j ACCEPT
fi
fi
virsh destroy ssh-serverWenn alles funktioniert hat sollten keinerlei Fehlermeldungen im Log auftauchen und die iptables die entsprechenden Regeln enthalten.
/etc/init.d/libvirt-bin restart
virsh start ssh-server
tail -f /var/log/libvirt/libvirtd.log
iptables -L
Chain FORWARD (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere 192.168.100.10 state NEW tcp dpt:ssh
iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:10000 to:192.168.100.10:22
Referenzen
- http://www.jimscode.ca/index.php/component/content/article/19-linux/142-linux-port-forwarding-to-guest-libvirt-vms
- http://www.libvirt.org/hooks.html
Servus,
AntwortenLöschenVielen Dank für den Tipp,
Soweit hat das ganze auch geklappt ich sehe in den iptables die regeln , doch der Port ist nicht offen und ich kann von aussen nicht drauf.
Warum ? DIE VM läuft und hat auch den NAmen der angegeben ist,
Viele Grüße
Christian