strongswan配置win7、安卓、iOS全平台ikev2 VPN

本篇文章涉及针对各平台的strongswan配置,不包含编译、安装、证书生成等环节。

安装和证书配置请参考:linux上用strongswan搭建ikev2协议vpn

各平台均测试ok,记录于此。

windows7

EAP-MSCHAPv2

服务器配置

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
conn windows7
keyexchange=ikev2
ike=aes256-sha1-modp1024! # windows7的ikev2指定了DH group必须是modp1024
leftid=@tyr.so # 服务器证书中指定的域名或者IP地址
rekey=no
left=%defaultroute # 通告默认路由,作为网关
leftauth=pubkey
leftsubnet=0.0.0.0/0
leftcert=serverCert.pem
right=%any
rightauth=eap-mschapv2
rightsourceip=10.8.0.0/16 # 分配给客户端ip的子网范围
rightsendcert=never
eap_identity=%any
auto=add

ipsec.secrets

配置如下:

1
2
: RSA serverKey.pem #指定服务器密钥
ThisIsYourUserName : EAP "ThisIsYourPasswd"

客户端配置

使用win7自带客户端(Agile):

导入证书:

  • 开始菜单搜索“cmd”,打开后输入 mmc(Microsoft 管理控制台);
  • “文件”-“添加/删除管理单元”,添加“证书”单元;
  • 证书单元的弹出窗口中一定要选“计算机账户”,之后选“本地计算机”,确定;
  • 在左边的“控制台根节点”下选择“证书”-“个人”,然后选右边的“更多操作”-“所有任务”-“导入”打开证书导入窗口;
  • 选择刚才生成的 clientCert.p12 文件。下一步输入私钥密码。下一步“证书存储”选“个人”;
  • 导入成功后,把导入的 CA 证书剪切到“受信任的根证书颁发机构”的证书文件夹里面;
  • 打开剩下的那个私人证书,看一下有没有显示“您有一个与该证书对应的私钥”,以及“证书路径”下面是不是显示“该证书没有问题”;
  • 然后关闭 mmc,提示“将控制台设置存入控制台1吗”,选“否”即可;
  • 至此,证书导入完成。

千万不要双击 .p12 证书导入!因为那样会导入到当前用户而不是本机计算机中,ipsec是访问不了它的。
否则会出现错误 13801:IKE身份验证凭证不可接受

建立连接:

  • “控制面板”-“网络和共享中心”-“设置新的连接或网络”-“连接到工作区”-“使用我的 Internet 连接”;
  • Internet 地址写服务器地址或域名;
  • 描述随便写;
  • 用户名密码写之前配置的 EAP 的那个;
  • 确定;
  • 点击右下角网络图标,在新建的 VPN 连接上右键属性然后切换到“安全”选项卡;
  • VPN 类型选 IKEv2;
  • 数据加密是“需要加密”;
  • 身份认证这里需要说一下,如果想要使用 EAP-MSCHAPV2 的话就选择“使用可扩展的身份认证协议”-“Microsoft 安全密码(EAP-MSCHAP v2)”,想要使用私人证书认证的话就选择“使用计算机证书”。

iOS

PSK

服务器配置

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
conn %default
left=%defaultroute
ikelifetime=60m
keylife=20m
rekeymargin=3m
keyingtries=1
keyexchange=ikev2
authby=secret
conn iOS_psk
leftsubnet=0.0.0.0/0
# end ref
leftfirewall=yes
right=%any
rightsourceip=10.8.0.0/16
auto=add

ipsec.secrets

配置如下:

1
: PSK "123123123123"

客户端配置

为了方便iOS设备配置,我们可以使用AppleConfiguration生成一个xml格式的.mobileconfig文件,用于自动配置,脚本如下

你可能需要更改CONN_SHARED_SECRET中的ipsec.secrets文件路径

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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/bin/bash
# TODO: add regenerate shared secret option
# In normal cases, you will only need to pass the HOST of your server.
#[ "no${HOST}" = "no" ] && echo "\$HOST environment variable required." && exit 1
HOST="tyr.so"
: ${PROFILE_NAME="Tyrchen VPN Profile"}
: ${PROFILE_IDENTIFIER=$(echo -n "${HOST}." | tac -s. | sed 's/\.$//g')}
: ${PROFILE_UUID=$(hostname)}
# These variable, especially CONN_UUID, are bind to per username,
# which currently, all users share the same secrets and configurations.
: ${CONN_NAME="Tyrchen IKEv2 VPN"}
: ${CONN_IDENTIFIER="${PROFILE_IDENTIFIER}.shared-configuration"}
: ${CONN_UUID=$(uuidgen)}
: ${CONN_HOST=${HOST}}
: ${CONN_REMOTE_IDENTIFIER=${HOST}}
CONN_SHARED_SECRET=$(grep "PSK" /usr/local/etc/ipsec.secrets | sed 's/.*"\(.*\)"/\1/g')
cat <<EOF
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Read more: https://wiki.strongswan.org/projects/strongswan/wiki/AppleIKEv2Profile -->
<plist version="1.0">
<dict>
<!-- Set the name to whatever you like, it is used in the profile list on the device -->
<key>PayloadDisplayName</key>
<string>${PROFILE_NAME}</string>
<!-- This is a reverse-DNS style unique identifier used to detect duplicate profiles -->
<key>PayloadIdentifier</key>
<string>${PROFILE_IDENTIFIER}</string>
<!-- A globally unique identifier, use uuidgen on Linux/Mac OS X to generate it -->
<key>PayloadUUID</key>
<string>${PROFILE_UUID}</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<array>
<!-- It is possible to add multiple VPN payloads with different identifiers/UUIDs and names -->
<dict>
<!-- This is an extension of the identifier given above -->
<key>PayloadIdentifier</key>
<string>${CONN_IDENTIFIER}</string>
<!-- A globally unique identifier for this payload -->
<key>PayloadUUID</key>
<string>${CONN_UUID}</string>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
<!-- This is the name of the VPN connection as seen in the VPN application later -->
<key>UserDefinedName</key>
<string>${CONN_NAME}</string>
<key>VPNType</key>
<string>IKEv2</string>
<key>IKEv2</key>
<dict>
<!-- Hostname or IP address of the VPN server -->
<key>RemoteAddress</key>
<string>${CONN_HOST}</string>
<!-- Remote identity, can be a FQDN, a userFQDN, an IP or (theoretically) a certificate's subject DN. Can't be empty.
IMPORTANT: DNs are currently not handled correctly, they are always sent as identities of type FQDN -->
<key>RemoteIdentifier</key>
<string>${CONN_REMOTE_IDENTIFIER}</string>
<!-- Local IKE identity, same restrictions as above. If it is empty the client's IP address will be used -->
<key>LocalIdentifier</key>
<string></string>
<!--
OnDemand references:
http://www.v2ex.com/t/137653
https://developer.apple.com/library/mac/featuredarticles/iPhoneConfigurationProfileRef/Introduction/Introduction.html
Continue reading:
https://github.com/iphoting/ovpnmcgen.rb
-->
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
<!-- The server is authenticated using a certificate -->
<key>AuthenticationMethod</key>
<string>SharedSecret</string>
<key>SharedSecret</key>
<string>${CONN_SHARED_SECRET}</string>
<!-- The client uses EAP to authenticate -->
<key>ExtendedAuthEnabled</key>
<integer>0</integer>
</dict>
</dict>
</array>
</dict>
</plist>
EOF

将该脚本保存为generate-mobileconfig.sh,运行./generate-mobileconfig.sh > my.mobileconfig

将生成的my.mobileconfig通过邮件、或者网络发送到iOS设备,安装描述文件,就可以自动配置好vpn。

PSK+xauth

Apple声明使用的 IPsec 客户端为 Cisco,实际为自己修改的 racoon。它只支持 ike 协议的第一版即 ikev1,可以使用证书或纯密码(PSK)认证,但必须辅之 xauth 用户名/密码认证。

服务器配置

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
conn iOS_xauth_psk
keyexchange=ikev1
aggressive=yes
left=%defaultroute
leftid=@tyr.so
leftauth=psk
leftsubnet=0.0.0.0/0
right=%any
rightauth=psk
rightauth2=xauth
rightsourceip=10.8.0.0/16
auto=add

ipsec.secrets

配置如下:

1
2
user : XAUTH "password"
: PSK "123123123123"

客户端配置

通用-VPN-新建IPSec VPN

  • 服务器:ip地址或者域名
  • 账户和密码填写上述中的XAUTH前后两个
  • 密钥输入上述PSK
  • 群组名称随便填

RSA

服务器配置

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
conn iOS_cert
keyexchange=ikev1
fragmentation=yes
left=%defaultroute
leftauth=pubkey
leftsubnet=0.0.0.0/0
leftcert=serverCert.pem
right=%any
rightauth=pubkey
rightauth2=xauth
rightsourceip=10.8.0.0/16
rightcert=clientCert.pem
auto=add

ipsec.secrets

配置如下:

1
2
: RSA serverKey.pem
userRSA : EAP "password"

客户端配置

把CA 证书和之前做好的 pkcs12(clientCert.p12)发邮件给自己。在 iOS 上收邮件,导入两者。通用-VPN-新建IPSec VPN

  • 服务器:ip地址或者域名
  • 账户和密码填写上述中的EAP前后两个
  • 使用证书
  • 证书选择客户端证书

Android

PSK

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
conn android_xauth_psk
keyexchange=ikev1
aggressive=yes
left=%defaultroute
leftid=@tyr.so
leftauth=psk
leftsubnet=0.0.0.0/0
right=%any
rightauth=psk
rightauth2=xauth
rightsourceip=10.8.0.0/16
auto=add

ipsec.secrets

配置如下:

1
: PSK "123123123123"

RSA

ipsec.conf

建立如下连接配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
conn android_rsa
left=%defaultroute
leftsubnet=0.0.0.0/0
leftcert=serverCert.pem
leftauth=pubkey
leftid=@tyr.so
right=%any
rightsourceip=10.8.0.0/16
rightauth=pubkey
rightcert=clientCert.pem
rightsendcert=never
keyexchange=ikev2
eap_identity=%any
auto=add

ipsec.secrets

配置如下:

1
: RSA serverKey.pem

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
#/etc/strongswan.conf - strongSwan configuration file
#
#strongswan.conf - strongSwan configuration file
#
#Refer to the strongswan.conf(5) manpage for details
#
#Configuration changes should be made in the included files
charon {
load_modular = yes
i_dont_care_about_security_and_use_aggressive_mode_psk = yes
duplicheck.enable = no
plugins {
include strongswan.d/charon/*.conf
# https://wiki.strongswan.org/projects/strongswan/wiki/Attrplugin
attr {
dns = 8.8.8.8, 8.8.4.4
}
}
}
include strongswan.d/*.conf

日志记录

1
2
3
4
5
6
7
8
9
10
11
12
13
cat >/usr/local/etc/strongswan.d/charon-logging.conf <<EOF
charon {
filelog {
/var/log/strongswan.log {
append = yes
default = 1
flush_line = yes
ike_name = yes
time_format = %b %e %T
}
}
}
EOF

更多配置可以修改/usr/local/etc/strongswan.d/charon.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
#!/bin/bash
FILE="/usr/local/etc/ipsec.secrets"
case $1 in
"start" )
iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -A POSTROUTING -s 10.8.0.0/16 -o eth0 -j MASQUERADE
# SHARED_SECRET="123$(openssl rand -base64 32 2>/dev/null)"
# if ! grep -q "PSK" $FILE;then
# sed -i '/PSK/d' $FILE
# echo ": PSK \"${SHARED_SECRET}\"" >> $FILE
# fi
ipsec start && echo "ipsec start ok." || echo "start fail."
;;
"stop" )
iptables -t nat -D POSTROUTING -s 10.8.0.0/16 -o eth0 -m policy --dir out --pol ipsec -j ACCEPT
iptables -t nat -D POSTROUTING -s 10.8.0.0/16 -o eth0 -j MASQUERADE
ipsec stop && echo "ipsec stop ok." || echo "stop fail."
;;
"reload" )
ipsec reload && echo "ipsec reload ok." || echo "reload fail."
;;
"restart" )
$0 stop && $0 start
;;
* )
echo "Args error"
exit 1
;;
esac

再alias一下alias vpn='/etc/init.d/vpn-ike2.sh'

这样我们可以使用如下命令来控制

  • vpn stop
  • vpn start
  • vpn reload
  • vpn restart

更多内容请参考 SDB:Setup Ipsec VPN with Strongswan

如果您觉得这篇文章对您有帮助,不妨支持我一下!