pfsense in a bottle

Ein Artikel über die Idee eine Firewall zu virtualisieren, pfsense als Gastsystem in einer Linux kvm, macht aber für Heimserver durchaus Sinn, oder auch nicht.

Bei der Auswahl der Hardware muss darauf geachtet werden, dass die Hardwarevirtualisierung (VT-d bzw. AMD-V) unterstützt wird, die CPU dafür alleine reicht nicht aus, es muss auch das Mainboard/Chipset dies unterstützen. 
Der zweite Fallstrick ist u.U. eine BIOS-Einstellung, welche VT-d deaktiviert,  d.h. zuerst im BIOS prüfen und die Virtualisierungfunktion geg. aktivieren. 

Danach kann via:

grep --color svm /proc/cpuinfo #AMD
grep --color vmx /proc/cpuinfo #Intel
geprüft werden, ob die Hardwarevirtualisierung aktiv ist oder nicht. 
Ohne Hardwarevirtualisierung wirds extrem mühsam und daher nicht zu empfehlen. 
Eine mögliche stromsparende Hardwarekonfiguration wäre: 
Mainboard: Supermicro X9SCM-F  (2xLAN, 1xIPMI ded, LGA1155, Intel® C204 PCH Chipset) 
CPU: Intel® Xeon E3-1220LV2, 2,30GHz, 2-Core, TDP 17W) 

Der E3-1220LV2 Xeon ist gewissermaßen ein Sonderfall, da dieser keinen Grafiksupport mitbringt, daher wird ein Mainboard mit Onboard-Grafik benötigt.

KVM SETUP
Als Hostsystem kommt Ubuntu-Server 64bit 12.10 zum Einsatz, die Konfiguration der VMs erfolgt via libvirt, die Installation ist denkbar einfach:

apt-get install kvm qemu libvirt-bin
danach unbedingt prüfen ober der kvm Hardwarevirtualisierungssupport geladen wurde, da sonst libvirt automatisch eine reine qemu VM anlegt.

root@soerva:~# lsmod | grep kvm
kvm_intel             132759  3 
kvm                   414070  1 kvm_intel

der wichtige Teil ist in dem Fall das kvm_intel Modul für die Hardwarevirtualisierung.

Anlegen der VM
Die VM kann entweder mit dem Virtual Machine Manager oder besser per virsh selbst angelegt werden, prinzipiell werden zwei Netzwerkbridges benötigt (einmal für WAN und einmal für LAN), 10GB Diskspace, 1GB RAM und eine CPU sind für pfsense ausreichend. 
Über die Details wie die einzelnen kvm Konfigurationsschritte sind, wird hier nicht näher eingegangen, da das Anlegen von VMs via virsh im Netz hinlänglich dokumentiert ist, wir beschränken uns hier auf die Besonderheiten. 

Ist die VM fertig konfiguriert sollten folgende Netzwerkinterfaces vorhanden sein: 
br0 und br1 für LAN bzw. WAN, die LANseite hat zusätzlich die private IP des Servers gebunden 
vnet0 und vnet1 die virtuellen Netzwerkkarten des Gastsystems 
Eine Bridge ist mit vnet0 und dem physikalischen Interface für WAN zusammengeschaltet und die andere mit vnet1 und dem physikalischen Interface für die LANseite. 
Die Bridgekonfiguration könnte so aussehen

root@soerva:~# brctl show
bridge name    bridge id        STP enabled    interfaces
br0        8000.002590a2d3ee    yes        p4p1
                            vnet1
br1        8000.002590a2d3ef    yes        em1
                            vnet0

Zuletzt muss noch das pfsense Installationsimage eingebunden werden, verwendet wird pfsense 2.1 Beta1, hier erhältlich.
Danach die vm starten und mit der pfsense Installation beginnen.


PFSENSE
Die Installation von pfsense ist einfach, wichtig ist, dass die Netzwerkinterfaces erkannt werden, dem LAN und dem WAN Interface die entsprechenden IPs zuweisen, das wars dann im Großen und Ganzen, für die Konfiguration von pfsense deren Doku zu Rate ziehen, mit wenigen Clicks sollte aber eine funktionierende Firewall vorhanden sein, zumindest in der Grundkonfiguration.

Autostart
Wünschenswert ist natürlich wenn die VM nach einem Neustart auch automatisch startet:

virsh # autostart firewall
Domain firewall als automatisch zu starten markiert

Theoretisch wars das, praktisch bleibt noch eines zu tun, die virtuellen Schalter "--very-fast --less-cpu" umzulegen?!?

VIRTIO
Richtig performant wird das System erst durch den Einsatz der virtio Treiber im Gastsystem. FreeBSD bringt Out-of-the-Box die Treiber für die Netzwerkkarten, Blockdevices und Memory-Blooning mit. Verwendet man diese nicht, muss die VM die entsprechende Hardware emulieren, was wiederum Resourcen kostet. Im pfsense System zunächst die Kernel-Module aktivieren:

cat /boot/loader.conf.local
virtio_load="YES"
virtio_pci_load="YES"
if_vtnet_load="YES"
virtio_blk_load="YES"
und die fstab ändern: 
statt /dev/ad0s1a muss /dev/vtbd0s1a eingetragen werden. 
Danach die VM runterfahren, weiter über die virsh das Model der Netzwerkkarte in virtio ändern, die Konfiguration sollte danach so aussehen:

virsh # domiflist firewall
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     br1        virtio      52:54:00:b0:d5:cf
vnet1      bridge     br0        virtio      52:54:00:d3:43:01
Gleichermaßen ist das Blockdevice auf virtio umzustellen, es kann sein, dass man manuell in die XML-Konfiguration eingreifen muss, dies in der virsh mit edit <domain> machen, nach dem Speichern erfolgt automatisch ein Check der XML Datei, die Datei also nicht direkt ändern.

    <disk device="disk" type="file">
      <driver name="qemu" type="qcow2">
      <source file="/var/lib/libvirt/images/firewall.img">
      <target bus="virtio" dev="hda">
      <address bus="0x00" domain="0x0000" function="0x0" slot="0x07" type="pci">    
</address></target></driver></disk>   
Nun die VM wieder starten, funktioniert alles, sollten die Netzwerkinterfaces vtnet0 bzw. vtnet1 lauten, des Weiteren sollte die Disk via /dev/vtbd0s1a gemountet sein. 


Spielverderber Checksum Offloading
Bei meinem Setup funktionierte aus irgendeinem Grund der Zugriff vom Ubuntu Server selbst ins WAN nicht, nach langer Suche ich habe ich herausgefunden, dass die Prüfsummen der IP-Pakete, die vom Server ausgesendet wurden, falsch waren. Schuld daran ist offenbar das Checksum Offloading, also jener Mechanismus im Netzwerkkartentreiber, der die IP-Prüfsummenberechnung an die Netzwerkkarte übergibt. Da ist entweder im vtnet Treiber vom FreeBSD oder im Linux virtio Treiber ein "Käfer" drinnen, auf alle Fälle kann dies durch Deaktivierung dieser Funktion im Gastsystem behoben werden:

Zurück zur Übersicht