IPsec mit Linux

Submitted by admin on So, 11.12.2016 - 11:37

Voraussetzungen

Es sollte eine aktuelle Linux Distribution verwendet werden, die eine aktuelle StrongSwan enthält. Der Grund liegt darin, dass gelegentlich Cryptoverfahren, die bislang als sicher galten, aufgrund neuer Erkenntnisse doch nicht so sicher sind. Die StrongSwan Entwickler liefern Updates für ihren Sourcecode, jedoch ist es Sache der Distributionen, diese Änderungen ebenfalls aufzunehmen. Es ist schon sehr bemerkenswert, dass gerade einige Firewall Hersteller da etwas schlampig sind

Es versteht sich von selbst, dass die (Sicherheits) Updates der gewählten Distribution regelmäßig installiert werden. Die Prüfung, ob Updates vorliegen, sollte täglich erfolgen. Liegt etwas vor, dann sollte das Update innerhalb von 24h erfolgen.

  • In diesem Beitrag wird als Plattform Ubuntu 16.04 verwendet.
  • Preshared Keys sollten nicht mehr verwendet werden, wenn man das Passwort schon verschlüsselt übertragen muss, kann man für das VPN auch gleich Zertifikate verwenden. Es wäre nicht das erste Mal, dass ein VPN Secret aus Versehen unverschlüsselt per E-Mail verschickt wurde… Deshalb: Kein Preshared Secret!

PKI erstellen

Unter “einfache PKi” wird beschrieben, wie man eine PKI selbst bauen kann. So einfach wie diese Lösung ist, so sicher ist sie auch, wenn diese PKI z.B. auf einem alten Notebook ohne Netzverbindung erstellt. Aus Performancegründen sollten Zertifikate auf der Basis elliptischer Kurven erstellt werden. In diesem Fall muss aus dem privaten Key File der Abschnitt

-----BEGIN EC PARAMETERS-----
....
-----END EC PARAMETERS-----

entfernt werden, sonst nimmt Strongswan den privaten Key nicht an.

Konfiguration

/etc/ipsec.conf

in dem Config File wird eine Beschreibung der Verbindung abgelegt. Die Parameter für ike und esp sind sicherheitsrelevant. Unter IKEv2CipherSuites werden die möglichen Parameter dafür beschrieben. IKEv1 sollte heute nicht mehr verwendet werden.

conn %default
	ikelifetime=60m
	keylife=20m
	rekeymargin=3m
	keyingtries=1
	keyexchange=ikev2
	ike=aes256gcm128-sha512-modp4096
	esp=aes256gcm128-sha512-modp4096

conn alice
	left=192.168.34.15
	leftcert=alice.crt
	leftid="CN=alice"
	leftsubnet=10.168.117.0/24
	leftfirewall=no
	right=172.16.69.26
	rightid="CN=bob"
	rightsubnet=10.168.116.0/24
	auto=start

Bei “bob” werden die Left und Right Parameter vertauscht. Weiterhin sollte auto=add gesetzt werden, hier soll eben nur alice die Verbindung aktiv aufbauen.

/etc/ipsec.secrets

In dieser Datei wird auf die privaten Keys referenziert.

: ECDSA alice.key

Zertifikate und Keys

Die Zertifikate und Keys gehören alle in bestimmte Verzeichnisse unter /etc/ipsec.d:

  • cacerts : CA Zertifikat. Dieses Zertifikat ist identisch auf allen IPsec Installationen, die mit dieser CA arbeiten, im Beispiel: ca.crt
  • certs: Das individuelle Zertifikat für den IPsec Teilnehmer, im Beispiel: alice.crt
  • private: Der zugehörige private Key für das Zertifikat unter certs, im Beispiel: alice.key (siehe ipsec.secrets)

Test

Mit ipsec restart wird StrongSwan neu initialisert, hat man alles richtig gemacht, dann sollte die Verbindung starten.

Mit ipsec statusall kann man sehen, ob eine Verbindung aktiv ist.

Status of IKE charon daemon (strongSwan 5.3.5, Linux 4.4.0-24-generic, x86_64):
  uptime: 29 minutes, since Jun 12 07:22:40 2016
  malloc: sbrk 2547712, mmap 0, used 389232, free 2158480
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
  loaded plugins: charon test-vectors aes rc2 sha1 sha2 md4 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf gmp agent xcbc hmac gcm attr kernel-netlink resolve socket-default connmark stroke updown
Listening IP addresses:
  192.168.34.15
  10.168.117.1
Connections:
    alice:  192.168.34.15...192.168.69.26  IKEv2
    alice:   local:  [CN=bob] uses public key authentication
    alice:    cert:  "CN=bob"
    alice:   remote: [CN=alice] uses public key authentication
    alice:   child:  10.168.117.0/24 === 10.168.116.0/24 TUNNEL
Security Associations (1 up, 0 connecting):
    alice[1]: ESTABLISHED 29 minutes ago, 192.168.34.15[CN=bob]...192.168.69.26[CN=alice]
    alice[1]: IKEv2 SPIs: c20483a6dbe16829_i* fc373141d281f135_r, public key reauthentication in 21 minutes
    alice[1]: IKE proposal: AES_GCM_16_256/PRF_HMAC_SHA2_512/MODP_4096
    alice{2}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c51b7328_i ce066c75_o
    alice{2}:  AES_GCM_16_256, 51441 bytes_i (193 pkts, 118s ago), 47766 bytes_o (187 pkts, 119s ago), rekeying in 2 minutes
    alice{2}:   10.168.117.0/24 === 10.168.116.0/24

Nur wenn die in der letzten Zeile angegebene Verbindung alice{2}: 10.168.117.0/24 === 10.168.116.0/24 zu sehen ist, dann kann diese erst genutzt werden. Ist diese Zeile nicht zu sehen, dann wird irgendwo in Log eine Fehlermeldung zu sehen sein, die meist einen wichtigen Hinweis auf den Grund dafür gibt.

IPsec und dynamisches Routing

IPsec ist seht gut zum Verschlüsseln von IP Paketen geeignet, jedoch routet es nichts, was nicht in der ipsec.conf steht. Dynamisches Routing mit z.B. OSPF oder BGP4 geht also damit nicht. Die Lösung: Ein GRE Tunnel. Man kann selbstverständlich auch andere Tunneltypen wie z.B. VTI verwenden, aber das kann nicht jede Plattform. Der Nachteil dieser Lösung besteht lediglich darin, das man bei jedem IP Paket noch mindestens 24Bytes zusätzlich übertragen muss.

auto mygre0
iface mygre0 inet static
	address 192.168.78.2 # IP Adresse des Tunnel Interfaces
	netmask 255.255.255.252 # Netzmaske des Tunnel Interfaces
	pre-up ip tunnel add mygre0 mode gre remote 10.168.116.1 local 10.168.117.1 ttl 255

Die Endpunkte des GRE Tunnels sind die beiden IPsec Endpunkte. Damit wird alles verschlüsselt, was über den GRE Tunnel geht. Das im Beispiel genannte Netz 192.168.78.0/30 ist aus Sicht des Linux Kernels (oder einer beliebigen anderen Plattform) eine ganz normale IP Verbindung, über die man routen kann. Läuft da auf beiden Seiten z.B. ein OSPF Prozess, dass werden darüber auch Routingtabellen ausgetauscht. Mit IS-IS klappt das zunächst natürlich nicht, weil das kein IP Protokoll ist. Bei Routern (z.B. Cisco oder Huawei), die auch OSI über GRE können, geht das jedoch.

Default Route über IPsec

Grundsätzlich kann man auch die Default Route über IPsec laufen lassen, dabei sind jedoch einige Spielregeln zu beachten, damit das auch funktioniert. Auf der Client Seite gibt man einfach die Default Routen als right an:

right=192.168.69.26
rightsubnet=0.0.0.0/0,2000::/3

Damit der Client seinen Server noch erreichen kann, muss hier 192.168.69.26 als Host Route in der Netzwerk Config angegeben werden. Ansonsten findet der IPsec Prozess sein Ziel nicht. IKE2 ist übrigens sehr praktisch, weil man da mehrere Routen angeben kann, in diesem Beispiel wird damit gleich auch noch IPv6 bearbeitet.

Damit der Host lokal erreichbar bleibt wird in der ipsec.conf noch folgende Connection benötigt:

conn lan
    leftsubnet=192.168.0.0/24,172.16.0.0/27,fd00::/16
    rightsubnet=192.168.0.0/24,172.16.0.0/27,fd00::/16
    authby=never
    type=passthrough
    auto=route

Ansonsten sind die Interfaces im LAN nicht mehr erreichbar. Die conn lan Einstellungen sind nur für den Client von Interesse, dieser schließt dann alle Netze von dem default IPsec aus, die im LAN liegen. Die im Beispiel genannten IP Netze müssen individuell an das LAN angepasst werden.

Es klappt nicht!

Firewall

Falls gar nichts zu sehen ist, dann blockt die Firewall vermutlich die Verbindung. Freigeschaltet müssen sein:

  • 500/udp
  • 4500/udp (falls IPsec über NAT geht)
  • esp
  • Manchmal triggern auch INVALID Rules, besonders wenn man noch GRE über IPsec fährt

Falls es nicht die Firewall ist, dann sollte man auch das Routing genauer untersuchen. Kommen die IP Pakete bei StrongSwan nicht an, dann kann auch keine IPsec Verbindung zustande kommen.

Verbindungsparameter

Sind auf beiden Seiten die gleichen Parameter konfiguriert?

  • ike=aes256gcm128-sha512-modp4096
  • esp=aes256gcm128-sha512-modp4096

Nicht irgend etwas annehmen, sondern hardcodiert setzen! Cisco hat andere Defaults als StrongSwan und StrongSwan hat andere Defaults als OpenBSD.

ipsec.secrets

Eine sehr beliebte Fehlerquelle ist auch ein vergessener private Key. Dieser muss in der ipsec.secrets angegeben werden. Falls im Logfile irgendwo Zeilen wie charon: 10[IKE] no private key found for… dann fehlt der private Key. Mit ipsec listcerts lässt sich das feststellen, wo da etwas fehlt. Da muss an passender Stelle * pubkey: ECDSA 521 bits, has private key* stehen (kann auch RSA sein, je nach Key). Wurder der Fehler behoben, dann erscheint im Log charon: 00[CFG] loaded ECDSA private key from…