haohaolee's blog

nerd以上,geek未满

使用 StrongSwan 搭建 Ipsec VPN (1) for Nokia Mobile VPN Client

背景

话说如今这年头,翻墙已经不是要不要,而是怎么翻的问题。所以网上各种免费的收费的代理VPN满天飞,活生生在天朝创造了一个新兴的市场。可是对于使用 nokia s60 的用户来讲,各种不方便啊。ssh 代理不好用,vpn 呢官方客户端只支持 ipsec,还有个商业客户端 symVPN 支持 pptp 但是太贵且不实用。经过大半个月的摸索,笔者最终使用开源软件 strongSwan 成功搭建了 Nokia S60 3rd 可以使用的VPN服务器。(理论上 v5 symbian3 应该也行,只要使用的是 Nokia Mobile VPN,Maemo 就不提了)。

网上有关搭建Nokia VPN的中文文章据我所知只有 alpha2beta 这一篇,该文采用的是 openswan,和 strongswan 其实差不太多,都实现了 ipsec 协议。强烈推荐先去那里看看,如果:

  1. 你想要快速搭建一个 Nokia 手机可用的 VPN,因为那篇文章采用的是 PSK 认证(pre-shared keys),所以相对来说准备工作和步骤要少很多,实际上会容易一些
  2. 你并不需要同时支持其它客户端,比如 iOS,Windows 等等

如果你和笔者一样需要支持手头上的众多设备,那么请继续往下看吧。在本文基础上,可以很容易添加其它的设备。不过请做好心理准备,因为 ipsec 是公认的难搞,再加上 Nokia 设备的极度不友好,所以请一定要有耐心。笔者曾经碰到到相同的配置应用到 Nokia 上,第一次行第二次不行的情况,实在是太诡异了。

不过搞定 ipsec 的一个好处是,ipsec 这样一个古老标准有着极其广泛的支持,几乎所有支持 VPN 的客户端原生支持着某种 ipsec 协议(大多数是兼容 Cisco 的 VPN 或者 L2TP over ipsec),不像 openvpn 或者 pptp 配置起来很容易,但是往往设备不支持或者需要另外安装。

本文假设

  1. 基本的 linux 使用经验,会 make,会 build,会查 log,会配 iptables,当然您也可以现在就学起来~

  2. 有一台 public ip 的linux服务器,如果是 VPS 最好是 xen 的( openvz 似乎不能安装 strongSwan ),并且服务器的public ip 是分配在某个 interface 上的,比如eth0,这意味服务器不能在NAT后面。(在NAT后面其实也是可以的,但是那会涉及到更多复杂的情况,本文不考虑,好在如今VPS不是都像EC2这样玩的)

  3. 有一个指向该 ip 的域名

步骤

  • 建立自己的 CA & 颁发证书

  • 安装&配置 StrongSwan

  • 配置手机客户端

  • 杂项

建立自己的 CA & 颁发证书

因为针对不同设备需要不同的配置,而 psk 是共享同一个密钥,所以服务器无法区分客户端。因此我们需要采用 x.509 证书认证。关于 x.509 体系的具体情况,请查阅相关资料,笔者也不是这方面的专家,不敢误人子弟。大致来说,就是通过同时颁发证书给服务器和客户端使它们互相信任并且识别对方,达到认证的目的,另外好处是比密码更安全。

颁发证书一般都采用 openssl。为了简便,尽量少的涉及到细节,这里采用 easy-rsa —— 一套脚本来完成这种任务。OpenVPN 项目就含有这一套脚本,这里以 linux 下的操作为例。Windows 的 OpenVPN 安装包也可以完成类似任务,不赘述。

将 easy-rsa 目录 copy 到你的工作目录,比如 $HOME 。easy-rsa 一般在 OpenVPN 的例子目录中,比如 /usr/share/openvpn/easy-rsa ,然后进入easy-rsa。我们需要修改两个文件:

  • openssl.cnf (如果 openssl 的版本是0.9.6,那就是修改openssl-0.9.6.cnf) 以下带有注释的行是需要增加或者修改的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
......
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=clientAuth      # add or modify this line
......
......
[ server ]

# JY ADDED -- Make a cert with nsCertType set to "server"
basicConstraints=CA:FALSE
nsCertType          = server
nsComment           = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
extendedKeyUsage=clientAuth, serverAuth, 1.3.6.1.5.5.8.2.2   # add or modify this line
subjectAltName=DNS:your.vpn.domain                           # replace with your domain
......

subjectAltName 可以指定为 ip 或者域名,域名显然更灵活一些

  • vars 修改最后几行,主要是证书的名称,机构,email等等,对应你自己的情况。例如:
1
2
3
4
5
export KEY_COUNTRY="TC"
export KEY_PROVINCE="HX"
export KEY_CITY="modu"
export KEY_ORG=""
export KEY_EMAIL="whatever@xxx.com"

另外,KEY_SIZE 可以是1024也可以是2048,2048理论上更安全一些。

然后,执行以下命令:

1
2
3
4
. ./vars
./clean-all
./build-dh
./build-ca

过程中会问你一些问题,因为上面设置过了,大多数可以直接回车。 末了,会在 keys 目录下生成 ca.crt 和 ca.key,前者是证书,后者是 key,key 是不能公开的

然后,继续:

1
./build-key-server your.vpn.domain

替换 your.vpn.domain 为你自己的域名。生成一大堆东西,我们需要的包括 your.vpn.domain.crt 和 your.vpn.domain.key,这里用域名的原因是证书中的 common name 需要指定域名,作为参数传进去省事;当然你也可以手动指定。

继续:

1
./build-key-pkcs12 client_name

过程和 server 的差不多,末了,会让你输入一个密码。这个密码是用来打包证书和 key 的。目录下会产生 client_name.crt,client_name.key 以及 client_name.p12

最后还有一步,执行:

1
openssl x509 -inform PEM -outform DER -in keys/ca.crt -out keys/ca.cer

这一步其实是 Symbian 需要的,它只能识别 der 格式,所以需要转换一下。 这样,CA 和证书就弄好了,这里我们建立了一个 root CA,一对服务器 证书/密钥, 一对客户端 证书/密钥。注意一定要保存好 keys 目录的现场,因为以后还需要颁发更多的证书。下文中我将 your.vpn.domain.crt/key 改名为 strongswan.crt/key, 客户端则假设为 E71.crt/key/p12

安装&配置 strongSwan

strongSwan 我使用的最新的 release 4.5.1,你可以使用自己的 distro 自带的版本,也可以自行 build,这里略过。唯一需要注意的是,你使用的版本最好支持 NAT traversal,虽然对于本文针对的 Nokia VPN 的情况下不一定需要,但是很多情况下客户端在 NAT 后面并且使用 ikev1 的时候是需要的(特别是以后关于 iOS 的部分)。 NAT traversal 是由一个编译选项 enable-nat-transport 决定的。这里给我 build 时使用的 config 作为参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
./configure   --prefix=/usr --sysconfdir=/etc --libexecdir=/usr/lib \
              --with-ipsecdir=/usr/lib/strongswan \
              --enable-sqlite --enable-smartcard --enable-cisco-quirks \
              --enable-openssl --enable-curl \
              --enable-sql --enable-attr-sql \
              --enable-farp --enable-dhcp \
              --enable-eap-sim --enable-eap-sim-file --enable-eap-simaka-pseudonym \
              --enable-eap-simaka-reauth --enable-eap-identity --enable-eap-md5 \
              --enable-eap-gtc --enable-eap-aka --enable-eap-aka-3gpp2 \
              --enable-eap-mschapv2 --enable-eap-radius \
              --enable-ha \
              --enable-nat-transport \
              --disable-mysql --disable-ldap \
              --disable-static --enable-shared

安装好以后,可以看看是否存在 ipsec 命令,以及是否存在 /etc/ipsec.d/ 目录

  • 安装证书 这里我们需要的证书和密钥包括 ca.crt,strongswan.crt,strongswan.key。 将 ca.crt copy 到 /etc/ipsec.d/cacerts/ ,strongswan.crt copy 到 /etc/ipsec.d/certs/ ,strongswan.key copy 到 /etc/ipsec.d/private/

  • 配置 /etc/ipsec.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# ipsec.conf - strongSwan IPsec configuration file

config setup
    strictcrlpolicy=no
    charonstart=yes
    uniqueids=yes

conn %default
    authby=rsasig
    leftrsasigkey=%cert
    rightrsasigkey=%cert
    left=%defaultroute

conn ikev2
    keyexchange=ikev2
    leftsubnet=0.0.0.0/0
    leftcert=strongswan.crt
    rightca=%same
    dpddelay=90
    dpdtimeout=90
    dpdaction=clear
    right=%any
    rightsourceip=192.168.66.240/29
    auto=add

这里 192 打头的地址段是分配给客户端的虚拟 ip,你可以任意配置,我这里掩码用了29 bit,所以同时支持的客户端只有8个

/etc/strongswan.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# strongswan.conf - strongSwan configuration file

charon {
    # number of worker threads in charon
    threads = 16

    # send strongswan vendor ID?
    # send_vendor_id = yes

    dns1 = 8.8.8.8

    filelog {
            /var/log/charon.log {
                # loggers to files also accept the append option to open files in
                # append mode at startup (default is yes)
                # the default loglevel for all daemon subsystems (defaults to 1).
                default = 1
            }
            stderr {
                # more detailed loglevel for a specific subsystem, overriding the
                # default loglevel.
                ike = 2
                knl = 3
            }
    }

    plugins {

            sql {
              # loglevel to log into sql database
              loglevel = -1

              # URI to the database
              # database = sqlite:///path/to/file.db
              # database = mysql://user:password@localhost/database
          }
    }

}

pluto {

}

libstrongswan {

    #  set to no, the DH exponent size is optimized
    #  dh_exponent_ansi_x9_42 = no

}

dns1 是 push 到客户端的 dns,这里用的 google anycast dns,另外 filelog 是一些 log 选项

/etc/ipsec.secrets

1
: RSA /etc/ipsec.d/private/strongswan.key

这里指定的是服务器使用的密钥,冒号之前可以用具体的 ip 来限制客户端,这里表示任意客户端。

  • 防火墙 ipsec 需要打开 udp 500,udp 4500,ESP (协议号50),AH (协议号51). 你还需要将服务器配置为一个路由器(如果不是的话),这意味你需要打开 ip 转发,并且要为你的虚拟 ip 段做 SNAT (除非你玩的是ipv6)。这部分内容请参考其他资料,一般不同的发行版都有专门文档阐述。

你可以尝试启动 ipsec 服务,如果没有错误信息的话,服务器就配置好了。log 信息是在 /var/log 下面 auth.log 以及 charon.log

配置手机客户端

Nokia Mobile VPN Client,E系列我记得是自带的,其他手机可能要手动下载安装。另外,这里讨论的客户端版本>=3.1,因为3.1之后的客户端支持用一个后缀为 vpn 的 zip 包作为 vpn 策略文件,很方便。之前的版本需要创建 sis 文件,搞不好还要签名。所以这里只考虑3.1以后的。据我所知大都能升级到至少3.1。

目前网上的文章都是基于手工制作 vpn 策略文件,很容易出错。所幸我找到一个官方的程序可以自动生成策略文件,减少了出错的可能。

下载地址 需要 .Net Framwork 2.0

现在切换到 Windows 平台下面。准备以下文件 ca.cer (不是ca.crt),E71.p12,都是建立 CA 时生成的。过程都用截图算了,很简单。在 vista 和 win7 下需要管理员权限来执行。

注意正确替换你的域名或ip

将 cert store 改为 DEVICE,这样不用每次启动 VPN 都要输入密码

然后执行 generate VPN policy,就OK了。至于如何安装及其设置接入点,网上已有很多资料,不再赘述。比如这里这里

设置好接入点之后就可以测试了。 如果连接失败了,一方面需要看手机上的日志(虽然信息量有限),另一方面需要看服务器上日志,特别是 charon.log,这是 ikev2 的日志。 如果能连上,但是不能上网,那8成是服务器没有做好 ip 转发或者 SNAT 的问题,还有可能是 DNS 的问题

杂项

最后说一下相关细节,没兴趣可以不看。网上其它有关使用 openswan 或者 strongSwan 配置 ipsec 的文章大都使用的 ikev1 协议,但是 Nokia 的客户端恰好支持更先进的 ikev2 协议(不能不赞一下~),具有更好的连接稳定性,更好的 NAT 穿透性。之前我配置 Nokia VPN 和 openswan 使用 ikev1 也成功了,但是因为该死的 E71 的 bug (也许吧,看这里)要给 openswan 打补丁才行,整个折腾过程更悲催。经 @tjmao 提醒才想起对 ikev2 支持更好的 strongSwan,才有了本文。

另外,如果你通过本文,成功建立了 VPN 服务器。那么一个 bonus 就是,你同时支持了 windows 7 的 ikev2 客户端,只要给 win7 也颁发安装证书,然后可以了。而且从此远离恶心的 L2TP over ipsec。你可以看这里 以及 这里

最后的最后,本文一部分是边实验边写的,还有一部分是凭记忆写的,所以如果有什么问题,欢迎在下面提出来,看看有什么错误或者漏掉的。

Good luck~

Posted via UltraBlog.vim.

Comments