Gewünscht ist die Anbindung von zwei unterschiedlichen Broadcast-Domains mit Hilfe von IPsec als VPN Lösung.
Das VPN Routing selbst soll jeweils in einer Jail stattfinden.
Da eine Direktkommunikation zwischen den FreeBSD Gateways möglich ist, kann unmittelbar mit AH (für Authentizität/Integrität und Echtheit der Daten) die erste Ebene abgesichert werden ohne auf NAT Probleme zu stoßen.
– die Außenhülle des Tunnels verwendet AH mit hmac-sha1 (transport mode)
– der Kern des Tunnels besteht aus ESP mit aes-cbc Verschlüsselung
– die Zwiebel innerhalb des Kernes bedient sich erneut einer AH Verbindung zur Validierung, diesmal mit hmac-ripemd160
# <<< ======== (ipip-proto-4) ======== >>> 10003 ------------- AH ---------- >>> 20003 (transport) 10002 <<< --------- ESP ------------- 20002 (tunnel) 10001 ------------- AH ---------- >>> 20001 (tunnel)* #
*(nicht im Jail HOST tcpdump sichtbar)
statische Keys, KEIN Perfect Forward Secrecy
Ausgegangen wird von einem “Bridge Zones” Setup
siehe: FreeBSD 10: komplexe Bridge Zones (mit lacp uplink)
Da es bei einigen Servern Probleme mit “options IPSEC_FILTERTUNNEL” (Abstürze/keine funktionierende Filterung mit ipfw unter FreeBSD 10) gab, rate ich zum Zeitpunkt dieses HowTo davon ab.
INFO: 28.02.2014 – Patch in FreeBSD 10.1, siehe:
FreeBSD 10: IPv4 VPN Relay (IPsec entry/OpenVPN middle/OpenVPN exit node) mit Jails für Roadwarrior
Als Einführung sind recht hilfreich:
– FreeBSD VPN over IPsec
– FreeBSD IPsec
– Network Configuration—Tunneling with Free BSD
– Understanding VPN IPsec Tunnel Mode and IPsec Transport Mode – What’s the Difference?
– An Illustrated Guide to IPsec
Security: IPsec ohne integrity check
– A DoS Attack Against the Integrity-Less ESP (IPsec)
VPN Jail1 (Maschine A) hat eine Public Adresse beginnend mit 80.xxx.xxx.xxx
VPN Jail2 (Maschine B) hat eine Public Adresse beginnend mit 212.xxx.xxx.xxx
geroutet werden soll 192.168.1.0 nach 192.168.2.0 und umgekehrt
IPv4 IPsec Net-to-Net VPN in der Jail
Punkt 1 Kernel mit IPsec kompilieren
$ options IPSEC #IP security device crypto $
Die Jails benötigen ein GIF Interface, Auszug aus einer ezjail config:
Punkt 2 ezjail/jail1
$ ### VIMAGE // ### export jail_vpnjail1_exec_poststart0="ifconfig epair89a vnet vpnjail1" export jail_vpnjail1_exec_poststart1="ifconfig epair90a vnet vpnjail1" export jail_vpnjail1_exec_poststart2="ifconfig epair92a vnet vpnjail1" export jail_vpnjail1_exec_poststart3="ifconfig epair93a vnet vpnjail1" export jail_vpnjail1_exec_poststart4="ifconfig gif26 vnet vpnjail1" export jail_vpnjail1_exec_poststart5="ifconfig gif27 vnet vpnjail1" export jail_vpnjail1_exec_poststart6="jexec vpnjail1 /sbin/ifconfig epair89a 80.xxx.xxx.xxx/27" export jail_vpnjail1_exec_poststart7="jexec vpnjail1 /sbin/route add default 80.xxx.xxx.xxx" export jail_vpnjail1_exec_poststart8="jexec vpnjail1 /sbin/ifconfig epair89a inet6 2a01:xxxx:xxxx:xxxx::xxxx:1 prefixlen 64" export jail_vpnjail1_exec_poststart9="jexec vpnjail1 /sbin/route add -inet6 default fe80::1%epair89a" export jail_vpnjail1_exec_poststart10="jexec vpnjail1 /sbin/ifconfig epair90a 192.168.254.254/24" export jail_vpnjail1_exec_poststart11="jexec vpnjail1 /sbin/ifconfig epair93a 192.168.253.254/24" ### // VIMAGE ### ## IPSEC / # export jail_vpnjail1_exec_poststart12="jexec vpnjail1 /sbin/ifconfig epair92a 192.168.1.254/24" export jail_vpnjail1_exec_poststart13="jexec vpnjail1 /sbin/ifconfig epair92a 192.168.5.254/24 alias" # # --- route 1 to 2 export jail_vpnjail1_exec_poststart14="jexec vpnjail1 /sbin/ifconfig gif26 192.168.101.254 192.168.102.254" export jail_vpnjail1_exec_poststart15="jexec vpnjail1 /sbin/ifconfig gif26 tunnel 80.xxx.xxx.xxx 212.xxx.xxx.xxx" export jail_vpnjail1_exec_poststart16="jexec vpnjail1 /sbin/ifconfig gif26 up" export jail_vpnjail1_exec_poststart17="jexec vpnjail1 /sbin/route add 192.168.2.0 192.168.102.254 255.255.255.0" # ## / IPSEC $
Punkt 3 HOST !!! IPsec in den Bridge Zones erlauben
$ vi /etc/firewall.rules add 00040 allow esp from any to any add 00041 allow ah from any to any add 00042 allow ipencap from any to any add 00043 allow udp from any 500 to any $
Punkt 4 Jail1: sofern die Firewall alles erlaubt -> kann man zumindest die Pakete zählen lassen und routing aktivieren
$ vi /etc/jail_firewall.rules ### ### ### ### ### ### ### ### ### add 00040 count esp from any to any add 00041 count ah from any to any add 00042 count ipencap from any to any add 00043 count udp from any 500 to any ### ### ### ### ### ### ### ### ### vi /etc/sysctl.conf ### ### ### ### ### ### ### ### ### net.inet.ip.forwarding=1 net.inet.ip.fastforwarding=0 net.inet6.ip6.forwarding=1 net.inet.ip.fw.one_pass=1 ### ### ### ### ### ### ### ### ### $
Punkt 5 Jail1: ipsec-tools installieren
$ cd /usr/ports/security/ipsec-tools/ && make install clean $
Punkt 6 Jail1: racoon.conf erstellen
$ vi /usr/local/etc/racoon/racoon.conf ### ### ### ### ### ### ### ### ### path pre_shared_key "/usr/local/etc/racoon/psk.txt"; #location of pre-shared key file log debug; #log verbosity setting: set to 'notify' when testing and debugging is complete padding # options are not to be changed { maximum_length 20; randomize off; strict_check off; exclusive_tail off; } timer # timing options. change as needed { counter 5; interval 20 sec; persend 1; # natt_keepalive 15 sec; phase1 30 sec; phase2 15 sec; } listen # address [port] that racoon will listening on { isakmp 80.xxx.xxx.xxx [500]; isakmp_natt 80.xxx.xxx.xxx [4500]; } remote 212.xxx.xxx.xxx [500] { exchange_mode main; doi ipsec_doi; situation identity_only; my_identifier address 80.xxx.xxx.xxx; peers_identifier address 212.xxx.xxx.xxx; lifetime time 8 hour; passive off; proposal_check strict; # nat_traversal off; generate_policy off; proposal { encryption_algorithm aes 256; hash_algorithm sha512; authentication_method pre_shared_key; lifetime time 7200 sec; dh_group 16; } } sainfo (address 192.168.1.0/24 any address 192.168.2.0/24 any) { pfs_group 16; lifetime time 3600 sec; encryption_algorithm aes 256; authentication_algorithm hmac_sha512; compression_algorithm deflate; } ### ### ### ### ### ### ### ### ### $
Punkt 7 Jail1: pre-shared key file erzeugen
$ vi /usr/local/etc/racoon/psk.txt 212.xxx.xxx.xxx my_fancy_psk $
Punkt 8 Jail1: setkey.conf erstellen
Beispiel mit statischen Keys, ohne PFS und ohne racoon !!!
$ vi /usr/local/etc/racoon/setkey.conf ### ### ### ### ### ### ### ### ### flush; # route 1 to 2 # / INFO: -A key length 20 # / INFO: -E key length 16 # add 80.xxx.xxx.xxx 212.xxx.xxx.xxx ah 0x10001 -m tunnel -u 1 -A hmac-ripemd160 "B884DA4799BE4A4F5D57"; add 80.xxx.xxx.xxx 212.xxx.xxx.xxx esp 0x10002 -m tunnel -u 2 -E aes-cbc "36DE843AFA42554F"; add 80.xxx.xxx.xxx 212.xxx.xxx.xxx ah 0x10003 -m transport -u 3 -A hmac-sha1 "B884DA4799BE4A4F5D58"; # add 212.xxx.xxx.xxx 80.xxx.xxx.xxx ah 0x20001 -m tunnel -u 4 -A hmac-ripemd160 "A884DA4799BE4A4F5D57"; add 212.xxx.xxx.xxx 80.xxx.xxx.xxx esp 0x20002 -m tunnel -u 5 -E aes-cbc "38DE843AFA42554A"; add 212.xxx.xxx.xxx 80.xxx.xxx.xxx ah 0x20003 -m transport -u 6 -A hmac-sha1 "C884DA4799BE4A4F5D50"; spdflush; # route 1 to 2 # spdadd 192.168.1.0/24 192.168.2.0/24 any -P out ipsec ah/tunnel/80.xxx.xxx.xxx-212.xxx.xxx.xxx/unique:1 esp/tunnel/80.xxx.xxx.xxx-212.xxx.xxx.xxx/unique:2 ah/transport/80.xxx.xxx.xxx-212.xxx.xxx.xxx/unique:3; # spdadd 192.168.2.0/24 192.168.1.0/24 any -P in ipsec ah/tunnel/212.xxx.xxx.xxx-80.xxx.xxx.xxx/unique:4 esp/tunnel/212.xxx.xxx.xxx-80.xxx.xxx.xxx/unique:5 ah/transport/212.xxx.xxx.xxx-80.xxx.xxx.xxx/unique:6; ### ### ### ### ### ### ### ### ### # EOF chmod 0600 /usr/local/etc/racoon/* $
Racoon wird benötigt, PFS wird verwendet !!!
$ vi /usr/local/etc/racoon/setkey.conf ### ### ### ### ### ### ### ### ### flush; spdflush; # route 1 to 2 # spdadd 192.168.1.0/24 192.168.2.0/24 any -P out ipsec esp/tunnel/80.xxx.xxx.xxx-212.xxx.xxx.xxx/require ah/transport/80.xxx.xxx.xxx-212.xxx.xxx.xxx/require; # spdadd 192.168.2.0/24 192.168.1.0/24 any -P in ipsec esp/tunnel/212.xxx.xxx.xxx-80.xxx.xxx.xxx/require ah/transport/212.xxx.xxx.xxx-80.xxx.xxx.xxx/require; ### ### ### ### ### ### ### ### ### # EOF chmod 0600 /usr/local/etc/racoon/* $
Punkt 9 Jail1: psk generieren
$ # für 20 Zeichen lange AH Keys # openssl enc -aes-256-xts -k secret -P -md sha1 | grep "key" | sed 's/key=//g' | cut -c-20 # # für 16 Zeichen lange ESP Keys openssl enc -aes-256-xts -k secret -P -md sha1 | grep "key" | sed 's/key=//g' | cut -c-16 $
Punkt 10 Jail1: bei Jailstart IPsec mit laden lassen
$ vi /etc/rc.conf ### ### ### ### ### ### ### ### ### gateway_enable="YES" ipv6_gateway_enable="YES" rtadvd_enable="NO" rtadvd_interfaces="epair89a" firewall_enable="YES" #firewall_type="open" firewall_logging="YES" firewall_type="/etc/firewall.rules" firewall_script="/etc/rc.firewall.local" ipsec_enable="YES" ipsec_program="/usr/local/sbin/setkey" ipsec_file="/usr/local/etc/racoon/setkey.conf" # allows setting up spd policies on boot racoon_enable="yes" ### ### ### ### ### ### ### ### ### $
Punkt 11 Jail1: IPsec Policy manuell setzen und Racoon starten
$ clear; service racoon stop; service ipsec stop; sleep 1; service ipsec start; service racoon start $
In Jail2 erfolgt das ganze noch einmal nur mit umgedrehter Reihenfolge in der setkey.conf (spdadd die in und out Einträge)
Bei erfolgreicher Verbindung kann man folgendes im TCPDump beobachten:
Punkt 12 Verbindungstest
$ # ipfw counter in der jail # 00040 0 0 count esp from any to any 00041 28660 6649120 count ah from any to any 00042 0 0 count ipencap from any to any 00043 0 0 count udp from any 500 to any $
$ # tcpdump im Jail HOST # # tcpdump -e -n -i vswitch26 'not ip6 and not arp and not icmp' # tcpdump: WARNING: vswitch26: no IPv4 address assigned tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on vswitch26, link-type EN10MB (Ethernet), capture size 65535 bytes capability mode sandbox enabled 15:07:53.785236 MAC > MAC, ethertype IPv4 (0x0800), length 246: 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: AH(spi=0x00020003,seq=0x3d17): 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: ESP(spi=0x00020002,seq=0x3d17), length 168 15:07:53.787686 MAC > MAC, ethertype IPv4 (0x0800), length 246: 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: AH(spi=0x00010003,seq=0x38b2): 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: ESP(spi=0x00010002,seq=0x38b2), length 168 15:07:54.791368 MAC > MAC, ethertype IPv4 (0x0800), length 246: 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: AH(spi=0x00020003,seq=0x3d18): 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: ESP(spi=0x00020002,seq=0x3d18), length 168 15:07:54.793567 MAC > MAC, ethertype IPv4 (0x0800), length 246: 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: AH(spi=0x00010003,seq=0x38b3): 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: ESP(spi=0x00010002,seq=0x38b3), length 168 15:07:55.796186 MAC > MAC, ethertype IPv4 (0x0800), length 246: 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: AH(spi=0x00020003,seq=0x3d19): 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: ESP(spi=0x00020002,seq=0x3d19), length 168 15:07:55.797195 MAC > MAC, ethertype IPv4 (0x0800), length 246: 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: AH(spi=0x00010003,seq=0x38b4): 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: ESP(spi=0x00010002,seq=0x38b4), length 168 15:07:56.805821 MAC > MAC, ethertype IPv4 (0x0800), length 246: 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: AH(spi=0x00020003,seq=0x3d1a): 212.xxx.xxx.xxx > 80.xxx.xxx.xxx: ESP(spi=0x00020002,seq=0x3d1a), length 168 15:07:56.806448 MAC > MAC, ethertype IPv4 (0x0800), length 246: 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: AH(spi=0x00010003,seq=0x38b5): 80.xxx.xxx.xxx > 212.xxx.xxx.xxx: ESP(spi=0x00010002,seq=0x38b5), length 168 ^C 9 packets captured 11 packets received by filter 0 packets dropped by kernel $
eine gute Übersicht liefert auch: setkey -D
in einem laufenden BHYE Linux, mit tap Device Anbindung, muss noch zusätzlich die Route (über die VPN Jail) gesetzt werden:
$ route add -net 192.168.2.0 netmask 255.255.255.0 gw 192.168.1.254 $
Ergänzungen
24.11.2014 Im BHYVE (Debian) Linux funktioniert eine MTU von 1350
$ # tap26: bhyve vm1 <-> ipsec jail1 <---> ipsec jail2 <-> vm2 ifconfig eth1 mtu 1350 up $
That’s FreeBSD
Ein Gedanke zu „FreeBSD 10: IPv4 IPsec Net-to-Net VPN in der Jail“