Mon, 01 Apr 2019 12:00:00 +0200
computernetz, gre, ipsec, mikrotik, sysadmin, vpn

IPsec-VPN mit IKEv2 und GRE bei MikroTik

Um mich in die Materie einzuarbeiten, habe ich vor kurzem im Netzwerk-Simulator ein IPsec-VPN mit IKEv2 und GRE auf MikroTik CHR aufgebaut.

GNS3 Projekt

Als erstes habe ich zwei MikroTik CHR mit verschiedener Firmwareversion in einem GNS3-Projekt platziert:

Version 6.42.12 war die beim Schreiben des Artikels aktuelle Long-Term-Version von MikroTik

Version 6.44.1 ist momentan die Stable-Version

Ich bevorzuge die Long-Term-Version. Bei Hardware-Routern mit neuerer Firmwareversion kann ich diese aber nicht einspielen. Darum habe ich je eine Stable- und eine Long-Term-Version gewählt, um die Unterschiede in der Konfiguration zu erkunden.

Zu den beiden CHR habe ich zwei VPCs für die Verbindungstests hinzugefügt, sowie eine Cloud mit der ich die externen Interfaces der CHR über zwei Tap-Devices zum Hostrechner verbinde.

Konfiguration MikroTik

Zunächst konfiguriere ich nur das Nötigste und teste die Funktion.

MikroTik-1:

/ip address
add address=172.31.0.1/24 interface=ether1
add address=192.168.0.254/24 interface=eth2

/ip firewall nat
add action=masquerade chain=srcnat out-interface=ether1

/ip route
add gateway=172.31.0.254

/system identity
set name=MikroTik-1

MikroTik-2:

/ip address
add address=172.31.1.1/24 interface=ether1
add address=192.168.1.254/24 interface=eth2

/ip firewall nat
add action=masquerade chain=srcnat out-interface=ether1

/ip route
add gateway=172.31.1.254

/system identity
set name=MikroTik-2

Am GNS3-Host habe ich die Adressen für die Gateways auf die entsprechenden Tap-Devices konfiguriert und Forwarding eingeschaltet.

Konfiguration VPCS

Bei den VPCS konfiguriere ich nur die lokale Netzwerkkonfiguration und das Default-Gateway.

VPCS-1:

ip 192.168.0.1 255.255.255.0 192.168.0.254

VPCS-2:

ip 192.168.1.1 255.255.255.0 192.168.1.254

Tests

Wenn alles richtig verbunden und konfiguriert ist, kann ich die Konsole von VPCS-1 öffnen und mit PING die folgenden Adressen erreichen:

192.168.0.254

172.31.0.1

172.31.0.254

172.31.1.254

172.31.1.1

Funktionieren nicht alle Tests, muss ich Konfiguration und Verbindungen überprüfen. Die ICMP-Datagramme werden an allen Stellen im Netz unverschlüsselt übertragen, wie eine Kontrolle mit Wireshark zeigt.

VPCS-2 kann ich noch nicht erreichen, da dieser aufgrund des NAT außerhalb seines Netzes nicht direkt adressierbar ist.

IPsec-VPN mit IKEv2

Nachdem die Grundkonfiguration funktioniert, beginne ich mit dem VPN. Ich will ein route-basiertes VPN einrichten. Dieses ist dadurch charakterisiert, dass im VPN nur Traffic zwischen den Gateways auftaucht.

Das heißt, ich benötige nur eine Security Association (SA) für jede Richtung und zwar zwischen den externen Adressen der VPN-Gateways. Das erlaubt mir, das VPN im Transportmodus zu konfigurieren, was den Protokoll-Overhead durch IPsec in den Datagrammen etwas reduziert.

Ich ergänze die Konfiguration für MikroTik-1 mit Software-Version 6.42.12 wie folgt:

/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-128-cbc name=proposal1 pfs-group=ecp256

/ip ipsec peer
add address=172.31.1.1/32 dh-group=ecp256 enc-algorithm=aes-128 exchange-mode=ike2 hash-algorithm=sha256 secret=sehrgeheim

/ip ipsec policy
add dst-address=172.31.1.1/32 level=unique proposal=proposal1 src-address=172.31.0.1/32

Bei MikroTik-2 mit Version 6.44 hingegen sieht die IPsec-Konfiguration etwas anders aus. Hier ergänze ich wie folgt:

Mit Version 6.44.1:

/ip ipsec profile
add dh-group=ecp256 enc-algorithm=aes-128 hash-algorithm=sha256 name=profile1

/ip ipsec peer
add address=172.31.0.1/32 exchange-mode=ike2 name=peer1 profile=profile1

/ip ipsec proposal
add auth-algorithms=sha256 enc-algorithms=aes-128-cbc name=proposal1 pfs-group=ecp256

/ip ipsec identity
add peer=peer1 secret=sehrgeheim

/ip ipsec policy
add dst-address=172.31.0.1/32 level=unique proposal=proposal1 src-address=172.31.1.1/32

Zum Test schicke ich ein Ping von MikroTik-1 zu MikroTik-2, im Paketmitschnitt tauchen ESP-Datagramme zwischen den CHR statt ICMP auf.

Ping von PC-1 zu MikroTik-2 taucht dort nun ebenfalls als ESP-Traffic auf, weil MikroTik-1 NAT (Masquerading) macht. Das gleiche gilt für PING von PC-2 zu MikroTik-1.

PC-1 und PC-2 können sich immer noch nicht gegenseitig erreichen.

Bei Problemen mit dem VPN kann ich das Logging für IPsec auf den MikroTik einschalten:

/system logging
add topics=ipsec,!debug,!packet

Je nach Schwere des Problems kann ich dabei die Topics debug und packet dazuschalten, schreibe dann das Log jedoch lieber in eine Datei.

GRE-Tunnel

Für den GRE-Tunnel definiere ich ein entsprechendes Interface, dessen lokale und entfernte Adressen denen des IPsec-Tunnels gleichen. Der Name ist frei wählbar, ich bevorzuge den Namen der Gegenstelle, das erleichtert mir die Übersicht wenn ich mit mehreren Tunneln arbeite. Beiden GRE-Interfaces weise ich eine Adresse aus einem Transfernetz zu, die ich später für das Routing benötige.

/interface gre
add allow-fast-path=no local-address=172.31.0.1 name=MikroTik-2 remote-address=172.31.1.1
/ip address
add address=192.168.255.1/30 interface=MikroTik-2

Für MikroTik-2 ist die Konfiguration analog:

/interface gre
add allow-fast-path=no local-address=172.31.1.1 name=MikroTik-1 remote-address=172.31.0.1
/ip address
add address=192.168.255.2/30 interface=MikroTik-1

Nachdem der GRE-Tunnel aufgesetzt ist, kann ich im Paketmitschnitt zwischen den VPN-Gateways neben dem regelmäßigen IKE-KeepAlive-Austausch nun auch regelmäßigen ESP-Traffic ausmachen, selbst wenn keine Daten durch den Tunnel gesendet werden. Das sind GRE-Protokoll-Nachrichten.

Zum Test schicke ich einen PING von MikroTik-1 zu 192.168.255.2. Im Paketmitschnitt taucht ESP-Traffic mit den externen Adressen der VPN-Gateways auf.

Das jeweils andere interne Netz ist immer noch nicht von den VPCS aus zu erreichen.

Routing über den GRE-Tunnel

Nachdem ich nun mit dem GRE-Interface und den daran gebundenen IP-Adressen die Möglichkeiten geschaffen habe, beliebigen Traffic verschlüsselt zwischen den VPN-Gateways zu übertragen, füge ich als nächstes Routen zum jeweils gegenüberliegenden Netz hinzu, das vorher nicht erreichbar war.

MikroTik-1:

/ip route
add dst-address=192.168.1.0/24 gateway=192.168.255.2

MikroTik-2:

/ip route
add dst-address=192.168.0.0/24 gateway=192.168.255.1

Zum Test schicke ich ein PING von PC-1 an 192.168.1.1 und bekomme nun Antworten von dort. Auf der äußeren Seite der VPN-Gateways sind die ICMP-Nachrichten im ESP-Traffic verborgen.

Firewall

Damit habe ich ein funktionsfähiges route-basiertes VPN und könnte den Artikel beenden. Dann würde jedoch ein überaus wichtiger Aspekt fehlen, den ich hier zumindest anreißen will.

Route-basierte VPN wie das hier vorgestellte haben gegenüber policy-basierten VPN, bei denen ich für jedes Paar von Netzwerken auf beiden Seiten, die miteinander kommunizieren sollen, eigene IPsec-SA benötige, einige Vorteile. Sie sind sehr viel flexibler, was die Gestaltung der Netzwerke auf beiden Seiten betrifft, mit Routingprotokollen lässt sich der Verkehr gut steuern und Traceroute funktioniert über das VPN hinweg.

Dafür muss ich beachten, dass das VPN sich nicht um die Einhaltung bestehender Policies kümmert. Den erlaubten Traffic muss ich selbst mit Firewall-Regeln von unerlaubtem Traffic trennen.

Ich betrachte dabei zwei Aspekte bei den Firewall-Regeln:

1. den Datenverkehr zum VPN-Gateway,

2. den Datenverkehr durch das VPN.

Den Datenverkehr zum VPN-Gateway muss ich auch bei policy-basierten VPN regulieren. Das passiert in der input Chain. Den Datenverkehr durch das VPN reguliere ich hingegen in der forward Chain.

Da ich im GNS3-Projekt auf der grünen Wiese angefangen und bis auf das NAT noch keine Filterregel habe, beginne ich mit einer protokollierenden Sperr-Regel.

/ip firewall filter add action=drop chain=input log=yes

Achtung: Bei Systemen, die via SSH, Webinterface oder WinBox konfiguriert werden, unterbinde ich damit die weitere Arbeit mit dem Gerät, daher füge ich diese Regel nur dann als erste ein, wenn ich zuverlässigen Zugriff auf die Konsole habe.

Nun funktioniert das VPN nicht mehr, dafür bekomme ich mit /log print angezeigt, welchen Traffic ich freigeben muss.

Für IPsec muss ich die UDP-Ports 500 und 4500 sowie das Protokoll ESP (50) freigeben. Im Beispiel gebe ich sämtlichen Verkehr zwischen den VPN-Gateways frei und habe damit auch gleich den GRE-Tunnel mit erlaubt.

Ich verwende in der Filter-Regel eine Adressliste, damit ich später ohne großen Aufwand weitere VPN-Gateways hinzufügen kann, falls das nötig ist.

/ip firewall address-list
add address=172.31.1.1 list=VPN-Peers

/ip firewall filter
add action=accept chain=input src-address-list=VPN-Peers

Die gleichen Regeln benötige ich auch bei policy-basierenden VPN, dann ist allerdings kein GRE-Tunnel notwendig.

Bei einem route-basierten VPN benötige ich nun zusätzlich Regeln, die den durch das VPN geschützten Traffic regulieren.

Ich beginne wieder mit einer Drop-Regel, diesmal für die forward Chain:

/ip firewall filter
add action=drop chain=forward log=yes

In den Logs finde ich nun die Adressen, die ich freigeben muss. Die Regeln, mit denen ich den gewünschten Traffic explizit erlaube, kommen vor diese DROP-Regel.

Als erstes stelle ich fest, dass GRE selbst durch die Forward-Chain läuft, und zwar zwischen dem Tunnel-Interface und dem externen Interface. Ich nutze hier die bestehende Adressliste VPN-Peers und bin damit auf der sicheren Seite, wenn ich mehrere Tunnel einrichten will.

/ip firewall filter
add action=accept chain=forward dst-address-list=VPN-Peers out-interface=ether1 protocol=gre

Sodann erlaube ich den Traffic von Netz 1 zu Netz 2 auf beiden VPN-Gateways. Je nachdem, auf welcher Seite die Verbindungen aufgebaut werden, binde ich die zugehörigen Regeln auf dem lokalen VPN-Gateway mittels out-interface an das GRE-Interface und auf dem entfernten mittels in-interface

Wie genau ich den erlaubten Traffic durch das VPN spezifiziere, hängt von meinem Sicherheitsbedürfnis ab. Im Beispiel hier erlaube ich sämtlichen Traffic zwischen beiden lokalen Netzen.

Auch hier bietet es sich wieder an, mit Adresslisten zu arbeiten. Die Adresse des GRE-Interfaces auf der Peer-Seite kommt mit in die Adressliste, da diese bei Nachrichten des VPN-Gateways selbst verwendet wird.

/ip firewall address-list
add address=192.168.1.0/24 list=MikroTik-2
add address=192.168.255.2 list=MikroTik-2

/ip firewall filter
add action=accept chain=forward out-interface=MikroTik-2 dst-address-list=MikroTik-2
add action=accept chain=forward in-interface=MikroTik-2 src-address-list=MikroTik-2

Außerdem benötige ich eine Regel für den unverschlüsselten Traffic von Inside, für den bisher die NAT-Regel ausreichend war.

/ip firewall address-list
add address=192.168.0.0/24 list=local-net

/ip firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward out-interface=ether1 src-address-list=local-net

Für das zweite VPN-Gateway lege ich entsprechende Firewall-Regeln an.

In den oben gezeigten Beispielen habe ich die Befehle in der Reihenfolge angebracht, die mir besser nachvollziehbar erschien. In den Regeln müssen die spezifischen accept Regeln vor den allgemeineren drop Regeln stehen, um wirksam zu werden.

Die Reihenfolge der Adresslist-Einträge ist hingegen egal. Zur Kontrolle kommt hier noch einmal die Liste aller Firewall-Einträge bei MikroTik-1:

/ip firewall address-list
add address=172.31.1.1 list=VPN-Peers
add address=192.168.1.0/24 list=MikroTik-2
add address=192.168.255.2 list=MikroTik-2
add address=192.168.0.0/24 list=local-net

/ip firewall filter
add action=accept chain=input src-address-list=VPN-Peers
add action=drop chain=input log=yes

/ip firewall filter
add action=accept chain=forward connection-state=established,related
add action=accept chain=forward out-interface=ether1 src-address-list=local-net
add action=accept chain=forward in-interface=MikroTik-2 src-address-list=MikroTik-2
add action=accept chain=forward out-interface=MikroTik-2 dst-address-list=MikroTik-2
add action=accept chain=forward dst-address-list=VPN-Peers out-interface=ether1 protocol=gre
add action=drop chain=forward log=yes

/ip firewall nat
add action=masquerade chain=srcnat out-interface=ether1

Fazit

Damit sind wir am Ende der Exkursion zu route-basierten IPsec-VPN mit IKEv2 und GRE bei MikroTik-Routern. Damit route-basierte VPN wie gewünscht funktionieren, müssen wir ein paar Dingen Beachtung schenken: der Konfiguration von IPsec mit IKEv2, dass sich von Version zu Version unterscheidet, der Konfiguration von GRE-Tunneln sowie dem Binden von IP-Adressen und -Routen an diese und schließlich den nötigen Firewall-Regeln, die das VPN absichern.