从OpenSwan自身构建×××,到最后用L2TP与X.509证书构成较为普遍的IPSec ×××,中间遇到了很多挫折,一起写在这里。 
在整个过程中,主要参考下面几篇文章:
九尾银狐的“开源Linux ×××解决方案 - OpenSWan安装配置指南”一文。地址: [url]http://www.entage.net/1/viewspace_8112.html[/url]
以及“Use L2TP and OpenSwan To build IPSec ×××”。这是我起的名字,因为似乎作者nate.carlson没给它起名字。我转贴了一下,地址: [url]http://blog.csdn.net/purewinter/archive/2007/05/23/1623336.aspx[/url]。原文地址也在转贴里写明了。
然后是师兄写的说明文档(没有贴到网上)。师兄后来又写了一个,可谓短小精悍,呵呵。^_^
本文所用软件:
Red Hat Enterprise Linux AS 4 (kernel 2.6.9-42EL)
Openssl 0.97a
OpenSwan 4.4.7
L2TPD 0.69(12jdl.i386.rpm) / XL2TPD 1.1.09
其中Openssl其实只是用来做CA功能的,可以用其它CA工具如OpenCA代替。
而xl2tpd则是代替l2tpd的。个人推荐使用。当然,如果你使用l2tpd没有问题,也无妨。这两个软件的设置几乎一模一样,毕竟都是L2TP的daemon嘛。
Openssl只是起到CA的作用,简要说一下安装过程:
解压后进入目录,输入命令:
./config --prefix=/usr/local/openssl 设置安装文件夹。
然后就make,再make install即可。
 
实验的网络配置和拓扑结构:
由于条件所限,使用的是VMware虚拟机。
简要说明一下在VM中的网络设置。在VMware提供的Manage Network Tools中的Host Virtual Network Mapping把VMNet2设为Not bridged,点击右边的“>”按钮-subnet,IP地址填入192.168.2.0。确定。
×××Gateway虚拟机需要在虚拟机设置中添加一个网卡。然后在每个虚拟机中Linux下照下表设置各个网卡,并在
虚拟机设置中选择网卡对应的网络。其中×××Gateway的网卡0属于VMNet0,网卡1属于VMNet2。网卡1的默认网卡设为192.168.2.1。另外,XP本机自动位于VMNet0,不需要进行设置。
机器名网卡0(eth0)网卡1默认网关所属网络角色说明
PureWinter192.168.0.2 192.168.0.2VMNet0XP Client
×××Gateway192.168.0.254192.168.2.1192.168.0.254VMNet0,VMNet2×××Gateway
Jim192.168.2.2 192.168.2.1VMNet2网关后服务器
其中,192.168.0.0/24网段模拟外网,XP本机模拟外网拨号的×××客户机。192.168.2.0/24网段模拟内网,Jim为内网中一台机器。可以当作提供某个服务的应用服务器。
 
0.使用Openssl为各个机器颁发证书
建立CA工作目录:(推荐为/root/ca/demoCA)由于demoCA为openssl的默认CA工作目录,存放CA的一些信息,所以还需要一个目录为我们存放各个机器的证书,所以要建立两层目录(ca和ca/demoCA)。当然也可以这样:CA在/root/demoCA,证书在/root/certs。

建立CA:(以下CA.sh指openssl安装目录/ssl/misc/CA.sh)使用命令
CA.sh -newca或命令
openssl req –x509 –days 3650 –newkey rsa:1024 –keyout cakey.pem –out cacert.pem
使用openssl命令建立以后,还要进入demoCA目录执行以下命令:
mkdir newcerts
touch index.txt
echo “01” > serial
请确认在demoCA/private目录下有cakey.pem文件。若没有请复制过来。
CA生成以后,在demoCA上级目录输入openssl ca -gencrl -out crl.pem生成证书吊销列表文件。

为×××Gateway生成证书(以下命令请在demoCA的上一级目录下执行,如/root/ca下):
使用命令CA.sh -newreq
或Openssl req –newkey rsa:1024 –keyout ***gateway.key –out ***gatewayreq.pem
这样得到了×××Gateway的私钥。然后使用命令
CA.sh -sign
或Openssl ca –in ***gatewayreq.pem –days 365 –out ***gateway.cert –notext
为其签名并生成证书。
使用CA.sh的方式,需要把生成的newreq.pem改名成***gateway.key,把newcert.pem改名成***gateway.cert。

由上文可以看出,CA操作即可以使用CA.sh,也可以使用openssl命令。区别是CA.sh简单易用,但是功能简单,而openssl命令功能强大,但是比较复杂。需要定制比较多的时候使用openssl命令更加方便。
为其它机器生成证书与为×××Gateway生成证书类似。
 
1.安装OpenSwan
安装之前,需要修改配置。在/etc/sysctl.conf文件中,找到
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1 
改为:
net.ipv4.ip_forward = 1
net.ipv4.conf.default.rp_filter = 0
然后执行sysctl -p使之生效。

下载OpenSwan,解压:tar zxvf openswan-2.4.7.tar.gz
进入openswan-2.4.7目录,编译,生成,安装:
make programs
make install
安装本身没有太多好说的。但是linux内核版本在2.6.9以下的(如Red Hat Linux 9),需要打Nat补丁。而2.6.9及其以上版本(如我使用的AS 4)不需要打补丁。
安装完成后验证安装:ipsec --version
以及IPSec状态验证:ipsec verify。

OpenSWan主要配置文件
/etc/ipsec.secrets                 用来保存private RSA keys 和 preshared secrets (PSKs)
/etc/ipsec.conf                    配置文件(settings, options, defaults, connections)
OpenSWan主要配置目录
/etc/ipsec.d/cacerts               存放X.509认证证书(根证书-"root certificates")
/etc/ipsec.d/certs                 存放X.509客户端证书(X.509 client Certificates)
/etc/ipsec.d/private               存放X.509认证私钥(X.509 Certificate private keys)
/etc/ipsec.d/crls                  存放X.509证书撤消列表(X.509 Certificate Revocation Lists)
/etc/ipsec.d/ocspcerts             存放X.500 OCSP证书(Online Certificate Status Protocol certificates)
/etc/ipsec.d/passwd                XAUTH密码文件(XAUTH password file)
/etc/ipsec.d/policies              存放Opportunistic Encryption策略组(The Opportunistic Encryption policy groups)
 
2.使用OpenSwan测试构建IPSec通道(可跳过)
此步只是测试使用。验证不使用L2TP之前,OpenSwan能正常构建IPSec通道。
Openswan提供两种模式:net-to-net模式和roadwarrior模式。简单的说,net-to-net是两个×××网关互联,为双方后面的内网互连提供安全通道的模式,而roadwarrior是一个客户端和一个×××网关相连,为客户端与×××网关后的内网提供安全通道的模式。关于这两种模式的具体说明和net-to-net模式的设置,见九尾银狐的帖子或其它网上说明。下面简单说明一下roadwarrior下的设置。
客户端(Laptop):JIm。×××服务器:×××Gateway. 服务器后的内网: 无或位于VMNet1的任意机器,如PureWinter
Jim和×××Gateway机器需要安装OpenSwan。其它机器不需要。
复制证书(在机器之间复制证书请确保安全性):
cp cacert.pem  /etc/ipsec.d/cacerts
cp ***gateway.cert  /etc/ipsec.d/certs
cp ***gateway.key  /etc/ipsec.d/private
在Jim机器上,除了上面三个文件,还需要把jim.cert复制到/etc/ipsec.d/certs,把jim.key复制到/etc/ipsec.d/private

编辑/etc/ipsec.secerts:
在此文件最后加上一行(以×××Gateway为例)
: RSA /etc/ipsec.d/private/***gateway.key "读取此key的密码"
jim机器类似。注意RSA前面有一个冒号。引号内用你生成key时输入的密码替换。
编辑×××Gateway的/etc/ipsec.conf文件:如下:
version 2.0
config setup
  interfaces=%defaultroute
 nat_traversal=yes
 virtual_private=%v4:192.168.0.0/16,%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:!192.168.0.0/24
conn %default
 compress=yes
 authby=rsasig
 leftrsasigkey=%cert
 rightrsasigkey=%cert
 
conn roadwarrior
 left=192.168.2.1
 leftcert=***gateway.cert
 leftsubnet=192.168.0.0/24
 right=%any
 auto=add

include /etc/ipsec.d/examples/no_oe.conf

编辑jim的/etc/ipsec.conf文件:除了roadwarrior一段,其它与×××Gateway的配置文件相同。
 conn roadwarrior
 left=192.168.2.2
 leftcert=jim.cert
 right=192.168.2.1
 rightcert=***gateway.cert
 rightsubnet=192.168.0.0/24
 auto=add
在JIm上输入命令ipsec auto --up roadwarrior ,启动Ipsec。
在×××Gateway上输入命令tcpdump -i eth1,可以监听数据包,应已被加密。不过,其实这种方式只有Jim想访问×××Gateway后的内网机器,数据包才会被加密,Jim与×××Gateway互相访问的数据包并不会被加密。可以在Jim上使用命令ping 192.168.0.254
然后再ping 192.168.0.2,
查看×××Gateway的tcpdump监听到的数据包对比得知。如果到×××网关也要加密,则双方的配置文件中的subnet一行要提出来,放到新的conn roadwarrior-net一段中去,并再加上一行:also=roadwarrior。然后在jim机器上执行ipsec auto --up roadwarrior,
再执行ipsec auto --up roadwarrior-net。 (注意:若已启动Ipsec,则修改配置以后要重启IPSec服务。)
关于roadwarrior以及使用RSA认证的方法,net-to-net模式,还可参见toorq的“用Openswan组建Linux IPSec”一文。地址: [url]http://www.xfocus.net/articles/200610/891.html[/url]
 
3.安装L2TPD
如果只使用L2TP的IPSec,L2TPD和OpenSwan都只需要在×××Gateway上安装。L2TPD是整个过程折磨我最多的东西了。这里我把通常情况和我遇到的问题分开进行说明。
安装的是l2tpd-0.69-12jdl.i386.rpm:双击这个rpm包,或输入命令:rpm -i l2tpd-0.69-12jdl.i386.rpm;
安装的是l2tpd-0.69.tar.gz或l2tpd-0.70pre.tar.gz:强烈建议不要安装0.69源包。解压后进入目录,输入命令make即可。生成l2tpd文件以后,可以复制到/usr/local/sbin下。
安装的是xl2tpd-1.1.09.tar.gz:解压后进入目录,输入make,回车,再输入make install回车。
问题说明:其实在目前的Linux平台上,l2tpd的原版,包括0.70pre,直接编译是通不过的。都会在某个文件(似乎是avp.c)的某一行"__FUNCTION__"之前出错。仔细一看,是一个叫log的函数调用,而"__FUNCTION__"之前少了一个分隔参数的逗号!我真的要晕倒了。。。0.70pre只有这一处有问题,而0.69版本还在其它地方多处出现字符串之中出现不应该出现的回车符而导致的gcc报错。据说这是gcc变严格了,以前可以通过。不过即使编译成功,0.69原版还是有相当多的bug需要打补丁。特别是其中有个pty(tty)的bug,虽然不一定在每个机器上都出问题,但偏偏在我这里出了问题,而且无论是rpm版,还是0.70pre,还是换pty补丁都无济于事。最后还是使用的xl2tp才解决问题。
配置文件路径说明:
rpm版的配置文件在/etc/l2tpd/l2tpd.conf
普通版的配置文件在/etc/l2tp/l2tpd.conf
xl2tpd的配置文件或者使用普通版的路径和名称,或者在/etc/xl2tpd/xl2tpd.conf
 
4.×××Gateway的设置
首先说明使用证书作为IPSec认证方式时的配置方法。
与l2tp相关的设置:
/etc/ppp/chap-secrets文件:在最后加入一行
test   *    "test123456"    *

含义是test用户的密码是test123456。最后那个*号可以换成IP地址或网段,表示这个用户只能在这个地址或网段拨号,否则无效。这个用户名地址就是在拨号前要填的用户名密码,就像拨宽带连接时的用户名密码一样。
/etc/ppp/options.l2tp文件:全部替换成如下内容
ipcp-accept-local
ipcp-accept-remote
#ms-dns  202.96.209.6
#需要设置dns,就把上一行的#号去掉
ms-wins 192.168.0.2
#noccp
auth
crtscts
idle 1800
mtu 1200
mru 1200
#mtu需要小于1500。也可以设成其它值,如1300
nodefaultroute
debug
lock
connect-delay 5000
logfile /var/log/l2tpd.log
proxyarp
/etc/l2tpd/l2tpd.conf文件(或/etc/xl2tpd.conf或/etc/l2tp/l2tpd.conf):注意此文件注释使用分号
[global]
listen-addr = 192.168.0.254
port=1701
auth file = /etc/ppp/chap-secrets
[lns default]
;exclusive = no
ip range = 192.168.2.128-192.168.2.254
;ip range即l2tp拨号成功后分配给客户端的ip地址范围。
local ip = 192.168.0.254
;lac = 0.0.0.0-255.255.255.255
require chap = yes
refuse pap = yes
require authentication = yes
name = ×××Gateway
ppp debug = yes
pppoptfile = /etc/ppp/options.l2tp
length bit = yes

注:原版l2tpd0.69没有listen-addr设置项。其余版本(rpm版,0.70pre,xl2tpd)均有此设置。
与OpenSwan相关的设置:
/etc/ipsec.secerts文件:与 2.使用OpenSwan测试构建IPSec通道中相同。
/etc/ipsec.conf文件:(可参照2中的文件进行修改。需要把conn roadwarrior整段都注释掉)
version 2.0 
config setup
  interfaces=%defaultroute
 nat_traversal=yes
 virtual_private=%v4:192.168.0.0/16,%v4:10.0.0.0/8,%v4:172.16.0.0/12,%v4:!192.168.0.0/24
conn %default
 compress=yes
 authby=rsasig
 disablearrivalcheck=no
 leftrsasigkey=%cert
 rightrsasigkey=%cert
 keyingtries=1
     
conn l2tpx509
 pfs=no
 auto=add
 left=192.168.0.254
 leftcert=***gateway.cert
 leftprotoport=17/1701
 right=%any
 rightca=%same
 rightprotoport=17/%any
 
include /etc/ipsec.d/examples/no_oe.conf
输入命令service ipsec restart重启ipsec服务。
输入命令l2tpd -D以前台模式启动L2TPD服务。使用XL2TPD则输入xl2tpd -D。如果不加-D的参数,将以后台服务的方式运行l2tpd,不实时显示连接信息。
输入命令tcpdump -i eth0监视数据包。可能需要加参数host 192.168.0.254以缩小监视的信息范围。
 
5.Windows端的设置
导出CA和Win端的证书:
在×××Gateway的demoCA的上一级目录下,用以下命令导出CA证书为p12文件:
openssl pkcs12 -export -in democA/cacert.pem -inkey demoCA/private/cakey.pem  -out demoCA.p12
输入读取CA密钥的密码,然后再指定导出p12文件中的证书需要的密码,再确认此密码即可。
然后导出win端的证书:
openssl pkcs12 -export -in purewinter.cert -inkey purewinter.key -out purewinter.p12
把这两个文件通过安全方式复制到Windows客户端。
导入证书:
运行mmc,添加删除管理单元->添加->证书->计算机账户->本地计算机->完成。
在证书:本地计算机里,选择个人->所有任务->导入,导入两个p12证书。把CA的证书由个人拖到“受信任的根证书颁发机构”里。
添加拨号连接:
网络连接->创建一个新连接->连接到我工作场所的网络->虚拟专用网络连接->随意输入一个名字->不拨初始连接->192.168.0.254->完成。
右键点此连接,选属性-网络-×××类型选择为L2TP IPSec ×××,选定TCP/IP协议,属性-高级,去掉“在远程网络上使用默认网关”的勾。确定。(此步是防止IPSec ×××的拨号连接建立以后,夺去原来宽带拨号的路由,导致宽带拨号假断线。如果宽带接入方式不是拨号则可跳过此步。)
双击此连接,输入用户名test,密码test123456。拨号。如果顺利,就拨号成功了。在×××Gateway的tcpdump可以看到加密信息在传输,L2TPD的输出中可以看到Call established with 192.168.0.2...等字样。
在Jim上输入service httpd start启动Apache服务,然后在Win客户端的浏览器中输入 [url]http://192.168.2.2[/url],就可以看到Jim上架设的网站了。如果没有架设,可能看到Apache的默认页面,或者看到403禁止访问,Apache 2.x.x的信息。至此L2TP的IPSec ×××架设成功。
 
6.使用预共享密钥的IPSec设置
×××Gateway端:
/etc/ipsec.secerts文件:最后加入一行:其中123456即为预共享的密钥。
192.168.0.254  %any  : PSK "123456"

/etc/ipsec.conf文件:注释掉conn l2tpx509段的所有行。加入以下行:
conn l2tp
 authby=secret
 pfs=no
 auto=add
 type=transport 
 left=192.168.0.254
 leftprotoport=17/1701
 right=%any
 rightprotoport=17/%any
输入service ipsec restart重启ipsec。
Win端:
右键点击×××拨号连接,属性-安全-IPSec设置-输入预共享密钥“123456”。确定。
然后再拨号试试。顺利的话应该直接成功。