Bridging

Aus ConfigWiki
Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

libvirt-Netzwerke

libvirt kann Netzwerke selbst verwalten und verändert dazu die iptables-Regeln. Will man die Regeln anpassen, zerstört ein Neustart von libvirt diese Konfiguration wieder. Aus diesem Grund (und weiteren) verwalten wir die Netze außerhalb von libvirt. Zu beachten ist, daß in dem Fall auch ein DHCP- und DNS-Server zu konfigurieren ist.

Ausgangszustand

In libvirt wurden 4 Netzwerke konfiguriert:

  • virbr0: default, NAT
  • virbr1: local, isoliert
  • virbr2: routed, geroutet
  • virbr3: nodhcp, gerouted

Damit geroutete Netze funktionieren, muß auch der die Gegenseite bzw. der Router entsprechend konfiguriert sein.

~# ip route|grep virbr
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 
192.168.100.0/24 dev virbr1  proto kernel  scope link  src 192.168.100.1 
192.168.111.0/24 dev virbr2  proto kernel  scope link  src 192.168.111.1 
192.168.199.0/24 dev virbr3  proto kernel  scope link  src 192.168.199.1 
~# brctl show
bridge name	bridge id		STP enabled	interfaces
virbr0		8000.000000000000	yes		
virbr1		8000.000000000000	yes		
virbr2		8000.000000000000	yes		
virbr3		8000.000000000000	yes		

die entsprechenden Firewallregeln in ferm importiert und zusammengefaßt:

/etc/ferm/ferm.conf

domain ip {
   table nat {
       chain POSTROUTING {
           policy ACCEPT;
           saddr 192.168.122.0/24 outerface eth0 {
               protocol tcp MASQUERADE to-ports 1024-65535;
               protocol udp MASQUERADE to-ports 1024-65535;
               MASQUERADE;
           }
       }
       ...
   }
   table filter {
       chain INPUT {
           ...
           interface (virbr0 virbr1 virbr2 virbr3) protocol (udp tcp) dport (53 67) ACCEPT;
           ...
       }
       chain FORWARD {
           policy DROP;

           mod state state INVALID DROP;
           mod state state (RELATED ESTABLISHED) ACCEPT;

           ...

           # default (NAT)
           daddr 192.168.122.0/24 outerface virbr0 
           saddr 192.168.122.0/24 interface virbr0 ACCEPT;

           # local (isoliert)

           # routed
           daddr 192.168.111.0/24 outerface virbr2 ACCEPT;
           saddr 192.168.111.0/24 interface virbr2 ACCEPT;

           # sbsnet (geroutet, ohne DHCP)
           daddr 192.168.199.0/24 outerface virbr3 ACCEPT;
           saddr 192.168.199.0/24 interface virbr3 ACCEPT;

           interface virbr0 outerface virbr0 ACCEPT;
           interface virbr1 outerface virbr1 ACCEPT;
           interface virbr2 outerface virbr2 ACCEPT;
           interface virbr3 outerface virbr3 ACCEPT;

           interface (virbr0 virbr1 virbr2 virbr3) REJECT reject-with icmp-port-unreachable;
           outerface (virbr0 virbr1 virbr2 virbr3) REJECT reject-with icmp-port-unreachable;
           ...
       }
       chain OUTPUT policy ACCEPT;
   }
}

DHCP und DNS wird über dnsmasq bedient, wobei die Parameter jedoch von libvirt auf der Kommandozeile übergeben werden. Damit kann dnsmasq nur nach eigenständiger Konfiguration weiterverwendet werden. Wir werden es allerdings durch den dhcpd und bind ersetzen.

eigenständige Interfaces

Für jedes virbr-Interface wird ein br-Interface in /etc/network/interfaces angelegt:

auto br0
iface br0 inet static
	address 192.168.122.1
	netmask 255.255.255.0
	bridge_stp off
	bridge_fd 0
	pre-up brctl addbr $IFACE
	post-down brctl delbr $IFACE

auto br1
iface br1 inet static
	address 192.168.100.1
	netmask 255.255.255.0
	bridge_stp off
	bridge_fd 0
	pre-up brctl addbr $IFACE
	post-down brctl delbr $IFACE

auto br2
iface br2 inet static
	address 192.168.111.1
	netmask 255.255.255.0
	bridge_stp off
	bridge_fd 0
	pre-up brctl addbr $IFACE
	post-down brctl delbr $IFACE

auto br3
iface br3 inet static
	address 192.168.199.1
	netmask 255.255.255.0
	bridge_stp off
	bridge_fd 0
	pre-up brctl addbr $IFACE
	post-down brctl delbr $IFACE

Vor dem Starten der br-Interfaces sollten die alten virbr-Interfaces in libvirt gestoppt und deaktiviert werden.

Wie heißen die Netzwerke aus libvirt-Sicht?

~# virsh net-list
Name                 Status     Automatischer Start
-----------------------------------------
default              Aktiv      yes       
lokal                Aktiv      yes       
routed               Aktiv      yes 
~# virsh net-autostart default --disable
~# virsh net-autostart lokal   --disable
~# virsh net-autostart routed  --disable
~# virsh net-list
Name                 Status     Automatischer Start
-----------------------------------------
default              Aktiv      no        
lokal                Aktiv      no        
routed               Aktiv      no        

~# virsh net-destroy default
~# virsh net-destroy lokal
~# virsh net-destroy routed
~# virsh net-list
Name                 Status     Automatischer Start
-----------------------------------------

~# brctl show
bridge name	bridge id		STP enabled	interfaces

~# ip addr | grep virbr

nichts mehr da, jetzt kanns losgehen

~# ifup br0 br1 br2

In /etc/ferm/ferm.conf werden entsprechend alle virbr durch br ersetzt und danach neu geladen

~# ferm -i /etc/ferm/ferm.conf

DHCP

Für jedes Subnetz wird eine Sektion angelegt und Router/DNS-Server-Option gesetzt. Falls ein externer DNS verwendet wird, kann stattdessen die globale Option genutzt werden. Die globale Option domain-name ist dagegen eher im Falle eines lokalen DNS mit Namensauflösung für die virtuellen Maschinen sinnvoll.

/etc/dhcp/dhcpd.conf:

option domain-name "vm.my-domain.de";
option domain-name-servers $EXTERNER_DNS;

authoritative;

subnet 192.168.122.0 netmask 255.255.255.0 {
  range 192.168.122.100 192.168.122.199 ;
  option domain-name-servers 192.168.122.1;
  option routers 192.168.122.1;
  option broadcast-address 192.168.122.255;
}

subnet 192.168.100.0 netmask 255.255.255.0 {
  range 192.168.100.100 192.168.100.199 ;
  option domain-name-servers 192.168.100.1;
  option routers 192.168.100.1;
  option broadcast-address 192.168.100.255;
}

subnet 192.168.111.0 netmask 255.255.255.0 {
  range 192.168.111.100 192.168.111.199 ;
  option domain-name-servers 192.168.111.1;
  option routers 192.168.111.1;
  option broadcast-address 192.168.111.255;
}

/etc/default/isc-dhcp-server:

INTERFACES="br0 br1 br2"

Zum Schluß muß der DHCP-Server noch gestartet werden.

~# invoke-rc.d isc-dhcp-server start

Wahlweise kann für den DNS-Server ein entfernter Server angegeben werden, der dann aber nicht für lokale und nur bedingt für geroutete Netze funktioniert.

DNS

Mit einem lokalen DNS-Server können die virtuellen Maschinen ebenfalls mit Hostnamen verwaltet werden. In der Minimalkonfiguration sollte dieser als Forwarder bzw. "caching only" konfiguriert sein.

/etc/bind/named.conf.options

options {
       ...
	forwarders {
		8.8.8.8;
	};
       ...
};

Konfiguration neu einlesen

~# rndc reload

VM-Konfiguration

Bereits vorhandene virtuelle Maschinen müssen noch bzgl. Netzwerkinterface angepaßt werden. Die entsprechenden Dateien sind in /etc/libvirt/qemu/*.xml zu finden.


alt:

   <interface type='network'>
     ...
     <source network='default'/>
     ...
   </interface>

neu:

   <interface type='bridge'>
     ...
     <source bridge='br0'/>
     ...
   </interface>

Nach den Änderungen muß libvirt neu gestartet werden:

~# invoke-rc.d libvirt-bin restart

externe IP an VM

Im Folgenden werden 2 virtuelle Maschinen so konfiguriert, daß sie direkt eine öffentliche IP bekommen. Um Probleme mit Setups zu vermeiden, die mit eine Hostroute nicht funktionieren, bekommen die Gäste jeweils noch ein privates Netz zugewiesen.

Interfaces

/etc/network/interfaces ergänzen:

auto br100
iface br100 inet static
   address 192.168.200.1
   netmask 255.255.255.252
   bridge_stp off
   bridge_fd 0
   pre-up brctl addbr $IFACE
   post-up route add -host aa.bb.cc.100 $IFACE
   post-down brctl delbr $IFACE
auto br101
iface br101 inet static
   address 192.168.200.5
   netmask 255.255.255.252
   bridge_stp off
   bridge_fd 0
   pre-up brctl addbr $IFACE
   post-up route add -host aa.bb.cc.101 $IFACE
   post-down brctl delbr $IFACE

und starten:

~# ifup br100 br101

Firewall-Erweiterung

/etc/ferm/ferm.conf:

       ...
       chain POSTROUTING {
           policy ACCEPT;
           saddr (192.168.122.0/24 192.168.200.0/24) outerface eth0 {
               protocol tcp MASQUERADE to-ports 1024-65535;
               protocol udp MASQUERADE to-ports 1024-65535;
               MASQUERADE;
           }
       }
       ...
       chain INPUT {
           ...
           interface (... br100 br101) protocol (udp tcp) dport (53 67) ACCEPT;
           ...
       }
       chain FORWARD {
           ...
           saddr 192.168.200.0/30 interface br100 ACCEPT;
           saddr 192.168.204.0/30 interface br101 ACCEPT;

           interface br100 outerface br100 ACCEPT;
           interface br101 outerface br101 ACCEPT;

           interface (... br100 br101) REJECT reject-with icmp-port-unreachable;
           outerface (... br100 br101) REJECT reject-with icmp-port-unreachable;
           ...
       }
       ...

und wieder einlesen:

~# ferm -i /etc/ferm/ferm.conf

DHCP-Erweiterung

/etc/dhcp/dhcpd.conf:

subnet 192.168.200.0 netmask 255.255.255.252 {
  range 192.168.200.2 192.168.200.2;
  option domain-name-servers 192.168.200.1;
  option routers 192.168.200.1;
  option broadcast-address 192.168.200.3;
}

subnet 192.168.200.4 netmask 255.255.255.252 {
  range 192.168.200.6 192.168.200.6;
  option domain-name-servers 192.168.200.5;
  option routers 192.168.200.5;
  option broadcast-address 192.168.200.7;
}

/etc/default/isc-dhcp-server:

INTERFACES="... br100 br101"

DHCP-Server neustarten:

~# invoke-rc.d isc-dhcp-server start

Die öffentlichen IPs werden danach im Client als zusätzliche IP-Adressen zugewiesen.

Meine Werkzeuge