On this page
IPsec and IKEv2
The most "enterprise-grade" VPN protocol—deeply embedded in the kernel network stack, supporting hardware offload, and widely used for site-to-site interconnection. IKEv2 establishes SAs in two exchanges, and MOBIKE supports connection mobility. High complexity; misconfigurations often manifest as silent failures rather than explicit errors.
Overview
IPsec is the most "enterprise-grade" VPN protocol—deeply embedded in the kernel network stack, supporting hardware offload, and widely used for site-to-site interconnection and remote access. However, it is also the most complex: IKEv2 negotiation requires a complete state machine, and misconfigurations often manifest as silent failures. IKEv2 (2014) significantly simplified the IKEv1 negotiation process (establishing an SA in 2 exchanges) and natively supports MOBIKE (connection mobility). strongSwan and libreswan are the primary implementations on Linux.
IPsec Data Plane
ESP (IP protocol 50) provides encryption and integrity:
ESP Packet:
[SPI (4B)][Sequence Number (4B)]
[Encrypted: Payload + Padding + Pad Length + Next Header]
[ESP Auth (ICV, variable, 12B for GCM)]
SPI: Security Parameter Index — used to look up the receiving SA
Sequence Number: Monotonically increasing (prevents replay attacks)
Next Header: Encapsulated protocol (4=IPv4-in-IP tunnel, 6=TCP transport mode)
Two operational modes:
Transport Mode:
[Original IP Header][ESP Header][TCP][Payload]
Original IP header is preserved (Protocol field modified to 50)
→ Used for host-to-host, saving the overhead of an extra IP header
Tunnel Mode:
[New IP Header][ESP Header][Original IP Header][TCP][Payload]
→ Used for gateway-to-gateway, where the new IP header encapsulates the entire packet
→ The original packet can be IPv4 or IPv6 (IPsec can transport IPv6 over IPv4)
IKEv2 Control Plane
IKEv2 (Internet Key Exchange v2, RFC 7296) is simpler than IKEv1: two exchanges are required to establish an IKE SA and the first Child SA.
IKE_SA_INIT (1 RTT, plaintext):
Initiator → Responder: SAi1, KEi, Ni
SAi1: Proposed encryption algorithms (ENCR, PRF, INTEG, DH group)
KEi: Diffie-Hellman public value
Ni: nonce
Responder → Initiator: SAr1, KEr, Nr, [CERTREQ]
SAr1: Selected algorithms (chosen from proposals)
KEr: DH public value
Nr: nonce
Both sides compute: DH(KEi, KEr) → g^ir → SKEYSEED = prf(Ni | Nr, g^ir)
→ Derive: SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, SK_pr
IKE_AUTH (1 RTT, all encrypted!):
Initiator → Responder: IDi, [CERT], [CERTREQ], AUTH, SAi2, TSi, TSr
IDi: Identity (FQDN, email, IP, ...)
AUTH: Signature over the IKE_SA_INIT messages (using certificate private key)
SAi2: Proposed Child SA
TSi/TSr: Traffic Selectors (which traffic flows through this Child SA)
Responder → Initiator: IDr, [CERT], AUTH, SAr2, TSi, TSr
Mutual authentication completed
CREATE_CHILD_SA (< 0.5 RTT):
Used for: Creating additional Child SAs, or rekeying existing SAs (periodically rotating session keys)
Key Derivation
IKE SA:
SKEYSEED = prf(Ni | Nr, g^ir)
7 keys = prf+(SKEYSEED, Ni | Nr | SPIi | SPIr)
SK_d: Used to derive Child SA keys
SK_ai/ar: Integrity keys for IKE_AUTH messages
SK_ei/er: Encryption keys for IKE_AUTH messages
SK_pi/pr: Used to generate AUTH payload (signature)
Child SA (ESP):
KEYMAT = prf+(SK_d, Ni | Nr | [g^ir_new]) ← for PFS: new DH optional
References
- RFC: 7296 (IKEv2), 4303 (ESP), 4301 (IPsec Architecture)
- Implementations: strongSwan (C), libreswan
- Tools:
ipsec status,swanctl --list-sas
Keywords: IPsec, ESP, IKEv2, IKE_SA_INIT, IKE_AUTH, CREATE_CHILD_SA, strongSwan, tunnel mode, transport mode