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 環境,用於編譯源文件
