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.

  • KNL: IPsec/Networking kernel interface

  • 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 oder Host-to-Host

  • Tunnelmodus: Network-to-Network oder 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

Logging. Damit das Logfile erfolgreich geschrieben werden kann, muss auch SELinux passend konfiguriert werden:

semanage fcontext --add --type ipsec_log_t "/var/log/charon\.log.*"
touch /var/log/charon.log
restorecon /var/log/charon.log
/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 = 2
            # flush each line to disk
            flush_line = yes
        }
        stderr {
            # more detailed loglevel for a specific subsystem, overriding the
            # default loglevel.
            asn = 1
            cfg = 3
            chd = 3
            enc = 1
            ike = 2
            job = 1
            knl = 2
            mgr = 3
            net = 1
        }
    }
}

Die einzelnen Log-Level:

  • -1: Absolutely silent

  • 0: Very basic auditing logs, (e.g. SA up/SA down)

  • 1: Generic control flow with errors, a good default to see whats going on

  • 2: More detailed debugging control flow

  • 3: Including RAW data dumps in hex

  • 4: Also include sensitive material in dumps, e.g. keys

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 = 1.2.3.4
        local_addrs = 2.3.4.5
        # 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
        }
    }
}

secrets {
    ike-<connname> {
        secret = mypassword
        id-0 = 1.2.3.4
        id-1 = 2.3.4.5
    }
}

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

Default /etc/strongswan/swanctl/swanctl.conf

# Section defining IKE connection configurations.
# connections {

    # Section for an IKE connection named <conn>.
    # <conn> {

        # IKE major version to use for connection.
        # version = 0

        # Local address(es) to use for IKE communication, comma separated.
        # local_addrs = %any

        # Remote address(es) to use for IKE communication, comma separated.
        # remote_addrs = %any

        # Local UDP port for IKE communication.
        # local_port = 500

        # Remote UDP port for IKE communication.
        # remote_port = 500

        # Comma separated proposals to accept for IKE.
        # proposals = default

        # Virtual IPs to request in configuration payload / Mode Config.
        # vips =

        # Use Aggressive Mode in IKEv1.
        # aggressive = no

        # Set the Mode Config mode to use.
        # pull = yes

        # Differentiated Services Field Codepoint to set on outgoing IKE packets
        # (six binary digits).
        # dscp = 000000

        # Enforce UDP encapsulation by faking NAT-D payloads.
        # encap = no

        # Enables MOBIKE on IKEv2 connections.
        # mobike = yes

        # Interval of liveness checks (DPD).
        # dpd_delay = 0s

        # Timeout for DPD checks (IKEV1 only).
        # dpd_timeout = 0s

        # Use IKE UDP datagram fragmentation (yes, accept, no or force).
        # fragmentation = yes

        # Use childless IKE_SA initiation (allow, force or never).
        # childless = allow

        # Send certificate requests payloads (yes or no).
        # send_certreq = yes

        # Send certificate payloads (always, never or ifasked).
        # send_cert = ifasked

        # String identifying the Postquantum Preshared Key (PPK) to be used.
        # ppk_id =

        # Whether a Postquantum Preshared Key (PPK) is required for this
        # connection.
        # ppk_required = no

        # Number of retransmission sequences to perform during initial connect.
        # keyingtries = 1

        # Connection uniqueness policy (never, no, keep or replace).
        # unique = no

        # Time to schedule IKE reauthentication.
        # reauth_time = 0s

        # Time to schedule IKE rekeying.
        # rekey_time = 4h

        # Hard IKE_SA lifetime if rekey/reauth does not complete, as time.
        # over_time = 10% of rekey_time/reauth_time

        # Range of random time to subtract from rekey/reauth times.
        # rand_time = over_time

        # Comma separated list of named IP pools.
        # pools =

        # Default inbound XFRM interface ID for children.
        # if_id_in = 0

        # Default outbound XFRM interface ID for children.
        # if_id_out = 0

        # Whether this connection is a mediation connection.
        # mediation = no

        # The name of the connection to mediate this connection through.
        # mediated_by =

        # Identity under which the peer is registered at the mediation server.
        # mediation_peer =

        # Section for a local authentication round.
        # local<suffix> {

            # Optional numeric identifier by which authentication rounds are
            # sorted.  If not specified rounds are ordered by their position in
            # the config file/VICI message.
            # round = 0

            # Comma separated list of certificate candidates to use for
            # authentication.
            # certs =

            # Section for a certificate candidate to use for authentication.
            # cert<suffix> =

            # Comma separated list of raw public key candidates to use for
            # authentication.
            # pubkeys =

            # Authentication to perform locally (pubkey, psk, xauth[-backend] or
            # eap[-method]).
            # auth = pubkey

            # IKE identity to use for authentication round.
            # id =

            # Client EAP-Identity to use in EAP-Identity exchange and the EAP
            # method.
            # eap_id = id

            # Server side EAP-Identity to expect in the EAP method.
            # aaa_id = remote-id

            # Client XAuth username used in the XAuth exchange.
            # xauth_id = id

            # cert<suffix> {

                # Absolute path to the certificate to load.
                # file =

                # Hex-encoded CKA_ID of the certificate on a token.
                # handle =

                # Optional slot number of the token that stores the certificate.
                # slot =

                # Optional PKCS#11 module name.
                # module =

            # }

        # }

        # Section for a remote authentication round.
        # remote<suffix> {

            # Optional numeric identifier by which authentication rounds are
            # sorted.  If not specified rounds are ordered by their position in
            # the config file/VICI message.
            # round = 0

            # IKE identity to expect for authentication round.
            # id = %any

            # Identity to use as peer identity during EAP authentication.
            # eap_id = id

            # Authorization group memberships to require.
            # groups =

            # Certificate policy OIDs the peer's certificate must have.
            # cert_policy =

            # Comma separated list of certificate to accept for authentication.
            # certs =

            # Section for a certificate to accept for authentication.
            # cert<suffix> =

            # Comma separated list of CA certificates to accept for
            # authentication.
            # cacerts =

            # Section for a CA certificate to accept for authentication.
            # cacert<suffix> =

            # Identity in CA certificate to accept for authentication.
            # ca_id =

            # Comma separated list of raw public keys to accept for
            # authentication.
            # pubkeys =

            # Certificate revocation policy, (strict, ifuri or relaxed).
            # revocation = relaxed

            # Authentication to expect from remote (pubkey, psk, xauth[-backend]
            # or eap[-method]).
            # auth = pubkey

            # cert<suffix> {

                # Absolute path to the certificate to load.
                # file =

                # Hex-encoded CKA_ID of the certificate on a token.
                # handle =

                # Optional slot number of the token that stores the certificate.
                # slot =

                # Optional PKCS#11 module name.
                # module =

            # }

            # cacert<suffix> {

                # Absolute path to the certificate to load.
                # file =

                # Hex-encoded CKA_ID of the CA certificate on a token.
                # handle =

                # Optional slot number of the token that stores the CA
                # certificate.
                # slot =

                # Optional PKCS#11 module name.
                # module =

            # }

        # }

        # children {

            # CHILD_SA configuration sub-section.
            # <child> {

                # AH proposals to offer for the CHILD_SA.
                # ah_proposals =

                # ESP proposals to offer for the CHILD_SA.
                # esp_proposals = default

                # Use incorrect 96-bit truncation for HMAC-SHA-256.
                # sha256_96 = no

                # Local traffic selectors to include in CHILD_SA.
                # local_ts = dynamic

                # Remote selectors to include in CHILD_SA.
                # remote_ts = dynamic

                # Time to schedule CHILD_SA rekeying.
                # rekey_time = 1h

                # Maximum lifetime before CHILD_SA gets closed, as time.
                # life_time = rekey_time + 10%

                # Range of random time to subtract from rekey_time.
                # rand_time = life_time - rekey_time

                # Number of bytes processed before initiating CHILD_SA rekeying.
                # rekey_bytes = 0

                # Maximum bytes processed before CHILD_SA gets closed.
                # life_bytes = rekey_bytes + 10%

                # Range of random bytes to subtract from rekey_bytes.
                # rand_bytes = life_bytes - rekey_bytes

                # Number of packets processed before initiating CHILD_SA
                # rekeying.
                # rekey_packets = 0

                # Maximum number of packets processed before CHILD_SA gets
                # closed.
                # life_packets = rekey_packets + 10%

                # Range of random packets to subtract from packets_bytes.
                # rand_packets = life_packets - rekey_packets

                # Updown script to invoke on CHILD_SA up and down events.
                # updown =

                # Hostaccess variable to pass to updown script.
                # hostaccess = no

                # IPsec Mode to establish (tunnel, transport, transport_proxy,
                # beet, pass or drop).
                # mode = tunnel

                # Whether to install IPsec policies or not.
                # policies = yes

                # Whether to install outbound FWD IPsec policies or not.
                # policies_fwd_out = no

                # Action to perform on DPD timeout (clear, trap or restart).
                # dpd_action = clear

                # Enable IPComp compression before encryption.
                # ipcomp = no

                # Timeout before closing CHILD_SA after inactivity.
                # inactivity = 0s

                # Fixed reqid to use for this CHILD_SA.
                # reqid = 0

                # Optional fixed priority for IPsec policies.
                # priority = 0

                # Optional interface name to restrict IPsec policies.
                # interface =

                # Netfilter mark and mask for input traffic.
                # mark_in = 0/0x00000000

                # Whether to set *mark_in* on the inbound SA.
                # mark_in_sa = no

                # Netfilter mark and mask for output traffic.
                # mark_out = 0/0x00000000

                # Netfilter mark applied to packets after the inbound IPsec SA
                # processed them.
                # set_mark_in = 0/0x00000000

                # Netfilter mark applied to packets after the outbound IPsec SA
                # processed them.
                # set_mark_out = 0/0x00000000

                # Inbound XFRM interface ID.
                # if_id_in = 0

                # Outbound XFRM interface ID.
                # if_id_out = 0

                # Optional security label (e.g. SELinux context), IKEv2 only.
                # Refer to label_mode for details on how labels are processed.
                # label =

                # Security label mode (system, simple or selinux), IKEv2 only.
                # label_mode = system

                # Traffic Flow Confidentiality padding.
                # tfc_padding = 0

                # IPsec replay window to configure for this CHILD_SA.
                # replay_window = 32

                # Enable hardware offload for this CHILD_SA, if supported by the
                # IPsec implementation.
                # hw_offload = no

                # Whether to copy the DF bit to the outer IPv4 header in tunnel
                # mode.
                # copy_df = yes

                # Whether to copy the ECN header field to/from the outer IP
                # header in tunnel mode.
                # copy_ecn = yes

                # Whether to copy the DSCP header field to/from the outer IP
                # header in tunnel mode.
                # copy_dscp = out

                # Action to perform after loading the configuration (none, trap,
                # start).
                # start_action = none

                # Action to perform after a CHILD_SA gets closed (none, trap,
                # start).
                # close_action = none

            # }

        # }

    # }

# }

# Section defining secrets for IKE/EAP/XAuth authentication and private key
# decryption.
# secrets {

    # EAP secret section for a specific secret.
    # eap<suffix> {

        # Value of the EAP/XAuth secret.
        # secret =

        # Identity the EAP/XAuth secret belongs to.
        # id<suffix> =

    # }

    # XAuth secret section for a specific secret.
    # xauth<suffix> {

    # }

    # NTLM secret section for a specific secret.
    # ntlm<suffix> {

        # Value of the NTLM secret.
        # secret =

        # Identity the NTLM secret belongs to.
        # id<suffix> =

    # }

    # IKE preshared secret section for a specific secret.
    # ike<suffix> {

        # Value of the IKE preshared secret.
        # secret =

        # IKE identity the IKE preshared secret belongs to.
        # id<suffix> =

    # }

    # Postquantum Preshared Key (PPK) section for a specific secret.
    # ppk<suffix> {

        # Value of the PPK.
        # secret =

        # PPK identity the PPK belongs to.
        # id<suffix> =

    # }

    # Private key decryption passphrase for a key in the private folder.
    # private<suffix> {

        # File name in the private folder for which this passphrase should be
        # used.
        # file =

        # Value of decryption passphrase for private key.
        # secret =

    # }

    # Private key decryption passphrase for a key in the rsa folder.
    # rsa<suffix> {

        # File name in the rsa folder for which this passphrase should be used.
        # file =

        # Value of decryption passphrase for RSA key.
        # secret =

    # }

    # Private key decryption passphrase for a key in the ecdsa folder.
    # ecdsa<suffix> {

        # File name in the ecdsa folder for which this passphrase should be
        # used.
        # file =

        # Value of decryption passphrase for ECDSA key.
        # secret =

    # }

    # Private key decryption passphrase for a key in the pkcs8 folder.
    # pkcs8<suffix> {

        # File name in the pkcs8 folder for which this passphrase should be
        # used.
        # file =

        # Value of decryption passphrase for PKCS#8 key.
        # secret =

    # }

    # PKCS#12 decryption passphrase for a container in the pkcs12 folder.
    # pkcs12<suffix> {

        # File name in the pkcs12 folder for which this passphrase should be
        # used.
        # file =

        # Value of decryption passphrase for PKCS#12 container.
        # secret =

    # }

    # Definition for a private key that's stored on a token/smartcard.
    # token<suffix> {

        # Hex-encoded CKA_ID of the private key on the token.
        # handle =

        # Optional slot number to access the token.
        # slot =

        # Optional PKCS#11 module name to access the token.
        # module =

        # Optional PIN required to access the key on the token. If none is
        # provided the user is prompted during an interactive --load-creds call.
        # pin =

    # }

# }

# Section defining named pools.
# pools {

    # Section defining a single pool with a unique name.
    # <name> {

        # Addresses allocated in pool.
        # addrs =

        # Comma separated list of additional attributes from type <attr>.
        # <attr> =

    # }

# }

# Section defining attributes of certification authorities.
# authorities {

    # Section defining a certification authority with a unique name.
    # <name> {

        # CA certificate belonging to the certification authority.
        # cacert =

        # Absolute path to the certificate to load.
        # file =

        # Hex-encoded CKA_ID of the CA certificate on a token.
        # handle =

        # Optional slot number of the token that stores the CA certificate.
        # slot =

        # Optional PKCS#11 module name.
        # module =

        # Comma-separated list of CRL distribution points.
        # crl_uris =

        # Comma-separated list of OCSP URIs.
        # ocsp_uris =

        # Defines the base URI for the Hash and URL feature supported by IKEv2.
        # cert_uri_base =

    # }

# }

# Include config snippets
include conf.d/*.conf

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

unterminated string detected, oder syntax error, unexpected STRING_ERROR, expecting NAME or NEWLINE or '}':

Lag in unserem Fall an Double-Quotes im Passwort der secret-Angabe.

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

tcpdump -nn -p --interface 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 --snapshot-length 0 -n --interface nflog:5