---
title: IPsec 与 IKEv2
url: https://doc.liz6.com/networking/08-vpn-and-tunnels/03-ipsec-and-ikev2
locale: zh
area: networking
tags:
- networking
- VPN与隧道
date: 2026-06-30
modified: 2026-06-30
description: 最"企业级"的 VPN 协议——深度嵌入内核网络栈,支持硬件卸载,广泛用于站点互连。IKEv2 用两次 exchange 建立 SA,MOBIKE 支持连接迁移。复杂度高,错误配置常表现为静默失败而非显式报错。
---

# IPsec 与 IKEv2

> 最"企业级"的 VPN 协议——深度嵌入内核网络栈,支持硬件卸载,广泛用于站点互连。IKEv2 用两次 exchange 建立 SA,MOBIKE 支持连接迁移。复杂度高,错误配置常表现为静默失败而非显式报错。

## 概述

IPsec 是最"企业级"的 VPN 协议——深度嵌入内核网络栈，支持硬件卸载，广泛用于站点互连和远程接入。但复杂度也最高：IKEv2 协商需要完整的状态机，错误配置往往表现为静默失败。IKEv2（2014）大幅简化了 IKEv1 的协商过程（2 个 exchange 建立 SA），并原生支持 MOBIKE（连接迁移）。strongSwan 和 libreswan 是 Linux 上的主要实现。

## IPsec 数据平面

ESP (IP protocol 50) 提供加密+完整性:

```
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 — 查接收方 SA
Sequence Number: 单调递增 (防重放)
Next Header: 封装的协议 (4=IPv4-in-IP tunnel, 6=TCP transport mode)
```

两种操作模式:

```
Transport Mode:
  [Original IP Header][ESP Header][TCP][Payload]
  原始 IP header 保留 (修改 Protocol field = 50)
  → 用于主机到主机, 节省额外 IP header

Tunnel Mode:
  [New IP Header][ESP Header][Original IP Header][TCP][Payload]
  → 用于网关到网关, 新 IP header 封装整个包
  → 原始包可以是 IPv4/IPv6 (IPsec 可以传输 IPv6 over IPv4)
```

## IKEv2 控制平面

IKEv2 (Internet Key Exchange v2, RFC 7296) 比 IKEv1 简单: 两个 exchange 建立 IKE SA + 第一个 Child SA。

```
IKE_SA_INIT (1 RTT, 明文):
  Initiator → Responder: SAi1, KEi, Ni
    SAi1: 提议的加密算法 (ENCR, PRF, INTEG, DH group)
    KEi: Diffie-Hellman public value
    Ni: nonce

  Responder → Initiator: SAr1, KEr, Nr, [CERTREQ]
    SAr1: 选定的算法 (从提议中选择)
    KEr: DH public value
    Nr: nonce

  双方各自: DH(KEi, KEr) → g^ir → SKEYSEED = prf(Ni | Nr, g^ir)
  → 派生: SK_d, SK_ai, SK_ar, SK_ei, SK_er, SK_pi, SK_pr

IKE_AUTH (1 RTT, 全部加密!):
  Initiator → Responder: IDi, [CERT], [CERTREQ], AUTH, SAi2, TSi, TSr
    IDi: 身份 (FQDN, email, IP, ...)
    AUTH: 对 IKE_SA_INIT 消息的签名 (用证书私钥)
    SAi2: 提议 Child SA
    TSi/TSr: Traffic Selector (哪些流量走此 Child SA)

  Responder → Initiator: IDr, [CERT], AUTH, SAr2, TSi, TSr
  双向认证完成

CREATE_CHILD_SA (< 0.5 RTT):
  用于: 创建更多 Child SA, 或 rekey 现有 SA (定期换 session key)
```

### 密钥派生

```
IKE SA:
  SKEYSEED = prf(Ni | Nr, g^ir)
  7 个密钥 = prf+(SKEYSEED, Ni | Nr | SPIi | SPIr)
    SK_d: 用于派生 Child SA 密钥
    SK_ai/ar: IKE_AUTH 消息的完整性密钥
    SK_ei/er: IKE_AUTH 消息的加密密钥
    SK_pi/pr: 生成 AUTH payload (签名)

Child SA (ESP):
  KEYMAT = prf+(SK_d, Ni | Nr | [g^ir_new])  ← for PFS: 新 DH 可选
```

## 参考

- **RFC**: 7296 (IKEv2), 4303 (ESP), 4301 (IPsec Architecture)
- **实现**: strongSwan (C), libreswan
- **工具**: `ipsec status`, `swanctl --list-sas`

*Keywords: IPsec, ESP, IKEv2, IKE_SA_INIT, IKE_AUTH, CREATE_CHILD_SA, strongSwan, tunnel mode, transport mode*
