Saturday, August 9, 2008

l2tp over ipsec in Linux @ CUHK

[Last updated : Aug. 9th, 2008]

由于ITSC声称将于2008年9月1日开始正式停止PPTP服
务,而使用L2TP服务,
因此刚进来这两天虽然忙,但是还是要先把最基本的东西搞好,以便于日后的长久使用。

1. 原来的pptp VPN接入:
在ITSC的site有很详细的介绍:
http://www.cuhk.edu.hk/itsc/network/vpn/vpn.html
http://www.cuhk.edu.hk/itsc/network/vpn/ubuntu.html

2. l2tp over ipsec VPN接入:
注意:ipsec和l2tp是两个无关的东西,但是,
据说由于windows的ipsec和l2tp是捆绑在一起的,
所以只能一起把它们做了……

关于这两个东西,我看了一篇很好的文章:
Openswan - IPsec on Linux for the Future

主要是介绍了ipsec在linux的现状,
clarify了主要是两种方法,一是内核集成的ipsec支持+racoon+ipsec-tools,一是*swan家族。
在此不再赘述。

本人首先参考了这篇文章:
Using Linux as an L2TP/IPsec client
(另外该系列文章还有介绍linux,
windows上的server,client设置,强烈推荐)

然后发觉设置不大成功,运行不起来,搜了好久也不知道结果,
因此下面介绍使用racoon的方法。
注: 后来经过研究,发觉还是能配置起来的,主要是l2tp的问题。

总结一下使用的软件:
ipsec : racoon, ipsec-tools / openswan(或strongswan)
l2tp: xl2tpd( 基于l2tpd的一个fork )

3.ipsec链接的建立

ipsec和l2tp是不同的,我们必须先建立ipsec链接,
然后再建立l2tp链接。实际上一个包应该是这样的:
| ppp header | l2tp header | ipsec header | ip header |  payload |

这就是所谓的l2tp over ipsec.
不过ppp的位置我还有点混淆,不敢确定,以后补上。

在写这篇文章时主要参考了:
http://liuchuan.org/cuhk/l2tp_ipsec.html

也是介绍类似的情况,但是在使用之中我与它有一点出入(
gentoo vs ubuntu)
因此在这里做一个备忘(假设kernel是2.6系列的)。

另外这个页面
http://www.wogri.at/index.php?id=194
似乎也有有用信息,但是没来得及看。

以下步骤,3.1与3.2任选1个即可。

3.1. 使用racoon
1)设置 racoon:编辑/etc/racoon/racoon.
conf,内容与上文一致。
path pre_shared_key "/etc/racoon/psk.txt";

padding {
        maximum_length 20;
        randomize off;
        strict_check off;
        exclusive_tail off;
}
remote anonymous {
        exchange_mode main;
        doi ipsec_doi;
        situation identity_only;
        generate_policy on;
        proposal_check obey;
        proposal {
                encryption_algorithm des;
                hash_algorithm sha1;
                authentication_method pre_shared_key;
                dh_group 1;
        }
}
sainfo anonymous {
        lifetime time 28800 sec;
        encryption_algorithm 3des;
        authentication_algorithm hmac_md5;
        compression_algorithm deflate;
}

2) 编辑/etc/racoon/psk.txt
10.0.255.248 ipsec-vpn
10.0.255.249 ipsec-vpn
10.0.255.250 ipsec-vpn
10.0.255.251 ipsec-vpn
10.0.255.252 ipsec-vpn
10.0.255.253 ipsec-vpn
10.0.255.254 ipsec-vpn
这里就是ITSC提到的pre-shared key的地方了


3) 建立ipsec链接:
/etc/init.d/racoon start

3.2.使用openswan
1)  修改/etc/ipsec.conf
version 2

conn L2TP-PSK-CLIENT
        authby=secret
        pfs=no
        rekey=yes
        keyingtries=3
        type=transport
        left=%defaultroute
        leftprotoport=17/1701
        right=ipsec-vpn.resnet.cuhk.edu.hk
        rightprotoport=17/1701
        auto=add

2) 修改/etc/ipsec.secrets
localhost %any : PSK "ipsec-vpn"

3)
建立ipsec链接:
sudo /etc/init.d/ipsec start

4.l2tp的建立
1)编辑/etc/xl2tpd/xl2tpd.conf
[global]
port = 1701
auth file = /etc/xl2tpd/l2tp-secrets

[lac ResNet]
lns = ipsec-vpn.resnet.cuhk.edu.hk
redial = yes
require pap = yes
ppp debug = no
pppoptfile = /etc/ppp/options.xl2tpd
2) 编辑/etc/ppp/options.xl2tpd  (这个文件与上一个文件最后一行相对应)
noauth
lock
debug
mtu 1000
nobsdcomp
nodeflate
noaccomp
nopcomp
novj
defaultroute
replacedefaultroute  --> 以上两行使得自动更新route表而无须手动更新
name <your name> --> 这里填写用户名
3) 编辑/etc/l2tpd/l2tp-secrets
<your name> ipsec-vpn.resnet.cuhk.edu.hk <password>
在上面填写自己的用户名和密码。

4) 启动服务
首先建立一个这样的文件夹(即使使用xl2tpd,似乎也无法自动建立这个文件夹):
$ sudo mkdir /var/run/xl2tpd
然后启动xl2tpd
$ sudo /etc/init.d/xl2tpd start
使用
$ sudo xl2tpd -D
来使l2tp运行于前台查看debug信息。

最后建立连接:
$ sudo sh -c 'echo "c ResNet" > /var/run/xl2tpd/l2tp-control'
这个是中断连接:
$ sudo sh -c 'echo "d ResNet" > /var/run/xl2tpd/l2tp-control'

5) 总结
要建立连接的最后命令可以归纳为:
$ sudo /etc/init.d/racoon start
或者
$ sudo /etc/init.d/ipsec start

$ sudo mkdir /var/run/xl2tpd
$ sudo touch /var/run/xl2tpd/l2tp-control
$ sudo touch /
$ /etc/init.d/xl2tpd start
$ sudo sh -c 'echo "c ResNet" > /var/run/xl2tpd/l2tp-control'

6) 脚本(完善中,我的脚本实在烂)
$ sudo vi /usr/local/sbin/vpnon
#!/bin/bash
# use this script to build/stop l2tp/ipsec between PC and CUHK's VPN LNC

# check if it is root user
if [ $UID -ne 0 ]
then
    echo "Must be root!"
    exit 1
fi

# first we build ipsec channel
sudo /etc/init.d/ipsec start

# create the folder and file
sudo mkdir -p /var/run/xl2tpd
sudo touch /var/run/xl2tpd/l2tp-control

# run xl2tpd
sudo /etc/init.d/xl2tpd start

# sleep 3 seconds to wait for the PPP on
IP=''
count=0
MAX_TRY=5
while [ $count -lt $MAX_TRY ]
do
    count=$(($count+1))
    echo "trying " $count "first time"
    # just assume the face is ppp0
    IP=`ifconfig ppp0 2>/dev/null | awk '/inet/{print $2}' | awk -F: '{print $2}'`
    if [ "$IP" != '' ]
    then
        printf "IP is %s\n" $IP
        break;
    fi
    sleep 1
done


if [ $count -gt $MAX_TRY ]
then
    echo "Can't create connection"
    exit 1
else
    # create connection
    sudo sh -c 'echo "c ResNet" > /var/run/xl2tpd/l2tp-control'
    # show connection
    echo $IP
fi

exit 0

只做了基本的权限检查,建议把文件权限改为700.这样保证只有root可执行。

$ sudo vi /usr/local/sbin/vpno  

#!/bin/bash
if [ $UID -ne 0 ]
then
    echo "Must be root!"
    exit 1
fi

sudo sh -c 'echo "d ResNet" > /var/run/xl2tpd/l2tp-control'
sudo /etc/init.d/xl2tpd stop
sudo /etc/init.d/ipsec stop
sudo rm -rf /var/run/xl2tpd

exit 0

---------------------------------------------------------------------
5.后记
使用以上步骤与脚本可以很好地解决我的需求,就等9月ITSC正式终端pptp连接服务了。

补充:据说在每次建立连接前,有必要先flush security association table in kernel.
资料在这里
vi /etc/racoon/setup.sh
内容如下:
#!/bin/bash
/sbin/setkey -FP
/sbin/setkey -F
/sbin/setkey -c << EOF
spdadd 192.168.0.1[1701] 0.0.0.0/0[0] any
   -P out ipsec esp/transport//require;
EOF

然后chmodx +x /etc/racoon/setup.sh
在每次建立ipsec连接前运行一次。
但事实上经我实验,不需要这步也能很好地建立连接。

No comments: