[linux-l] Virtuelle Maschinen und IPv6

Volker Grabsch v at njh.eu
Sa Mär 8 13:17:13 CET 2014


Liebe Liste,

mir ist aufgefallen, dass ich euch noch gar berichtet habe,
was aus dem Virtualisierungs-Projekt geworden ist.

Erstmal vielen Dank für die vielen Antworten, da waren
sehr gute Anregungen dabei! Das meiste hat allerdings
nicht so funktioniert wie erhofft. Letztendlich habe ich
das folgendermaßen gelöst:

* Pro VM ein eigenes TAP-Device.

* Jede VM hat ihr Netzwerk fest konfiguriert.

* Auf jedem TAP-Device ein eigenes kleines IPv6-Subnetz "xxx",
  in dem "xxx::0" das Host-System und "xxx::1" die VM ist.
  Dadurch kann sich die VM auch weitere IPv6-Adressen nehmen,
  wenn sie will: "xxx::2", "xxx::3", ...

* Außerdem pro TAP-Device eine IPv4-Adresse, die ich via Option
  pointopoint ("peer") einrichte, weil ich da keinen üppigen
  Subspace habe.

Kurz: Stinknormales Subnetz für IPV6 und Pointopoint für IPv4. Kein
iptables, keine Bridge, kein NAT, keine gesonderten Routingeinträge
oder sonst irgendwas. Ebenfalls kein Router Advertisement (radvd),
kein DHCPv6 oder sonst irgendein Automatismus.

Der Grund für diese extreme Vereinfachung ist, dass etliche
Alternativen nicht wirklich gut funktioniert hatten. Meine
Irrwege waren folgende:

1) Das Router Advertisement (radvd) sah zunächst nach der
   elegantesten Lösung aus, und jede VM bekam auch eine eigene
   IPv6-Adresse. Aber ich hatte keine echte Kontrolle darüber,
   welche genau sie bekommt. Der radvd-Daemon lieferte nur einen
   Präfix (*/64), und die letzten 64 Bits waren im Wesentlichen
   die MAC-Adressen der VMs. Das war mir zu heikel. Denn einerseits
   hängt die virtuelle MAC-Adresse von der Virtualisierungs-Umgebung
   und nicht von der VM ab, und andererseits gibt es im Protokoll
   keine Garantie, dass die VM wirklich immer exakt ihre MAC-Adresse
   (na gut, mit dem einen bekannten verdrehten Bit) verwendet. Die
   könnten theoretisch auch zufallsbasiert arbeiten, solange es keine
   Kollisionen gibt.

2) Wenn ich jeder VM eine feste IPv6-Adresse zuweisen wollte, blieb
   also nur DCHPv6 übrig. Das habe ich aber nicht zuverlässig an
   den Start bekommen. Schlimmer noch: Wenn der DHCPv6-Daemon auf
   dem Host-System nicht richtig erreichbar war, froren die VMs
   beim Hochfahren ein. Ja, richtig: Der DHCPv6-Client unter Linux
   friert das System ein, bis er ne Antwort erhält. Kein Abbruch
   möglich. Mag sein, dass ich hier überempfindlich reagiert habe,
   aber ich bin für mich zu dem Schluss gekommen, dass DHCPv6 noch
   in den Kinderschuhen steckt - zumindest unter Linux - und dass
   DHCPv6 daher für mein Vorhaben ein untragbares Risiko darstellt.

3) Der Hinweis auf OpenStack und ähnliche Lösungen war sehr gut,
   da es sich tatsächlich um eine Art "private Cloud" handelt.
   Allerdings ist "Cloud" hier schon sehr hoch gegriffen, und ich
   hatte das Gefühl, dass hier ein kompletter Layer über KVM einfach
   Overkill wäre. Abgesehen vom ausbleibenden Lerneffekt, was Netz-
   werte und Virtualisierung angeht. Da mein Resultat aus einem
   sehr einfachen Shell-Script plus einer sehr einfachen Netzwerk-
   Konfiguration pro virtueller Maschine bestand, sehe ich mich
   darin im Nachhinein bestätigt. Mit OpenStack & Co. werde ich mich
   irgendwann später beschäftigen, wenn ich das wirklich brauche.


Als "Entschädigung" für den späten Bericht sende ich euch meine
Skripte und Konfigurationen. Vielleicht möchte das jemand von euch
auch einmal ausprobieren.

A) In dieser Anleitung verwendet ich folgende Platzhalter:

   * ${IPv6HOST}  = IPv6-Adresse des Host-Systems
   * ${IPv4HOST}  = IPv4-Adresse des Host-Systems
   * ${IPv6SPACE} = IPv6-Space der VM (hier: ein /80 Subnetz)
   * ${IPv4GAST}  = IPv4-Adresse der VM

B) Für jede VM gibt es ein Start-Shellskript. Es tätigt am Anfang zwei
   "Aufräum-Aktionen", und macht ansonsten gerade das Allernötigste.
   Wichtig ist, dass es die VM im Vordergrund(!) startet, damit ich
   das später mit Supervisor kontrollieren kann:

    (guest1.sh)

    #!/bin/sh
    set -e

    # Sicherstellen, dass IPv4-Forwarding aktiv ist
    # (kann alternativ auch via /etc/sysctl.conf festgelegt werden)
    echo 1 >/proc/sys/net/ipv4/conf/all/forwarding

    # TAP-Device von einem eventuell vorherigem Start der VM entfernen
    ip tuntap del dev tap_guest1 mode tap

    # TAP-Device anlegen und starten
    ip tuntap add dev tap_guest1 mode tap vnet_hdr
    ip link set tap_guest1 up

    # IPv6 via Subnetz
    ip addr add ${IPv6SPACE}::0/80 dev tap_guest1

    # IPv4 via pointopoint (peer)
    ip addr add ${IPv4HOST} peer ${IPv4GAST}/32 dev tap_guest1

    # VM starten
    exec kvm \
        -net nic,model=virtio \
        -net tap,ifname=tap_guest1,script=no,downscript=no \
        ... \
        -display none \
        "$@"

C) Dieses Skript, und damit die VM, kontrolliere ich via Supervisor:

    [program:guest1]
    user = root
    command = /PATH/TO/guest1.sh
    autorestart = true

D) Das Host-System konfiguriere ich auf exakt eine IPv4-Adresse
   und exakt eine IPv6-Adresse, die jeweils von den VMs nicht
   benutzt werden:

    (/etc/network/interfaces)

    auto eth0
    iface eth0 inet static
      address ${IPv4HOST}
      ...
    iface eth0 inet6 static
      address ${IPv6HOST}
      ...

E) Das Gast-System konfiguriere genauso wie dessen TAP-Device:

    (/etc/network/interfaces)

    auto lo
    iface lo inet loopback
    auto eth0
    iface eth0 inet6 static
        address ${IPv6SPACE}::1
        netmask 80
        gateway ${IPv6SPACE}::0
    iface eth0 inet static
        address ${IPv4GAST}
        netmask 32
        gateway ${IPv4HOST}
        pointopoint ${IPv4HOST}
    EOF

F) Status der VMs abfragen:

    supervisorctl status

G) VM starten:

    supervisorctl start vm1

H) VM sanft neustarten:

    ssh vm1 reboot

I) VM gewaltsam abbrechen bzw gewaltsam neustarten:

    supervisorctl stop vm1
    supervisorctl restart vm1

J) VM im Vordergrund starten (ermöglicht durch "$@" im Shellskript):

    /PATH/TO/guest1.sh -display sdl


Gruß
Volker



Volker Grabsch schrieb:
> Liebe Liste,
> 
> ich suche eine möglichst einfache Lösung für folgendes
> Problem. Ich weiß, wie ich es in der IPv4-Welt löse [1],
> aber bin mir unschlüssig, wie man das für IPv6 angeht:
> 
> Ich habe einen Server (Hostsystem) mit einem IPv6-Subnet,
> in dem mehrere VMs (Gastsysteme) laufen. Jede VM
> bekommt eine permanente IPv6-Adresse aus diesem Subnet,
> und das Hostsystem stellt sicher, dass der Traffic
> entsprechend geroutet wird.
> 
> Schwierigkeitsgrad: Das Hostsystem soll sicherstellen,
> dass jede VM jeweils nur ihre IPv6-Adresse geroutet
> bekommt und sonst nichts!
> 
> Dabei geht es nicht um absurdes "host-based security",
> sondern darum, dass keine VM ausversehen der anderen
> die IPv6-Adresse wegnehmen kann. Dies soll weder durch
> Fehlkonfiguration innerhalb der VM möglich sein, noch
> dadurch, dass eine VM aus einer anderen als Klon hervor-
> gegangen ist.
> 
> Idealerweise sollte es sogar möglich sein, dass zwei
> VMs die gleiche virtuelle MAC-Adresse haben, und trotzdem
> alles läuft. (Dieses Feature ist jedoch optional.)
> 
> Außerdem wäre es super, wenn die VMs nicht auf ihre
> IPv6-Adresse konfiguriert werden müssten, sondern sich
> diese Info vom Hostsystem holen. Falls möglich per NDP,
> sonst per DHCPv6.
> 
> Hat jemand von euch solch ein Setup am Laufen, oder
> kann mir grob skizzieren, wie das aussehen muss?
> Gibt es bekannte Fallstricke, die man beachten muss?
> 
> Für jeden Tipp wäre ich dankbar.
> 
> 
> Gruß
> Volker
> 
> 
> 
> [1] Mit IPv4 mache ich das so:
> 
> Auf dem Hostsystem gibt's für jede VM ein eigenes
> TAP-Device, an dem nur diese VM hängt. Entsprechende
> IPTables/Routing-Einträge sorgen dafür, dass Traffic
> für die entsprechenden IP-Adressen ins richtige TAP-
> Device geroutet wird. Zudem läuft auf dem Hostsystem
> ein DHCP-Server, der die entsprechende IP-Adresse zurück
> liefert, jenachdem von welchem TAP-Device die Anfrage
> kam. Die VMs sind dann so einfach konfiguriert wie nur
> möglich: ein einziges Netzwerk-Device, das auf DHCP
> konfiguriert ist.
> 
> Ich bezweifle jedoch, dass ich dieses 1:1 auf ein
> IPv6-Setup übertragen kann. Zudem hoffe ich, dass
> in der Welt von IPv6 vielleicht einfachere Wege gibt,
> eventuell über eine Netzwerk-Bridge, wo sich dann aber
> die Frage stellt, wie man verhindert, dass sich eine
> fehlkonfigurierte VM eine fremde IP-Adresse schnappt.
> 
> -- 
> Volker Grabsch
> ---<<(())>>---
> _______________________________________________
> linux-l mailing list
> linux-l at mlists.in-berlin.de
> Die Mailingliste der BeLUG (Berliner Linux User Group)
> 
> Wenn du diese Mailingliste  abbestellen willst, gehe bitte auf
> https://mlists.in-berlin.de/mailman/listinfo/linux-l-mlists.in-berlin.de
> und trage dich dort bitte aus

-- 
Volker Grabsch
---<<(())>>---


Mehr Informationen über die Mailingliste linux-l