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