strongSwan

strongSwan unterscheidet seit Version 5.x zwischen der ursprünglichen „deprecated“ Konfigurationsmöglichkeiten (und dem strongswan-Kommando unter RHEL / ipsec unter Debian), und der mit dem neuen swanctl-Kommando aufkommenden Config-Language.

Links

Begriffe:

  • Charon: ist der IKE-Daemon von strongSwan.

  • IKE: Internet Key Exchange, Austausch von Schlüsseln. IKE gibt es in v1 (Einsatz wird nicht empfohlen) und v2.

  • PFS: Perfect Forward Secrecy, z.B. per Diffie-Hellman-Group

  • PRF: Pseudo-Random Functions

  • PSK: Pre-Shared Key

  • SA: Security Association = ausgehandelte gemeinsame Algorithmen, Modi und Schlüssel zwischen zwei Endpunkten. Nutzen Shared Secrets. Security Associations laufen nach einer gewissen Zeit ab.

  • Transportmodus: Gateway-to-Gateway/Host-to-Host

  • Tunnelmodus: Network-to-Network/Site-to-Site

  • Encapsulation Protokolle (jeweils alternativ):

    • AH: Authentication Header, für Datenintegrität

    • ESP (meist der Standard): Encapsulating Security Payload, teil des IPSec-Protokollstacks, verschlüsselt und authentifiziert Datenpakete. Wird in Phase 2 Quick Mode ausgehandelt

Welche Angaben werden zur Einrichtung benötigt?

  • Art der Verbindung (transport oder tunnel)

  • IKE-Version: IKEv1 oder IKEv2 (empfohlen)

  • Public und Private IP Adresse, Gateway, CIDR Netzmaske für die lokale Maschine

  • Public und Private IP Adresse der Gegenstelle, zu der man sich verbindet

  • Shared Secret Passwort (falls Authentifizierung per PSK erfolgt)

  • Werte für IKE-Group und ESP-Group

Installation

# from EPEL-Repository
dnf -y install strongswan

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
echo "net.ipv6.conf.all.forwarding = 1" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.accept_redirects = 0" >> /etc/sysctl.conf
echo "net.ipv4.conf.all.send_redirects = 0" >> /etc/sysctl.conf

Firewall:

  • lokale Firewall > remote: Port 500/udp und Proto ESP freigeben

  • remote > lokale Firewall: Port 500/udp

  • SNAT-Regel: Client lokal > Client remote

  • Translated Source: Original Linux routet dann selbst nativ (nicht per ip r ersichtlich) in den IPsec-Tunnel.

Verwendung (swanctl-basiert)

Globale Konfiguration:

/etc/strongswan/strongswan.conf
charon {
    load_modular = yes
    plugins {
        include strongswan.d/charon/*.conf
    }
    interfaces_use = eth0
}

include strongswan.d/*.conf

Mit mehr Logging:

/etc/strongswan/strongswan.conf
charon {
    ...
    filelog {
        charon {
            # path to the log file, specify this as section name in versions prior to 5.7.0
            path = /var/log/charon.log
            # add a timestamp prefix
            time_format = %b %e %T
            # prepend connection name, simplifies grepping
            ike_name = yes
            # overwrite existing files
            append = no
            # increase default loglevel for all daemon subsystems
            default = 3
            # flush each line to disk
            flush_line = yes
        }
        stderr {
            # more detailed loglevel for a specific subsystem, overriding the
            # default loglevel.
            cfg = 3
            chd = 3
            ike = 2
            knl = 2
            mgr = 3
        }
    }
}

Beispiel-Konfiguration einer Site2Site-Connection (connname z.B. durch den Namen der Gegenstelle ersetzen) mit zwei Subnetzen:

/etc/strongswan/swanctl/conf.d/connname.conf
connections {
    connname {
        include /etc/strongswan/swanctl/conf.d/ike_sa_default.conf
        rekey_time = 24h
        reauth_time = 0
        version = 1
        remote_addrs = 198.51.100.10
        local_addrs = 203.0.113.20
        # https://docs.strongswan.org/strongswan-docs/5.9/config/IKEv2CipherSuites.html
        # IKE Policy: encryptionAlgo-integrityAlgo-PRF-DHKeyExchangeGroup
        proposals = aes256-sha256-modp2048, default
        children {
            connname1 {
                # IPSec Parameters / ESP:
                include /etc/strongswan/swanctl/conf.d/child_sa_default.conf
                start_action = start
                # for non-AEAD: integrityAlgo-encryptionAlgo-optDHGroup-optExtendedSequenceNumberMode
                esp_proposals = sha256-aes256-modp2048, default
                local_ts = 192.0.2.0/24
                remote_ts = 172.30.0.0/16
                rekey_time = 8h
            }
            connname2 {
                # IPSec Parameters / ESP:
                include /etc/strongswan/swanctl/conf.d/child_sa_default.conf
                start_action = start
                # for non-AEAD: integrityAlgo-encryptionAlgo-optDHGroup-optExtendedSequenceNumberMode
                esp_proposals = sha256-aes256-modp2048, default
                local_ts = 192.0.5.0/24
                remote_ts = 192.0.2.0/16
                rekey_time = 8h
            }
        }
        local {
            auth = psk
        }
        remote {
            auth = psk
        }
    }
}
pools {
}
authorities {
}
secrets {
    ike-connname {
        secret = mypassword
            id-0 = 198.51.100.10
            id-1 = 203.0.113.20
        }
    }
}

Als Dienst:

systemctl enable --now strongswan

Status abfragen, bei Verwendung der neuen Language:

swanctl --list-conns
swanctl --list-sas

Gezielt eine einzelne Verbindung ab- und neu aufbauen:

swanctl --terminate --child $CHILD_SA_NAME
swanctl --initiate --child $CHILD_SA_NAME

swanctl Cheat Sheet

swanctl --counters         (-C)  list or reset IKE event counters
swanctl --flush-certs      (-f)  flush cached certificates
swanctl --help             (-h)  show usage information
swanctl --initiate         (-i)  initiate a connection
swanctl --install          (-p)  install a trap or shunt policy
swanctl --list-algs        (-g)  show loaded algorithms
swanctl --list-authorities (-B)  list loaded authority configurations
swanctl --list-certs       (-x)  list stored certificates
swanctl --list-conns       (-L)  list loaded configurations
swanctl --list-pols        (-P)  list currently installed policies
swanctl --list-pools       (-A)  list loaded pool configurations
swanctl --list-sas         (-l)  list currently active IKE_SAs
swanctl --load-all         (-q)  load credentials, authorities, pools and connections
swanctl --load-authorities (-b)  (re-)load authority configuration
swanctl --load-conns       (-c)  (re-)load connection configuration
swanctl --load-creds       (-s)  (re-)load credentials
swanctl --load-pools       (-a)  (re-)load pool configuration
swanctl --log              (-T)  trace logging output
swanctl --monitor-sa       (-m)  monitor for IKE_SA and CHILD_SA changes
swanctl --redirect         (-d)  redirect an IKE_SA
swanctl --rekey            (-R)  rekey an SA
swanctl --reload-settings  (-r)  reload daemon strongswan.conf
swanctl --stats            (-S)  show daemon stats information
swanctl --terminate        (-t)  terminate a connection
swanctl --uninstall        (-u)  uninstall a trap or shunt policy
swanctl --version          (-v)  show version information

Deprecated strongSwan

Beispiel-Konfiguration einer Host-to-Host-Connection:

/etc/strongswan/ipsec.conf
config setup
    strictcrlpolicy=yes
    uniqueids = no

# Add connections here.
# Sample VPN connections
conn sample-self-signed
    leftsubnet=10.1.0.0/16
    leftcert=selfCert.der
    leftsendcert=never
    right=192.168.0.2
    rightsubnet=10.2.0.0/16
    rightcert=peerCert.der
    auto=start

conn sample-with-ca-cert
    leftsubnet=10.1.0.0/16
    leftcert=myCert.pem
    right=192.168.0.2
    rightsubnet=10.2.0.0/16
    rightid="C=CH, O=Linux strongSwan CN=peer name"
    auto=start

Manueller Start:

strongswan start
strongswan up sample-with-ca-cert

Status abfragen, bei Verwendung der „deprecated“ Language:

strongswan status
strongswan statusall

ipsec.secrets - strongSwan IPsec Credentials (wird von Charon verwaltet):

/etc/strongswan/ipsec.secrets
# customer:
192.0.2.19 1.2.3.4 : PSK "my-secret-psk"
192.0.2.20 %any : PSK "other-secret-psk"

DH Groups

Diffie-Hellman Key Groups:

  • DH1: enstpricht „modp768“ bit Modular Exponential (MODP) algorithm.

  • DH2: modp1024-bit MODP algorithm.

  • DH14: modp2048-bit MODP group.

  • DH15: modp3072-bit MODP algorithm.

  • DH16: modp4096-bit MODP algorithm.

  • DH19: modp256-bit random Elliptic Curve Groups modulo a Prime (ECP groups) algorithm. (IKEv2 only)

  • DH20: 384-bit random ECP groups algorithm. (IKEv2 only)

  • DH21: 521-bit random ECP groups algorithm. (IKEv2 only)

  • DH24: modp2048-bit MODP Group with 256-bit prime order subgroup. (IKEv2 only)

Route based vs Policy based

Im Unterschied zu anderer VPN-Software wie beispielsweise OpenVPN verwendet IPsec standardmässig keine Routen, sondern sogenannte Policies. Dies erkennt man unter anderem daran, dass strongSwan nach dem Start kein neues Netzwerk-Interface (siehe ip addr) anlegt. Stattdessen kann man die aktuellen Policies wie folgt einsehen:

ip xfrm policy show
ip -statistic xfrm policy show

ip xfrm state
ip -statistic xfrm state

ip xfrm monitor
ip xfrm monitor all

Wer IPsec so konfiguieren möchte, dass tatsächlich Routen verwendet werden, folgt https://docs.strongswan.org/strongswan-docs/5.9/features/routeBasedVpn.html.

Deinstallation

dnf remove trousers strongswan
rm -rf /etc/strongswan

In älteren Versionen User und Group „tss“ entfernen.

Troubleshooting

Logging:

tail -f /var/log/messages
# or
journalctl -fx -u strongswan

Bemerkung

Wer IPsec-Traffic monitoren will und auf /var/log/messages und iptables schaut, sollte bedenken, dass die IP-Pakete durch die IPsec-Funktionen des Kernels Pre- und Postrouted werden - iptables wird die in der Regel also nicht zu Gesicht bekommen.

Ist die Gegenstelle erreichbar?

dnf -y install nmap-ncat
ncat -z --udp --verbose --wait 3 ipsec.example.com 500

Testen des entfernten VPN-Servers (vorher müssen dazu alle IPSec-Services gestoppt werden):

dnf -y install ike-scan
ike-scan ipsex.example.com -vvv --ikev2

Traffic mithilfe von tcpdump beobachten (siehe https://docs.strongswan.org/docs/5.9/install/trafficDumps.html)

tcpdump -nn -p -i eth2 esp or net 192.168.0.112/32 -e

# more details, decapsulated

iptables -t raw -I PREROUTING -p esp -j NFLOG --nflog-group 5
iptables -t raw -I PREROUTING -p ah -j NFLOG --nflog-group 5
iptables -t raw -I PREROUTING -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5

iptables -t raw -I OUTPUT -p esp -j NFLOG --nflog-group 5
iptables -t raw -I OUTPUT -p ah -j NFLOG --nflog-group 5
iptables -t raw -I OUTPUT -p udp -m multiport --dports 500,4500 -j NFLOG --nflog-group 5

iptables -t mangle -I PREROUTING -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5
iptables -t mangle -I POSTROUTING -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

iptables -t filter -I INPUT -m addrtype --dst-type LOCAL -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5

iptables -t filter -I FORWARD -m addrtype ! --dst-type LOCAL -m policy --pol ipsec --dir in -j NFLOG --nflog-group 5

iptables -t filter -I OUTPUT -m policy --pol ipsec --dir out -j NFLOG --nflog-group 5

# Getting the traffic
tcpdump -s 0 -n -i nflog:5