Centos 7 VM/Portumleitung

Aus Hyperweb & OpenSim
Wechseln zu: Suche

Statische IP Adresse für den Guest

Vorbereitung: Wir benötigen später die Namen der realen Netzwerkkarte des Hosts und der virtuellen Netzwerkkarte des Guests. Dafür starten wir die Virtuelle Maschine noch mal kurz (Befehle siehe vorherige Seite). Während sie läuft, geben wir folgendes in der Kommandozeile ein:

arp -ae

Als Ausgabe erscheint eine Auflistung von Netzwerkanschlüssen. Jeweils die erste Spalte ist die IP-Adresse. Daran sollten wir unsere reale Netzwerkkarte erkennen, die an der vom Provider vergebenen externen IP hängt. Es folgen ggf. mehrere virtuelle Netzwerkkarten, die mit Hilfe ihrer MAC Adressen (dritte Spalte) identifiziert werden können. Die letzte Spalte zeigt die Namen der Netzwerkkarten im System.

Die MAC-Adresse der virtuellen Netzwerkkarte des Guests können wir in einer Konfigurationsdatei nachschauen, falls der obige Befehl mehrere vituelle Karten fand.

vi /etc/libvirt/qemu/Centos7.xml

In der XML-Datei sind die folgenden Zeilen mit einer MAC Adresse.

...
<interface type='network'>
  <mac address='11:22:33:44:55:66'/>
  <source network='default'/>
...

Wenn wir von außen den Guest erreichen wollen, müssen wir dessen IP-Adresse kennen. Deshalb legen wir sie mit einem kleinen Trick selber fest. Dafür ändern wir die Konfiguration des Netzwerkes "default". Das folgende Kommando öffnet eine temporäre XML-Datei im Editor vi, deren Inhalt beim Verlassen interpretiert und gespeichert wird.

virsh net-edit default

Absatz finden...

<dhcp>
  <range start='192.168.122.2' end='192.168.122.254'/>
</dhcp>

Wir ergänzen eine neue Zeile <host ... /> mit der ermittelten Mac-Adresse und einer willkürlichen IP-Adresse im vorgegebenen Bereich (hier also zwischen 192.168.122.2 und 192.168.122.254).

<dhcp>
  <range start='192.168.122.2' end='192.168.122.254'/>
  <host mac='11:22:33:44:55:66' name='virbr0' ip='192.168.122.42'/>
</dhcp>

Der Trick besteht darin, dass die IP-Adressen zwar weiterhin mit DHCP automatisch zugeteilt werden, jedoch die Netzwerkkarte des Guests immer "zufällig" die selbst gewählte IP bekommt.

Internet Ports auf den Guest umleiten

Beim Start einer Virtuellen Maschine wird die iptables Firewall automatisch so verändert, dass der Guest ins Internet hinaus kann. Die Gegenrichtung vom Internet in den Guest wird blockiert. Leider hilft es nicht unsere eigene Firewall anzupassen, da diese Änderungen nachträglich zur Laufzeit erfolgen. Der hier beschriebene Hack besteht aus einem Shellscript, das jedesmal beim Starten und Stoppen der Virtuellen Maschine aufgerufen wird, und die gewünschten Ports umleitet:

vi /etc/libvirt/hooks/qemu
#!/bin/bash
#
# /etc/libvirt/hooks/qemu 

### Config the following variables to fit your setup! ###
Host_ipaddr=11.22.33.44
eth=eth0
Guest_name=Centos7
Guest_ipaddr=192.168.122.42
vir=virbr0
Host_tcp_port=( '2222' '9000' )
Guest_tcp_port=( '22' '9000' )
Udp_port=( '9050' '9051' )
### End of config section! ###

if [ "${1}" = "${Guest_name}" ]; then
  length=$(( ${#Host_tcp_port[@]} ))
  if [[ $length -gt 0 ]]; then
    length=`expr $length - 1`
    if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
      for i in `seq 0 $length`; do
        iptables -t nat -D PREROUTING -p tcp ! -i ${vir} --dport ${Host_tcp_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_tcp_port[$i]}
        iptables -D FORWARD -d ${Guest_ipaddr}/32 -p tcp -o ${vir} --dport ${Guest_tcp_port[$i]} -m conntrack --ctstate NEW -j ACCEPT
      done
    fi
    if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
      for i in `seq 0 $length`; do
        iptables -t nat -I PREROUTING -p tcp ! -i ${vir} --dport ${Host_tcp_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Guest_tcp_port[$i]}
        iptables -I FORWARD -d ${Guest_ipaddr}/32 -p tcp -o ${vir} --dport ${Guest_tcp_port[$i]} -m conntrack --ctstate NEW -j ACCEPT
      done
    fi
  fi
  length=$(( ${#Udp_port[@]} ))
  if [[ $length -gt 0 ]]; then
    length=`expr $length - 1`
    if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
      for i in `seq 0 $length`; do
        iptables -t nat -D PREROUTING -p udp ! -i ${vir} --dport ${Udp_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Udp_port[$i]}
        iptables -t nat -D POSTROUTING -p udp -s ${Guest_ipaddr} --sport ${Udp_port[$i]} -j SNAT --to ${Host_ipaddr}:${Udp_port[$i]}
        iptables -D FORWARD -p udp --sport ${Udp_port[$i]} -o ${eth} -i ${vir} -j ACCEPT
        iptables -D FORWARD -p udp --dport ${Udp_port[$i]} -o ${vir} -i ${eth} -j ACCEPT
      done
    fi
    if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
      for i in `seq 0 $length`; do
        iptables -t nat -I PREROUTING -p udp ! -i ${vir} --dport ${Udp_port[$i]} -j DNAT --to ${Guest_ipaddr}:${Udp_port[$i]}
        iptables -t nat -I POSTROUTING -p udp -s ${Guest_ipaddr} --sport ${Udp_port[$i]} -j SNAT --to ${Host_ipaddr}:${Udp_port[$i]}
        iptables -I FORWARD -p udp --sport ${Udp_port[$i]} -o ${eth} -i ${vir} -j ACCEPT
        iptables -I FORWARD -p udp --dport ${Udp_port[$i]} -o ${vir} -i ${eth} -j ACCEPT
      done
    fi
  fi
  if [ "${2}" = "stopped" ] || [ "${2}" = "reconnect" ]; then
    iptables -D FORWARD -i ${vir} -o ${vir} -j ACCEPT
  fi
  if [ "${2}" = "start" ] || [ "${2}" = "reconnect" ]; then
    iptables -I FORWARD -i ${vir} -o ${vir} -j ACCEPT
  fi
fi

Konfiguration des Scriptes:

Host_ipaddr ist die IP-Adresse des Hosts, also die des realen Servers. Normalerweise wird sie vom Provider vergeben.

eth ist der Name der realen Netzwerkkarte des Hosts in der Betriebssystemkonfiguration des Hosts.

Guest_name ist der von uns für die KVM Administration vergebene Name der Virtuellen Maschine, hier "Centos7".

Guest_ipaddr ist die interne IP-Adresse auf dem Host. Hier in der Anleitung hatten wir sie auf 192.168.122.42 gesetzt.

vir ist der Name der virtuellen Netzwerkkarte des Guests in der Betriebssystemkonfiguration des Hosts. Der Name wurde von QEMU festgelegt.

Host_tcp_port=( '2222' '9000' ) und Guest_tcp_port=( '22' '9000' ) ist die Tabelle mit den TCP/IP Portumleitungen. Diese Listen enthalten nur die Ports, die vom Internet aus auf den Guest umgeleitet werden sollen! Die Gegenrichtung ins Internet hinein funktioniert schon per Voreinstellung. Hier im Beispiel wird der Port 2222 (für SSH) auf Port 22 des Guests umgeleitet, außerdem der Port 9000 (für OpenSim) auf die gleiche Portnummer des Guests. Beide Listen müssen logischerweise genauso viele Einträge haben.

Udp_port=( '9050' '9051' ) ist die Liste mit den UDP/IP Portumleitungen. Ich habe in dem Script auf eine Unterscheidung zwischen Host und Guest verzichtet, jeder UDP Port vom Host wird also auf die gleiche Portnummer des Guests umgeleitet.

Unser neues Script benötigt nun noch Execute-Rechte:

chmod +x /etc/libvirt/hooks/qemu

Damit all die Konfigurationen wirksam werden, booten wir den Host einmal durch:

shutdown -r now

Hinweis: Der OpenSim Regionenserver benutzt standardmäßig den TCP/IP Port 9000. Will man auf der selben externen IP-Adresse mehrere OpenSim Instanzen gleichzeitig laufen lassen, müssen sie auf unterschiedlichen Ports arbeiten. Dies wird in der OpenSim.ini konfiguriert (http_listener_port = ... ). Die einzelnen Regionen sind über UDP/IP Ports erreichbar, diese werden in der Regions.ini konfiguriert (InternalPort = ... ).

Hinweis: Jeder auf den Guest umgeleitete Port ist auf dem Host vom Internet aus nicht mehr erreichbar, braucht also auch in der Firewall des Hosts nicht berücksichtigt zu werden.

Achtung! Falls du über ein Terminal mit einem entfernten Server verbunden bist, leite nicht den SSH Port des Hosts um. Sonst sperrst du dich selber aus!

Abschließender Test der Installation:

Wichtig ist, dass dieser Test wirklich direkt aus dem Internet heraus erfolgt! Es darf kein Konsolenfenster verwendet werden, worin du bereits auf dem Host-Server eingeloggt bist. Öffne dafür zur Sicherheit zum Beispiel eine neue Konsole auf dem heimischen Linux-Rechner, oder verwende PuTTY auf einem Windows-Rechner.

Vom Internet aus gesehen hat der Guest nun die gleiche IP-Adresse wie der Host, also die vom Internet-Provider zugeteilte Adresse. Als vom Internet sichtbaren SSH Port haben wir oben im Beispiel Port 2222 konfiguriert. Der (noch) einzige User auf dem Guest ist root.

Wenn wir uns als root mit dem während der CentOS Installation vergebenen Passwort einloggen können, dann ist der Guest nun aus dem Internet erreichbar.

Den Guest automatisch starten

Wenn der obige Test erfolgreich war, kann die Virtuelle Maschine mit dem CentOS Guest zukünftig bei jedem Systemstart automatisch mit hochgefahren werden, falls sie (z.B. als Regionenserver) dauerhaft mitlaufen soll.

virsh autostart Centos7

Den Autostart bei Bedarf wieder deaktivieren: "virsh autostart Centos7 --disable"



Weiter: CentOS auf dem Guest konfigurieren