IKE/IPSec 属于网络层安全协议,保护 IP 及上层的协议安全。自上个世纪末面世以来,关于这两个协议的研究、应用,已经非常成熟。协议本身,也在不断地进化。仅以 IKE 为例,其对应的 RFC 编号从 RFC 2407/2408/2409 演化成 RFC 4306,再演化为 RFC 5996,最新版本是 RFC 7296。
为什么要分成两个协议呢?这两个协议有什么区别?从密码学角度看,IKE 用于密钥交换,IPSec 用于保护后续的通信。而保护通信的密钥,就来自 IKE 协议运行的结果。(在 SSL/TLS 协议中,密钥生成和加密保护都是在单独一个协议中完成的,在这一点上,两者各有千秋)
本篇仍采用庖丁解牛的思路:进行一次实验,抓一次报文,用密码学验算一次。文中采用 python 作为验证工具。
实验环境搭建
服务器采用 Linux 上著名的开源实现 strongSwan(版本 4.4.0),操作系统为 Ubuntu Server 12.10(VMware 虚拟环境)。
客户端采用 Windows 7 内置的 IPSec VPN 客户端。
虚拟机运行在 Windows 7 上,配置双网卡,分别使用 NAT 和 Host-only 工作模式。两块网卡映射 Linux 中对应为 eth0 和 eth1。
IKE 与 IPSec 框架十分复杂,仅协议的使用就有多种选择。
比如 IKE 分为 IKEv1/IKEv2 两个版本,认证方式也有多种。IPSec 工作模式又分为 Tunnel 和 Transport 两种,具体实现协议又有 AH 和 ESP 之分。
考虑实际的测试环境和应用场景,本文中 IKE 协议使用 IKEv2/证书认证。IPSec 使用 Tunnel/ESP 模式。
网络拓扑如下
下载、编译、安装 strongSwan 4.4.0。一句话,就是 ./configure && make && make install 三步曲。
过程就不多说,唯一需要说明:strongSwan 要求 gmp 库支持。为简单起见,所有命令行操作均使用 root 身份。
生成 CA 证书(下面使用 OpenSSL,也可以使用 strongSwan 自带的 pki 命令)
root@ubuntu:~# openssl genrsa -des3 -out cakey.pem -passout pass:123456 1024 root@ubuntu:~# openssl req -sha1 -days 3650 -new -key cakey.pem -out cacertreq.pem -passin pass:123456 -subj "/C=CN/ST=HZ/O=VPN/CN=strongSwan CA" root@ubuntu:~# mkdir -p demoCA/newcerts # 创建 CA 目录 root@ubuntu:~# touch demoCA/index.txt root@ubuntu:~# echo 01 > demoCA/serial root@ubuntu:~# openssl ca -batch -selfsign -extensions v3_ca -days 3650 -in cacertreq.pem -keyfile cakey.pem -passin pass:123456 -out ca.cer
临时修改 OpenSSL 配置文件
root@ubuntu:~# cp /etc/ssl/openssl.cnf ./
修改文件 openssl.cnf:
[ v3_ca ] authorityKeyIdentifier = keyid,issuer extendedKeyUsage = serverAuth
之所以这样(加上红色这一行),是因为 Windows 7 要求对端服务器证书具有【服务器身份验证】扩展属性,见下图
生成服务器证书
root@ubuntu:~# openssl genrsa -des3 -out serverkey.pem -passout pass:123456 1024 root@ubuntu:~# openssl req -sha1 -new -key serverkey.pem -out servercertreq.pem -passin pass:123456 -subj "/C=CN/ST=HZ/O=VPN/CN=server.vpn.cn" root@ubuntu:~# openssl ca -batch -config ./openssl.cnf -extensions v3_ca -days 3650 -in servercertreq.pem -cert ca.cer -keyfile cakey.pem -passin pass:123456 -out server.cer
安装 CA 及服务器证书到 strongSwan
root@ubuntu:~# cp ca.cer /usr/local/etc/ipsec.d/cacerts/ root@ubuntu:~# cp server.cer /usr/local/etc/ipsec.d/certs/ root@ubuntu:~# cp serverkey.pem /usr/local/etc/ipsec.d/private/
配置 strongSwan
root@ubuntu:~# cat /usr/local/etc/ipsec.conf # ipsec.conf - strongSwan IPsec configuration file # basic configuration config setup charondebug="cfg 4, chd 4, dmn 4, enc 4, ike 4, job 4, knl 4, lib 4, mgr 4, net 4" charonstart=yes plutostart=no # Add connections here. conn linux-vs-win7 authby=pubkey left=%defaultroute right=%any keyexchange=ikev2 compress=no auto=add pfs=no leftauth=pubkey rightauth=pubkey rightid=%any leftsubnet=1.2.3.0/24 leftsourceip=1.2.3.123 rightsourceip=1.2.3.0/24 leftcert=server.cer leftfirewall=yes root@ubuntu:~# cat /usr/local/etc/ipsec.secrets : RSA serverkey.pem "123456"
生成客户端证书并打包成 PKCS12 格式
root@ubuntu:~# openssl genrsa -des3 -out clientkey.pem -passout pass:123456 1024 root@ubuntu:~# openssl req -sha1 -new -key clientkey.pem -out clientcertreq.pem -passin pass:123456 -subj "/C=CN/ST=HZ/O=VPN/CN=VPN Client" root@ubuntu:~# openssl ca -batch -days 3650 -in clientcertreq.pem -cert ca.cer -keyfile cakey.pem -passin pass:123456 -out client.cer root@ubuntu:~# openssl pkcs12 -export -passin pass:123456 -passout pass:123456 -in client.cer -inkey clientkey.pem -out client.p12
将 PKCS12 及 CA 证书复制到 Windows 7 并安装到计算机帐户,点击【开始菜单】->【运行】->【mmc】,按下图所示,添加证书管理单元
导入客户端及 CA 证书
新建 VPN 连接
配置 VPN 连接属性:IKEv2 接入 VPN 网关
配置本地 DNS,在文件 c:\windows\system32\drivers\etc\hosts 最后一行加上
192.168.203.129 server.vpn.cn
配置结束,启动连接
root@ubuntu:~# ipsec start --nofork
Windows 7 下双击新建的 VPN 连接
下面是成功后的连接状态(已经获得服务器端分配的 IP 地址
连接过程中,Linux 命令行将输出一连串调试信息,这些信息在后面的计算验证中将用到
Python 环境准备
下载 Python 密码库 PyCrypto 的最新版本文件 pycrypto-2.6.1.tar.gz,解压到 C:\Python27\Lib
C:\Python27\Lib\pycrypto-2.6.1>python setup.py install
说明:安装过程中需要 Visual Studio 环境,用于编译源文件