IPSec 原理与部署
IPSec 原理与部署
一个公司怎么把北京和上海办公室连起来
某公司北京总部和上海分部各有一台路由器,两个办公室内部都用私有 IP(192.168.0.0/16)。但 192.168.1.0/24 和 192.168.2.0/24 之间需要直接通信——员工出差到上海要访问北京的文件服务器。
如果租用运营商专线(MPLS),年费几十万。如果用公网 IPsec VPN,两台路由器之间建一个加密隧道,私有 IP 包被加密后通过公网传输,效果一样但成本是专线的 1/10。
IPsec(Internet Protocol Security)就是干这事的。1995 年 IETF 在 IPv6 设计阶段就把它纳入标准,2005 年 RFC 4301-4309 重新修订成今天用的版本。它是 IP 层的"信封"——给 IP 包加上加密和认证两个属性,原始 IP 包对中间路由器完全不可见。
问题一:IPsec 要解决什么
问题清单:
- 机密性:别人不能看到包里的内容(加密)
- 完整性:包在传输过程中没被篡改(认证)
- 真实性:对方真的是我以为的那个路由器,不是冒充的(身份认证)
- 重放保护:攻击者不能截包重发(防 replay 攻击)
对应 IPsec 的核心机制:
| 机制 | 解决问题 |
|---|---|
| ESP(Encapsulating Security Payload) | 加密 + 认证 + 重放保护 |
| AH(Authentication Header) | 仅认证 + 重放保护(不加密) |
| IKE(Internet Key Exchange) | 双方协商密钥、身份认证 |
IPsec 不是一个协议,是一组协议。AH、ESP、IKE 各有独立 RFC 编号。
问题二:传输模式 vs 隧道模式
IPsec 有两种工作模式,区别在加密/认证的范围:
传输模式(Transport Mode):只加密载荷,IP 头明文保留:
适用:主机到主机(两端 IP 都可达)。目的 IP 明文——包必须能被路由到真实主机。
隧道模式(Tunnel Mode):加密整个原始 IP 包,套上新 IP 头:
适用:VPN 网关到网关(企业标准模式)。中间路由器只看到新 IP 头,公网可路由。
对比示例:
公司北京网关 IP 203.0.113.5,上海网关 IP 198.51.100.10,北京内网 192.168.1.0/24,上海内网 192.168.2.0/24。
传输模式包(主机到主机加密):
[IP: 192.168.1.100 → 192.168.2.100] [TCP] [应用数据]
[IP: 192.168.1.100 → 192.168.2.100] [ESP] [加密的 TCP] [应用数据]中间路由器看到目的 IP 192.168.2.100——这在公网上不可路由,包到不了。所以传输模式只能用于两台主机的 IP 都在公网可达时(比如服务器到服务器直接 IPsec)。
隧道模式包(VPN):
[IP: 192.168.1.100 → 192.168.2.100] [TCP] [应用数据]
[新 IP: 203.0.113.5 → 198.51.100.10] [ESP] [加密的 192.168.1.100→192.168.2.100 + TCP + 数据]中间路由器只看到 203.0.113.5 → 198.51.100.10(两个 VPN 网关的公网 IP),包在公网上正常路由。到达上海网关后解密,看到内网真实目的 IP 192.168.2.100,转发到内网。
企业 VPN 几乎都用隧道模式——这是 IPsec 的主要应用场景。
问题三:ESP 和 AH 的区别
ESP(Encapsulating Security Payload, RFC 4303):
ESP 是 IPsec 主力。提供加密 + 认证 + 重放保护三件套。
| 新 IP 头 | ESP 头 | 加密载荷 | ESP 尾 | ESP 认证 |
| | SPI | | 填充 | ICV |- SPI(Security Parameters Index, 32 位):标识用哪个 SA(Security Association)
- 加密载荷:原始 IP 包内容,用 AES-CBC 或 ChaCha20 加密
- ESP 尾:填充字节(让加密数据对齐 4 字节)+ 填充长度 + 下一个头(IP 协议号)
- ESP 认证(ICV, Integrity Check Value):对 ESP 头 + 加密载荷 + ESP 尾计算 HMAC
加密和认证算法独立可选。常见组合:
| 加密 | 认证 | 套件名 |
|---|---|---|
| AES-128-CBC | HMAC-SHA256 | esp-aes128-sha256 |
| AES-256-GCM | AES-GCM(自带认证) | esp-aes256-gcm |
| ChaCha20-Poly1305 | Poly1305 | esp-chacha20-poly1305 |
AES-GCM 和 ChaCha20-Poly1305 是 AEAD(认证加密)算法,同时提供加密和认证,效率比 CBC+HMAC 组合高。
AH(Authentication Header, RFC 4302):
AH 只做认证,不加密。AH 头插入在 IP 头之后、传输层之前:
| IP 头 | AH | TCP 头 + 数据 |AH 认证范围比 ESP 广——AH 认证包括 IP 头的不可变部分(源/目的 IP、TTL 等),ESP 只认证自己的头和载荷。AH 安全性更高,但因为不加密,实际几乎没人用——既然要做认证加密,为啥不直接用 ESP?
ESP vs AH 取舍:
- 99% 场景用 ESP(加密 + 认证)
- 极少数内网场景用 AH(不加密但认证包头,例如防 IP 欺骗)
- 现代 IPsec 实现(如 strongSwan)默认只支持 ESP
问题四:SA 和 SPI 是什么
SA(Security Association):两个 IPsec 端点之间协商出的"安全合同",包含:
- 用什么加密算法
- 用什么认证算法
- 共享密钥
- 密钥有效期
- SPI 值
SA 是单向的——A→B 一个 SA,B→A 另一个 SA。一个 IPsec 隧道(双向通信)需要 2 个 SA。
SPI(Security Parameters Index):SA 的 32 位标识符。每个 IPsec 包都带 SPI,接收方按 SPI 找到对应的 SA,用 SA 里的密钥解密认证。
抓包看 ESP:
# IPsec ESP 用 IP 协议号 50
tcpdump -ni eth0 -X 'proto 50'
# ESP 头结构
# 0x0000: 00000001 00000002 ← SPI=1, Seq=2
# 0x0008: 00000000 00000010 ← IV(如果是 CBC 模式)
# 0x0010: ... 加密载荷 ...Seq 字段是防重放用的序列号,每发一个包递增 1。接收方记录"已经收到的最大 Seq",小于这个的包视为重放丢弃。
问题五:IKE 怎么协商密钥
IKE(Internet Key Exchange)是 IPsec 最复杂的部分。IKEv1(RFC 2409)1998 年标准化,过程繁复;IKEv2(RFC 7296)2014 年简化,主流实现都已经支持 IKEv2。
IKEv2 协商流程(4 个包搞定):
图注:IKEv2 共 4 个包,比 IKEv1(6-9 个)大幅简化。DH 交换保证前向保密。
关键步骤详解:
IKE_SA_INIT:双方交换 DH(Diffie-Hellman)公开值。一个 2048 位的 DH 公开值约 256 字节。DH 交换的结果是双方都得到一个共享秘密,任何中间人都算不出来——这是 IKE 安全性的核心。
IKE_SA_INIT 响应:双方各自用对方的 DH 公开值和私钥计算共享秘密。这个共享秘密用于加密 IKE 后续的协商本身(防窃听)。
IKE_AUTH(Initiator):用共享秘密派生的密钥认证 Initiator 身份。身份可以是 PSK(预共享密钥)、证书、或者 RSA 签名。
IKE_AUTH(Responder):同样认证 Responder 身份,双方互相确认"我连的是真 B,不是中间人"。
为什么需要 DH 交换?理论上可以直接用 PSK 加密,但 PSK 是固定密钥,每次连接用同样的 key 容易被攻击。DH 每次连接生成不同的临时密钥,前向保密(Forward Secrecy)——即使长期私钥未来某天泄露,之前的会话密钥也算不出来。
IKEv2 vs IKEv1:
| 维度 | IKEv1 | IKEv2 |
|---|---|---|
| 协商包数 | 6-9 个 | 4 个 |
| 失败恢复 | 整过程重来 | 单个请求可重试 |
| 移动性 | 不支持 MOBIKE | 支持 MOBIKE(IP 变连接不中断) |
| 认证方法 | 多种独立 | 统一抽象 |
IKEv2 抓包:
# IKE 用 UDP 500 端口(NAT 穿越用 4500)
tcpdump -ni eth0 -X 'udp port 500'问题六:IPsec 的两种部署方式
站点到站点(Site-to-Site)VPN:
公司两个办公室的路由器之间建 IPsec 隧道。员工在办公室直接用内网 IP 通信,无感 VPN 存在。配置在路由器上。
[北京办公室] --[北京 VPN 网关]======公网======[上海 VPN 网关]-- [上海办公室]
192.168.1.0/24 203.0.113.5 198.51.100.10 192.168.2.0/24这是隧道模式 + ESP 的典型应用。
远程访问(Remote Access)VPN:
员工出差或在家,用笔记本/手机通过 IPsec 客户端软件连公司 VPN 网关。客户端获得一个内网 IP(如 10.10.10.50),所有流量经公司网关转发。
[员工笔记本] --[公网/酒店 WiFi]--[公司 VPN 网关]-- [公司内网]
10.10.10.50远程访问用 传输模式 + ESP 或 隧道模式 + ESP 都行,取决于是否需要把内网 IP 完全隐藏。
问题七:strongSwan 配置实战
strongSwan 是 Linux 上最成熟的 IPsec 实现(strongswan.org)。
安装:
# Ubuntu/Debian
sudo apt install strongswan strongswan-pki
# 启动
sudo systemctl enable strongswan
sudo systemctl start strongswan站点到站点 IPsec 配置(/etc/ipsec.conf):
conn beijing-shanghai
left=203.0.113.5 # 北京网关公网 IP
leftsubnet=192.168.1.0/24 # 北京内网
right=198.51.100.10 # 上海网关公网 IP
rightsubnet=192.168.2.0/24 # 上海内网
authby=secret # 用 PSK 认证
ike=aes256-sha256-modp2048 # IKE 阶段 1 算法
esp=aes256gcm16 # ESP 加密算法
keyexchange=ikev2
auto=start
type=tunnel # 隧道模式PSK 配置(/etc/ipsec.secrets):
203.0.113.5 198.51.100.10 : PSK "very-long-random-preshared-key-1234567890"重启并验证:
sudo ipsec restart
sudo ipsec statusall
# 输出会显示 beijing-shanghai conn established
# 抓包看 ESP 流量
sudo tcpdump -ni eth0 -X 'proto 50'
# 测试连通性
ping 192.168.2.1基于证书的认证(更安全):
# 生成 CA
ipsec pki --gen --type rsa --size 4096 --outform pem > caKey.pem
ipsec pki --self --ca --in caKey.pem --type rsa --dn "CN=VPN CA" --outform pem > caCert.pem
# 生成服务器证书
ipsec pki --gen --type rsa --size 4096 --outform pem > serverKey.pem
ipsec pki --pub --in serverKey.pem --type rsa | ipsec pki --issue --cacert caCert.pem --cakey caKey.pem --dn "CN=203.0.113.5" --san "203.0.113.5" --outform pem > serverCert.pemauthby= 改成 pubkey 即可使用证书。
问题八:IPsec 与 NAT 的冲突
NAT 修改 IP/端口,IPsec 的完整性校验会因为包被改而失败。这就是为什么 IPsec 和 NAT 历史上不能共存。
解决方案:NAT-Traversal(NAT-T, RFC 3947):
- 把 ESP 包整个封装在 UDP 4500 端口里
- NAT 设备只改 UDP 头,IPsec 完整性不受影响
- IKE 协商时自动探测是否需要 NAT-T
# strongSwan 默认启用 NAT-T
sudo sysctl net.ipv4.ip_forward
# 输出:net.ipv4.ip_forward = 1问题九:IPsec 性能
IPsec 加密解密是 CPU 密集型。AES-NI 指令集(Intel/AMD CPU 内置)让 AES 加解密性能提升 10 倍。10Gbps IPsec 隧道在现代服务器上可以达到 8-9 Gbps 吞吐。
Linux 内核态 vs 用户态:
- 内核态(kernel IPsec):性能高,但调试难,密钥管理复杂
- 用户态(strongSwan + charon):配置灵活,性能略低
- 硬件加速(Intel QAT、Mellanox ConnectX):专用芯片,最高吞吐
问题十:WireGuard 的崛起
IPsec 30 年了,配置复杂。2017 年 Jason Donenfeld 推出 WireGuard——目标是"用 SSH 一样简单的 VPN"。
- 配置只需 5 行
- 性能比 IPsec 高 2-3 倍
- 基于 Curve25519、ChaCha20、Poly1305 现代算法
- 内核态实现,Linux 5.6+ 内置
WireGuard 不算 IPsec 的继任(协议层面完全不同),但实际部署中很多场景用 WireGuard 替代 IPsec。Linux 内核 2020 年起把 WireGuard 合入主线。
# WireGuard 配置示例
[Interface]
PrivateKey = cFHr6GfK0q5f2v4X8...
Address = 10.0.0.1/24
ListenPort = 51820
[Peer]
PublicKey = Hb6C3pP9v4kY2n5j1...
Endpoint = 198.51.100.10:51820
AllowedIPs = 192.168.2.0/24实战命令
# Linux 看内核 IPsec 状态
ip xfrm state # SA 表
ip xfrm policy # SPD 策略数据库
# strongSwan 操作
ipsec statusall
ipsec listall
ipsec rereadall
ipsec reload
# 抓 ESP 流量
tcpdump -ni eth0 -X 'proto 50'
# 抓 IKE 协商
tcpdump -ni eth0 -X 'udp port 500 or udp port 4500'
# 测 IPsec 隧道
ping 192.168.2.1
mtr 192.168.2.1
# 看 IPsec 性能
iperf3 -c 192.168.2.1思考题
- 假设你设计一个企业 IPsec VPN,连接 10 个分支机构(hub-and-spoke 拓扑)。每个 spoker 只需要和 hub 通信,spoker 之间不需要。SA 数量怎么规划?IKE 协商过程怎么优化?
- IPsec 的 ESP 用 AES-GCM 加密。GCM 模式对每个包用一次性的 IV(随机数)。如果 IV 重复会怎样?(提示:GCM 在 IV 重复时会泄露明文 XOR)
- IPsec 传输模式和隧道模式各适合什么场景?一个 Web 服务器用 IPsec 保护与数据库的通信,传输模式还是隧道模式?
- IKE 阶段 1(IKE_SA_INIT)协商的是 IKE 本身的安全关联,阶段 2(IKE_AUTH)协商的是 IPsec SA。为什么 IKE 协议要分两阶段?为什么不一次性协商完?
- 抓一次
ipsec statusall输出,分析其中每个 SA 的细节(SPI、算法、密钥有效期)。如果 SA 即将到期会看到什么?到期后会发生什么? - WireGuard 只支持 UDP,IPsec 既支持 ESP(IP 协议 50)也支持 NAT-T(UDP 4500)。在某些严格限制 UDP 出口流量的企业防火墙环境下,IPsec 和 WireGuard 哪个更可能失败?为什么?
延伸阅读
- RFC 4301: Security Architecture for IP
- RFC 4303: IP Encapsulating Security Payload (ESP)
- RFC 4302: IP Authentication Header (AH)
- RFC 7296: Internet Key Exchange Protocol Version 2 (IKEv2)
- RFC 3947: Negotiation of NAT-Traversal in the IKE
- 《IPSec: The New Security Standard for VPNs, Intranets, and Remote Access》(Naganand Doraswamy)
- strongSwan 官方文档:strongswan.org/docs
- 动手实验:用两台 Linux 机器搭一个 IPsec 隧道,抓包观察 ESP 头和 IKE 协商过程