Total Pageviews

Thursday 30 July 2015

Setup Ipsec VPN with Strongswan

(详见https://briteming.blogspot.com/2016/03/ipsecikev2-vpn.html

本教学介绍了如何使用 Strongswan 5.0.x 在 openSUSE 12.3+ 服务器上架设支持 ikev1/ikev2 的 Ipsec VPN。适用于 openSUSE、iOS、Android、Windows 和其它 Linux。


注意 Strongswan 5 即现在的主力支持版本和 Strongswan 4 的 ipsec.conf 有很大的不同(作废了很多选项),请保证您的版本为 5.0.4+ 本教学才有参考价值。因此请不要往 Debian 这些软件包版本旧的系统上套,同样 openSUSE 用户也不要拿 Debian 的来套。
注意 本文的例子仅以最常见的 VPS/客户机模式为例,假设客户机使用图形客户端,因此并不涉及客户端文本配置的内容。其中的原理和服务器端配置可用于其它用途比如服务器到服务器(Site to Site)的连接,但这种连接的客户端文本配置部分需要领会原理自己写。
注意 本文只适用于有 VPS 的爱好者使用,并不提供已建立好的 demo 供测试,但保证文中出现的配置如无意外如上游改选项,实际中都是能够使用的。因此并不可用于“免费 VPN”这样的话题,如何优惠购买 VPS 请到我们的论坛 forum.suse.org.cn。本文也不讨论如何进行后台计费,但提供了计费软件的名称供 VPN 服务商参考,因此只适用于小团体的共用。如果小群体产生流量纠纷而需区分账户,那解散才是治本的方法,其它都只能治标。

目录

 [隐藏

[编辑] 什么是 IPsec?

IPsec 是 虚拟私密网络(VPN) 的一种,用于在服务器和客户端之间建立加密隧道并传输敏感数据之用。它由两个阶段组成,第一阶段(Phrase 1, ph1),交换金钥建立连接,使用互联网金钥交换(ike)协议; 第二阶段(Phrase 2, ph2),连接建立后对数据进行加密传输,使用封装安全载荷(esp)协议。参考:维基百科 IPsec 词条
其中,第一阶段和第二阶段可以使用不同的加密方法(cipher suites)。甚至,第一阶段 ike 协议的第一版(ikev1)有两种模式,主力模式(main mode)和积极模式(aggressive mode),主力模式进行六次加密握手,而积极模式并不加密,以实现快速建立连接的目的。
第一阶段的 ike 协议有两个版本(ikev1/ikev2),不同的开源/闭源软件实现的版本均不同,不同的设备实现的版本也不同。再联系到第一阶段/第二阶段使用的各种 不同加密方法,使得 IPsec 的配置有点黑魔法的性质,要么完全懂,通吃; 要么完全不懂,照抄。

[编辑] 设备/操作系统规格

这里主要介绍了设备/操作系统使用的 ike 版本及其特殊要求。

[编辑] Linux

命令行客户端就是 strongswan 本身,因此完美兼容,支持 ikev1/ikev2 和所有加密方法的连接。因此如果用户只使用 Linux 命令行客户端,不使用各种移动设备也不使用 Windows,那么完全没有那么多事。
但 Linux 的图形界面客户端 NetworkManager-strongswan 目前只支持 ikev2 连接,必须使用证书或 EAP (各种加密方法都支持,包括微软的 MSCHAPv2)进行认证,不支持纯密码(PSK)认证。这并不是 strongswan 的错误,或者技术不行(开源总是走在技术最前沿的,毕竟命令行是支持的),而仅仅是体现一种选择:ikev1 被 strongswan 项目认为是该淘汰的协议,而 PSK 加密被认为是非常不安全的。参考 strongswan 维基 NetworkManager 词条

[编辑] Android

Android 和 Linux 不一样,只支持 ikev1。其它方面和 Linux 一样,甚至有好多种 IPsec VPN 配置模式可供选择。

[编辑] iOS/Mac OS X

它们声明使用的 IPsec 客户端为 Cisco,实际为自己修改的 racoon。它只支持 ike 协议的第一版即 ikev1,可以使用证书或纯密码(PSK)认证,但必须辅之 xauth 用户名/密码认证。
该修改版的 racoon 会优先使用不加密的积极模式,而积极模式是 strongSwan 所不支持的。所以要使用主力模式。
iOS 6 还有一个“衔尾”故障:它在第一阶段握手时会把数据包拆分成小块(fragmentation),然后“加密”发送。然而这种加密仅仅是声明的,其实并未 加密,这就导致 strongSwan 及其它标准服务器端/Cisco 设备无法解密。另外 ikev1 的 fragmentation 插件是闭源的。开源服务器端无法对这些小块进行重组。参考:Cisco VPN stop working after upgrading to IOS 6
所以产生了一种权宜之计,就是使用小证书(小于 1024,默认一般为 2048),来达到不拆包的目的。但是 Mac OS X 10.7 的更新却对这种方式进行了封杀,学习微软加入了证书验证,小证书直接拒绝。
所幸 strongswan 5.0.2 已经完成了 fragmentation 的开源实现和对 iOS 那个声明加密其实未加密故障的处理:IKE message fragmentation (cisco) + IOS 6.0 Hack for encrypted flaged ike fragmentation packets,该链接中也能找到 strongswan 4 的补丁。

[编辑] Windows

微软的差劲只比 iOS 好一点。好处在于它支持了 ikev2,但是只在 Windows 7 以后支持,Vista 之前依然使用 ikev1。
坏处在于它的 ikev2 支持非常诡异,指定了 Diffie Hellman group(DH,迪菲-赫尔曼密钥交换组)必须是 modp1024。这是非常少见理论上不应该由系统管理员操心的加密选项:
在 strongswan 中,定义第一阶段(ike)和第二阶段(esp)加密方法的语法是:
 ike/esp=encryption-integrity[-dhgroup][-esnmode]
 第一阶段/第二阶段=加密方法-健壮性认证方法 (后面两项可选)[-DH 组] [-扩展序列号支持模式(RFC4304)]
参考:IKEv2CipherSuites
Windows 定义了一个可选的选项,导致了我们必须去定义整个第一阶段的加密方法。这样被破解的可能性就提高了。
其次在于它的 rekey(重连)。IPsec 的认证是有时效的,超过时间会重新认证。这种 CHILD_SA 认证可由服务器发出,也可由客户端发出,一般是由服务器发出。但是 Windows 7 的 ikev2 的表现是,如果你在路由器(NAT)后,收到这种请求会把微软内部的通知代码发出去,代码为 12345, 经过 strongswan 项目侦错后发现这个代码的意思是 ERROR_IPSEC_IKE_INVALID_SITUATION。但是处理不了,它不是 IPsec 标准协议定义过的错误。
于是有两种权宜之计:
一种是让 Windows 7 来主动 rekey。Windows 7 rekey 的时间大约是 58 分 46 秒,所以要配置服务器 rekey 时间比它长。但是效果非常不好。因为 rekey 是由三个变量控制的,key 的生命周期,key 的边际时间(生命周期前多久进行 rekey),和边际时间误差(rekeyfuzz),误差是不可控的。参考:ExpiryRekey
即使能控制 strongswan 这边,Windows 依然是“大约”; 即使两边都能控制,假设服务器延后一秒 rekey,理论上如果连接持续时间足够长,依然能够撞车:58x60+46 次 rekey 后即 146 天后撞车,连一年都没有,在 Linux 服务器对 Windows 服务器这种使用实例中就明显不符合要求。
所以目前只能使用后一种方法即完全禁用服务器端 rekey。
最后,它的 EAP 认证也非常糟糕。MSCHAPv2 的 eap 身份不是 ikev2 身份(ikev2 身份一般是 EAP 用户名),所以必须在服务器端显式定义 eap_identity 来使用 Windows 7 的 eap 身份。

[编辑] 安装 Srongswan

sudo zypper ar -f http://download.opensuse.org/repositories/network:/vpn/openSUSE_12.3/ network:vpn
sudo zypper ref
sudo zypper in --no-recommends strongswan-ipsec
这里 --no-recommends 是不带推荐软件包,因为推荐的软件包都是针对桌面环境的,服务器用不到。
如果你的版本是 openSUSE 12.1/12.2,请相应替换源地址。


[编辑] 生成证书(可选)

注意 如果不生成证书,后面配置部分的配置中用 pubkey 认证的 conn 都不能用,甚至不能保留在配置中。
每一个完整的 ssl 证书都有一个公钥和一个私钥,它们可以在一起也可以分开放(当然如果你要在网络上传输,肯定只能用公钥)。公钥是在网络上传输的,而私钥是藏好用来和接收到的公钥配对的(因此私钥里也有整个公钥,用来配对)。

[编辑] 生成 CA 证书

生成一个私钥:
ipsec pki --gen --outform pem > ca.pem
没什么好解释的,--outform 一共有三个格式可选,但是另外两个是 der 和 pgp...
基于这个私钥自己签一个 CA 证书:
ipsec pki --self --in ca.pem --dn "C=CN, O=strongSwan, CN=strongSwan CA" --ca --outform pem > ca.cert.pem
这里 --self 表示自签证书,--in 是输入的私钥,--dn 是判别名,--ca 表示生成 CA,其它同上。这里需要解释下判别名:
  • C 表示国家名,同样还有 ST 州/省名,L 地区名,STREET(全大写) 街道名。
  • O 表示组织名。
  • CN 为通用名。
具体见微软的文档:Distinguished Names

[编辑] 生成服务器证书

同样生成私钥:
ipsec pki --gen --outform pem > server.pem
用我们刚才自签的 CA 证书给自己发一个服务器证书:
 ipsec pki --pub --in server.pem | ipsec pki --issue --cacert ca.cert.pem \
--cakey ca.pem --dn "C=CN, O=strongSwan, CN=forum.suse.org.cn" \
--san="forum.suse.org.cn" --flag serverAuth --flag ikeIntermediate \
--outform pem > server.cert.pem
这条命令的意思解释下:
ipsec pki --pub --in server.pem 
是从我们刚生成的私钥里把公钥提取出来,然后用公钥去参与后面的服务器证书签发(这个是 VPN 连接时候要用的,你不想把私钥也给它吧?那样跟没签证书一样...)。
--issue, --cacert 和 --cakey 就是表明要用刚才自签的 CA 证书来签这个服务器证书。
--dn, --san,--flag 是一些客户端方面的特殊要求:
  • iOS 客户端要求 CN 也就是通用名必须是你的服务器的 URL 或 IP 地址;
  • Windows 7 不但要求了上面,还要求必须显式说明这个服务器证书的用途(用于与服务器进行认证),--flag serverAuth;
  • 非 iOS 的 Mac OS X 要求了“IP 安全网络密钥互换居间(IP Security IKE Intermediate)”这种增强型密钥用法(EKU),--flag ikdeIntermediate;
  • Android 和 iOS 都要求服务器别名(serverAltName)就是服务器的 URL 或 IP 地址,--san。

[编辑] 生成客户端证书

依然是生成私钥:
ipsec pki --gen --outform pem > client.pem
然后用刚才自签的 CA 证书来签客户端证书:
 ipsec pki --pub --in client.pem | ipsec pki --issue --cacert caCert.pem \
--cakey caKey.pem --dn "C=CN, O=strongSwan, CN=client" \
--outform pem > client.cert.pem
这时命令行会提示你输入两遍密码,这个就是你的客户端证书密码
看懂了服务器的,客户端的也就不难理解了。除了没有那一堆特殊要求别的都一样。
客户端证书可以每个客户端签一个,也可以让它们公用一个。是否多签看用途,一般用于区分设备(计费是不用这样的,是用账户来区分的)。

[编辑] 生成 pkcs12 证书(可选)

你可能还想生成一个可以直接导入的 pkcs12 证书(用于手机,诺基亚没这东西还不行):
 openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "client" \
-certfile ca.cert.pem -caname "strongSwan CA" -out client.cert.p12

[编辑] 安装证书

cp -r ca.cert.pem /etc/ipsec.d/cacerts/
cp -r server.cert.pem /etc/ipsec.d/certs/
cp -r server.pem /etc/ipsec.d/private/
cp -r client.cert.pem /etc/ipsec.d/certs/
cp -r client.pem /etc/ipsec.d/private/
CA 证书、客户证书(两个)和 .p12 证书用 FTP 复制出来给客户端用。有几种 Android 配置还需要服务器证书(server.cert.pem)。

[编辑] 配置 Strongswan

[编辑] ipsec.conf

config setup
    uniqueids=never 

conn iOS_cert
    keyexchange=ikev1
    # strongswan version >= 5.0.2, compatible with iOS 6.0,6.0.1
    fragmentation=yes
    left=%defaultroute
    leftauth=pubkey
    leftsubnet=0.0.0.0/0
    leftcert=server.cert.pem
    right=%any
    rightauth=pubkey
    rightauth2=xauth
    rightsourceip=10.0.0.0/24
    rightcert=client.cert.pem
    auto=add

# also supports iOS PSK and Shrew on Windows
conn android_xauth_psk
    keyexchange=ikev1
    left=%defaultroute
    leftauth=psk
    leftsubnet=0.0.0.0/0
    right=%any
    rightauth=psk
    rightauth2=xauth
    rightsourceip=10.0.0.0/24
    auto=add

# compatible with "strongSwan VPN Client" for Android 4.0+
# and Windows 7 cert mode.
conn networkmanager-strongswan
    keyexchange=ikev2
    left=%defaultroute
    leftauth=pubkey
    leftsubnet=0.0.0.0/0
    leftcert=server.cert.pem
    right=%any
    rightauth=pubkey
    rightsourceip=10.0.0.0/24
    rightcert=client.cert.pem
    auto=add

conn windows7
    keyexchange=ikev2
    ike=aes256-sha1-modp1024! 
    rekey=no
    left=%defaultroute
    leftauth=pubkey
    leftsubnet=0.0.0.0/0
    leftcert=server.cert.pem
    right=%any
    rightauth=eap-mschapv2
    rightsourceip=10.0.0.0/24
    rightsendcert=never
    eap_identity=%any
    auto=add

其中 config setup 只能出现一次,而 conn <连接名称> 可以有很多个。这里的名称不是预定义的,可以随意写,只要你能识别就行,主要用来定义一种连接,就是为了让你在日志里好找。
新版 strongswan 里 config setup 的内容不如旧版的多,许多旧版必须有的选项都被作废了。比如:
  • plutostart 新版所有的 ike 协议都由原来 ikev2 的 daemon:charon 接管。根本就没有 pluto 了。
  • nat_traversal 新版所有的 ike 协议都是可以穿越路由器(NAT)的。
  • virtual_private 定义服务器的局域网 IP 地址。现在被魔术字 0.0.0.0/0 取代了。
  • pfs 完美向前保密,用于 rekey 时。意思是你现在的金钥互换过程如果被攻破了,会不会对已经互换过的金钥产生影响。以前一般设置成 no 来适用于 iOS 这种客户端会以积极模式发出非加密的 rekey 请求的情况。现在这个选项完全没作用了。第一阶段永远是完美向前保密的,第二阶段(esp)如果指定了 DH 组那么也是完美向前保密的,但是默认加密方法就已经指定了 DH 组。所以该选项永远为 yes。
而另外旧版和新版都有的选项也都定义了默认值,比如:
  • strictpolicy 是否一定需要证书吊销列表(CRL)的 URL。默认就是 no。
  • charonstart 是否启动 ikev2 的 daemon。这是旧版加入的,因为那个时候的主力是 pluto。现在默认就是 yes,你改成 no 那你连原先 pluto 的连接都无法连接,因为 ike 协议的实现全被 charon 接管了。
所以 config setup 基本上占位就行了。这里我们修改了 uniqueids 的值来实现多设备同时在线。
而 conn 最主要要理解左右的概念。其实左右是可以不分的,它们只是用来表示一个连接的两端。只是在如果你定义的不够全面时,左侧会默认被认为是本机(你的 VPS),右侧默认为他机(你的笔记本),即以左为尊。
  • left/right 是左右 id。它们用来识别服务器/客户端,可以是证书的判别名(DN),比如 "C=CN, O=strongSwan, CN=strongSwan CA",也可以是 IP 地址,也可以是 EAP 的用户名,还可以是魔术字 %any,表示什么都行。只是在 5.0.0 之前,为本机这边定义 %any 的话,ikev1 连接即 keyexchange=ikev1 的连接是识别不了,所以要改成 %defaultroute 表示自己从 ifconfig 里取 IP。为了和 right 的 %any 区分开,我们使用这种方法。所以说到最后这两个选项似乎没有什么用。但它们是必须的。
  • leftauth/rightauth 这是最重要的改动。新版主要是作废了之前的 authby 和 xauth=server/client 选项而都改用这种方法。因此使得 ikev1 也能够出现混血认证(左右两边认证的方法不同)了。参数主要有 pubkey 表示用证书,psk 表示用密码,eap 表示用扩展验证协议。
  • leftauth2/rightauth2 是为了应对旧版很常见的 authby=xauthpsk/xauthrsasig 的。现在 xauth 只能写在这里。而 psk 对应 leftauth/rightauth 里的 PSK 方法,rsasig 则对应 pubkey 方法。
  • leftsubnet 最重要的,引入了魔术字 0.0.0.0/0。如果你在右侧为客户端分配虚拟 IP 地址的话,那表示你之后要做 iptables 转发,那么左边就必须是用魔术字。
  • leftcert/rightcert 就是指定证书名字。
  • rightsourceip 为客户端分配的虚拟 IP 段。
  • auto 定义 strongswan 启动时该连接的行为。start 是启动; route 是添加路由表,有数据通过就启动; add 是添加连接类型但不启动; ignore 是当它不存在。默认是 ignore。看起来似乎是 route 比较好,但问题是我们服务器端不能预分配虚拟 IP,所以服务器端一般用的都是 add。而客户端文本配置可以选择 start。
另外说下旧版的 xauth=server/client 的问题。它表示在服务器端还是在客户端执行 xauth 认证。而在新版中主要通过左右方向来体现。比如你在服务器端执行认证,那认证请求是由客户端发出的,所以要写 rightauth2=xauth。如果在客户端执行认证,那认证请求是服务器发出的,所以要写 leftauth2=xauth。
另外网上很常见的一个配置选项是 leftfirewall=yes。这是完全错误的。看上去它的唯一作用是定义你的服务器是不是在防火墙后面,但实际上它是作为 ipsec_updown 脚本的参数被开发出来,是表明你的本机 subnet 是不是用 iptables 转发/伪装出来的。如果是的话,就调用 left/rightupdown 定义的路径下的脚本,脚本的作用是对通过 ipsec 连接的数据包进行 iptables 豁免。
之所以说它是错到离谱的(虽然没有产生影响),因为这些人完全就不懂,有公网 IP 的服务器的 subnet 很少是伪装的。另外必须写了脚本该选项才有意义,没看过一个定义了这个选项的人写过脚本。还有,leftsubnet=0.0.0.0/0 通过魔术字把 subnet 定义为了 any,你根本没法写脚本啊。所以我们这里完全就不用。
至于某类型连接,主要是根据设备规格定义的,一些特殊选项的解释如下:
  • fragmentation=yes 开启对 iOS 拆包的重组支持。
  • ike=aes256-sha1-modp1024! Windows 指定的第一阶段加密方法。
  • rekey=no 服务器对 Windows 发出 rekey 请求会断开连接。
  • rightsendcert=never 因为这是一个混血连接。服务器对自己的身份进行认证时使用的是证书,而服务器对客户端的认证使用的只是 eap-mschapv2。如果不设置的话默认是 ifasked,意思是如果服务器向客户端请求证书,客户端就会给它,但客户端给不出,连接就会断。这里设置为客户端永远不给,实际上的意思其实是服务器 不要向客户端请求证书。
  • eap_identity=%any 使用 Windows 的 eap 身份。不然会出现”no eap key found for host <rightid>“错误。

[编辑] ipsec.secrets

#
# ipsec.secrets
#
# This file holds the RSA private keys or the PSK preshared secrets for
# the IKE/IPsec authentication. See the ipsec.secrets(5) manual page.
#
: RSA server.pem
: PSK "PSK password"
marguerite : XAUTH "user password"
marguerite : EAP "user password"
看上去比较好理解,实际不是。
有些人可能会误以为:
: PSK "PSK password"
marguerite : XAUTH "user password"
是成对的,用于比如 android-xauth-psk 这样的连接,于是到了 iOS 的时候又写了一对:
: RSA server.pem
marguerite : XAUTH "user password"
来支持 iOS 的 RSA + XAUTH 认证。
这样做是没有必要的,上面定义的是种认证方法。它们之间是遵循“各找各妈”的原则的,可以任意混搭。即你写了一个 XAUTH 即可支持所有完全使用或部分使用 XAUTH 方法的连接。
实际上:
: PSK "PSK password" 
相当于:
%any %any : PSK "PSK password"
遵循:
主机 对等点 : 方法 <本机证书/协议密码> <本机证书密码>
的格式。以 :为分界,分别从左到右填充,除了各类密码缺失以 null 补位,其它都用 %any 补位(密码怎么可能是 %any)。
于是
marguerite : EAP "user password"
相当于
marguerite %any : EAP "user password" // EAP 方法没有证书,也就没有证书密码
这里有些人可能迷惑了,前面不是说过以左为尊、本机(这里是 VPS)默认在左边吗,你刚才定义 eap-mschapv2 的时候可是定义给的 rightauth,这次怎么把 EAP 的用户名写在左边了?
请注意,ipsec.conf 使用的是本机/他机的逻辑,本机默认在左; 而 ipsec.secrets 使用的是主机/对等点的逻辑,主机永远在左。
ipsec.conf 里面定义的是连接,左侧的本机(对你来说,本机是你的笔记本,而对服务器来说,本机是它自己,你才是它的“他机”,这个配置是在服务器上的,不要混淆)用证书认证,右侧是你的 win7 用 mschapv2 认证; 而 ipsec.secrets 里定义的是认证,认证过程是你的 win7 用这个用户名和后面定义的密码去连接主机,认证是主机上发生的,所以要写在左边。
另外一部分人可能会混淆主机/对等点的含义,认为他们和 BT 是一样的,你开启了一个 strongswan 连接,于是你是主机,而其它人都是对等点,于是他们统一了本机/他机和主机/对等点这两种截然不同的逻辑。前面已经说了我们的例子是以 VPS/客户机这种典型案例为主,而你的客户机是图形界面自适配的,你没有改过客户机的配置文件(所以官方维基上提供的例子你要看的是 moon 的配置),这种尴尬的统一的影响几乎没有。
而这种案例下,你不能理解主机/对等点的含义的后果是致命的:
你有一台国外 VPS,一台国内 VPS,想让国内 VPS 也能科学上网。那你在国内 VPS 上就可能产生这样的配置:
<国外 VPS 的 IP> <国内 VPS 的 IP> : RSA <国内 VPS 的私人证书名称> <私人证书密码>
国外 VPS:
<国外 VPS 的 IP> <国内 VPS 的 IP> : RSA <国外 VPS 的服务器证书名称> // 服务器证书一般没有密码
这里国外服务器是主机,国内服务器是对等点。主机永远只有一台,而且是在一开始便确定并固定不变的。如果你把国内 VPS 配置成:
<国内 VPS 的 IP> <国外 VPS 的 IP> : RSA <国内 VPS 的私人证书名称> <私人证书密码>
是无法连接的。因为主机始终是国外的 VPS。你可以想象为 BT 中心种子服务器和你的计算机的关系。中心种子服务器是固定不变的。
另外也间接证明了 ipsec 连接的代理是单向的,只能是主机为对等点做代理。就是说即使两台都是服务器,它们的 ipsec 连接也不是双向的,比如你国内服务器可以科学上网,而国外服务器可以看优酷,这是不可能在一个连接里发生的。

[编辑] strongswan.conf

# strongswan.conf - strongSwan configuration file
charon {
       duplicheck.enable = no

       dns1 = 208.67.222.222
       dns2 = 208.67.220.220

       # for Windows only
       nbns1 = 208.67.222.222
       nbns2 = 208.67.220.220

       filelog {
               /var/log/strongswan.charon.log {
                   time_format = %b %e %T
                   default = 2
                   append = no
                   flush_line = yes
               }
       }
}
从 strongswan 5 起,无论是 ikev1 还是 ikev2 协议都使用 ikev2 的 daemon:charon 来实现。也就是说不必再在 /etc/strongswan.conf 里配置 pluto 了。
duplicheck.enable = no 是为了你能同时连接多个设备,所以要把冗余检查关闭。
dns 就不说了。nbns 是 Windows 的 NetBIOS 名称服务器实现, wins 服务会请求的。实际上 NBNS 协议是一个标准协议,但问题是 Linux 不强制而 Windows 强制请求,你不定义就无法连接。所以对于 ipsec VPN 来说,这个就是只供 Windows 使用的。
下面的 filelog 定义了一个文本日志。ipsec 协议的各种实现似乎都没有显式定义文本日志(比如 racoon,strongswan 都没有),而是写入系统日志 syslog。那样不利于调试,所以显式定义一下。
  • default 是默认日志级别:-1,0,1,2,3,4。-1 是完全没有日志; 0 只告诉你连接建立、连接关闭; 1 只输出错误提示; 2 会输出错误、警告和调试信息; 3 会把连接传输的数据也打印; 4 则会把密钥内容这些敏感数据也打印。一般情况下,1 或 2 都可以。
  • append 是当你重启 strongswan 后,是接上次日志写,还是新建一个日志(上次的会被删除)。因为 strongswan 的日志太多了,所以用 no。
  • flush_line 是每产生一行日志,就写入到磁盘一次。防止突然断电,磁盘缓存数据丢失。
另外你还可以详细定义每个 strongswan 模块的日志级别,但是没什么必要,具体可见 LoggerConfiguration

[编辑] 启动 Strongswan

sudo systemctl enable strongswan.service
sudo systemctl start strongswan.service
注:如果是 openSUSE12.2 发行版,包中默认没有strongswan.service,需要用户到 /etc/init.d/ 目录下启动服务。
cd /etc/init.d/
sudo ipsec start

[编辑] 配置 Iptables 转发

sudo iptables -A INPUT -p udp --dport 500 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 4500 -j ACCEPT
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -s 10.0.0.0/24 -j ACCEPT
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
为了每次 VPS 启动不重新输入这些命令,我们做成了一个 Systemd 服务 strongswan-iptables.service。下载扔到 /etc/systemd/system,然后:
systemctl enable strongswan-iptables.service
systemctl start strongswan-iptables.service
即可运行上述命令。以后系统启动时也将自动运行上述命令。

[编辑] openSUSE 客户端配置

strongswan 项目同时开发了 NetworkManager-strongswan,最新版本是 1.3。
安装 NetworkManager-strongswan
sudo zypper in NetworkManager-strongswan
GNOME 要安装 NetworkManager-strongswan-gnome
sudo zypper in NetworkManager-strongswan-gnome
KDE 要安装 NetworkManager-strongswan-kde4
sudo zypper in NetworkManager-strongswan-kde4
如果你的 strongswan 是 5.0.0 以上的话,你还要安装 strongswan-nm
sudo zypper in strongswan-nm
然后编辑 /etc/NetworkManager/VPN/nm-strongswan-service.name,替换
program=/usr/lib/ipsec/charon
为:
program=/usr/lib/ipsec/charon-nm
并重载 systemd 的全部系统服务
sudo systemctl --system daemon-reload
不然会出现 “vpn service 'strongswan' start timed out” 即 “signal of type SIGTERM received. Shutting down” 错误。因为 5 版的 strongswan 引入了一个 strongswan-nm 来避免与系统的 strongswan 冲突,而 openSUSE 的 NetworkManager-strongswan 的 systemd 服务有 bug(待修复),并不会去使用 strongswan-nm。
之后一定要重启 NetworkManager.service 服务:
sudo systemctl restart NetworkManager.service
不然你设置好了会发现无法保存私钥(private key)的密码,也不会弹出窗口,错误信息为:
 <error> [1370608229.893778] [nm-vpn-connection.c:1355] plugin_need_secrets_cb(): (f4f7fcdb-110b-4f80-8fc8-23934fc29a0c/strongswan) plugin NeedSecrets request #1 failed: dbus-glib-error-quark Rejected send message, 1 matched rules; type="method_call", sender=":1.3" (uid=0 pid=569 comm="/usr/sbin/NetworkManager --no-daemon ") interface="org.freedesktop.NetworkManager.VPN.Plugin" member="NeedSecrets" error name="(unset)" requested_reply="0" destination="org.freedesktop.NetworkManager.strongswan" (uid=0 pid=11246 comm="/usr/lib/ipsec/charon-nm ")
这是因为 NetworkManager 的 DBus 服务没有重载,不能识别 strongswan 的缘故。
配置要点如下:
  • 勾选系统连接,不然启动不了 daemon
  • 网关:你的服务器 URL 或 IP,必须和证书里面那个一样(证书里是 URL 这里就不能是 IP)
  • 证书:你的 CA 证书
  • 认证方式:证书/私钥
  • 证书:你的客户证书
  • 私钥:客户证书对应的私钥
  • 私钥密码:生成客户证书时让你输入的那个密码,没有就选不需要,否则选储存或总是询问
  • 勾选请求内部 IP 地址,不然你没有虚拟地址,tun 设备自然也没法为你中转流量
  • 勾选强制 UDP 封装,这是因为 strongswan 5 以后即使 ikev1 也是通过 ikev2 的 charon 后端通讯的。而 charon 有一个新的特性叫 MOBIKE,也就是手机端上的自动重连(只适用于使用证书的情况),这个特性是默认开启的。而开启了这个特性所有的流量都会走 4500 端口也就是 UDP。你不勾根本连不上。

[编辑] 其它客户端配置

[编辑] 其它 Linux

[编辑] Chakra Linux

方法和openSUSE的大同小异,不过关键问题在于Chakra默认所有源中是没有Strongswan,这个时候各位可以借助CCR来实现安 装,CCR中有三个包,分别是strongswan, networkmanager-strongswan, networkmanager-dispatcher-strongswan-systemd(目前三者由我自己维护,从AUR照抄,修改了其中一个依赖 而已)。其中,第一个是主要的,第二个大家都知道,第三个是systemd服务。推荐客户端用户只需要安装前两个。(我的源中默认启用了所有的源,包括 core, platform, desktop, apps, games, lib32, extra以及测试源和不稳定源,个人认为主要要启动extra源,因为需要到一些gtk库)
  • 编译安装两个主要包
ccr -S strongswan && ccr -S networkmanager-strongswan
(各位可以去喝喝茶,听听歌)
  • 下载strongswan源代码编译安装strongswan-nm,下载地址,下载到一个你知道的地方,我放到/home/source/目录下,解压后,开始编译strongswan-nm插件
# build charon with OpenSSL/NM Plugin
./configure --sysconfdir=/etc --prefix=/usr --libexecdir=/usr/lib \
   --disable-aes --disable-des --disable-md5 --disable-sha1 --disable-sha2 \
   --disable-fips-prf --disable-gmp --enable-openssl --enable-nm --enable-agent \
   --enable-eap-gtc --enable-eap-md5 --enable-eap-mschapv2
make
make install
完成安装后,注意/usr/lib/ipsec/目录下多出了一个charon-nm,这个就是我么需要的东西。下面的设置基本遵循玛丽苏的方式。
  • 编辑/etc/NetworkManager/VPN/nm-strongswan-service.name,替换
program=/usr/lib/strongswan/charon
为:
program=/usr/lib/ipsec/charon-nm
  • 后面的步骤依照openSUSE中“并重载 systemd 的全部系统服务”
  • NetworkManager 的配置要点同 openSUSE
  • 补充:这个时候你的客户端应该能够连接了,如果不能,首先看看防火墙策略,如果还是不行,你可以试试先随便连接一个 VPN ,然后断开再连自己的 strongswan
其他 Linux 发行版参考 openSUSE 配置。

[编辑] iOS

把 CA 证书和之前做好的 pkcs12(.p12)发邮件给自己。在 iOS 上收邮件,导入两者。然后新建 IPSec VPN:
  • 服务器,和 openSUSE 的要求一样,都是 IP 或都是 URL
  • 账户和密码写 ipsec.secrets 里 XAUTH 前后的那两个
  • 如果要使用证书,证书选刚才的那个。否则可以不使用证书,输入 ipsec.secrets 里设置的 PSK 密码。

[编辑] Android

[编辑] IPSec Xauth PSK

我的 Jelly Bean 是有这个的,设置 VPN 之前 JB 要求你必须设置锁屏密码或者 PIN 码。
主要还是:
  • 服务器,同上
  • IPSec 预共享密钥:写 ipsec.secrets 里 PSK 后面的那个密码。
然后登入时还是用 XAUTH 前后的那两个做用户名密码。

[编辑] "strongSwan VPN Client" for Android 4.0 (ICS)+

这是官方自己出的客户端,Google Play 里就有。
把之前做好的 pkcs12 发邮件给自己。实际上 pkcs12 里就包含了 CA 证书,iOS 是有 bug 才必须明确要求导入 CA 证书(鄙视之)。Android 不用。直接在 GMail 里点击就会提示你导入。
然后打开官方客户端,新建方案:
  • Gateway 就是服务器,同上
  • Type 选 IKEv2 Certificate
  • User certificate 选你刚才导入的
  • 取消自动选择 CA 证书,然后在用户证书里选你刚才从 pk12 导入的

[编辑] Windows XP/Vista

注意 XP/Vista 本身不支持纯 IPsec 连接。如果使用 L2TP/IPsec 模式,使用证书会 fallback 到 iOS_cert 这个连接类型,使用预共享密码会 fallback 到 android-xauth-psk 这个连接类型。

[编辑] 使用 Shrew Soft VPN Client

下载:https://www.shrew.net/download/vpn
安装后打开,选“Add”:
  • “General”选项卡下,把“Host Name or IP address”添好
  • “Authorization”选项卡下:
    • “Authorization Method”选“Mutual PSK + XAuth”
    • “Local Identity”的“Identification Type”选“IP Address”
    • “Credentials”下面“Pre Shared Key”里输入 PSK 密码
  • “Phrase 1”,“Exchange Type”选“Main”
  • “Phrase 2”,“PFS Exchange”选“auto”
保存。连接时用户名密码是你的 XAUTH 用户名密码。
服务器端对应的配置是 android-xauth-psk 的连接类型。

[编辑] Windows 7+

使用 Shrew Soft VPN Client 客户端:和上面 XP 的一样。
使用自带客户端(Agile):
导入证书:
  • 开始菜单搜索“cmd”,打开后输入 mmc(Microsoft 管理控制台)。
  • “文件”-“添加/删除管理单元”,添加“证书”单元
  • 证书单元的弹出窗口中一定要选“计算机账户”,之后选“本地计算机”,确定。
  • 在左边的“控制台根节点”下选择“证书”-“个人”,然后选右边的“更多操作”-“所有任务”-“导入”打开证书导入窗口。
  • 选择刚才生成的 client.cert.p12 文件。下一步输入私钥密码。下一步“证书存储”选“个人”。
  • 导入成功后,把导入的 CA 证书剪切到“受信任的根证书颁发机构”的证书文件夹里面。
  • 打开剩下的那个私人证书,看一下有没有显示“您有一个与该证书对应的私钥”,以及“证书路径”下面是不是显示“该证书没有问题”。
  • 然后关闭 mmc,提示“将控制台设置存入控制台1吗”,选“否”即可。
至此,证书导入完成。
注意 千万不要双击 .p12 证书导入!因为那样会导入到当前用户而不是本机计算机中,ipsec 守护精灵是访问不了它的。
建立连接:
  • “控制面板”-“网络和共享中心”-“设置新的连接或网络”-“连接到工作区”-“使用我的 Internet 连接”
  • Internet 地址写服务器地址,注意事项同 openSUSE 的,都是 IP 或都是 URL。
  • 描述随便写。
  • 用户名密码写之前配置的 EAP 的那个。
  • 确定
  • 点击右下角网络图标,在新建的 VPN 连接上右键属性然后切换到“安全”选项卡。
  • VPN 类型选 IKEv2
  • 数据加密是“需要加密”
  • 身份认证这里需要说一下,如果想要使用 EAP-MSCHAPV2 的话就选择“使用可扩展的身份认证协议”-“Microsoft 安全密码”,想要使用私人证书认证的话就选择“使用计算机证书”。

[编辑] 调试

如果没有特殊需要,服务器端的日志就足够检测出绝大多数问题的来源。
我唯一需要在客户端上侦错的那次是 iOS 客户端。

[编辑] 日志阅读技巧

strongswan 的 charon daemon 启动后,会初始化并加载之前你定义好的 conn,这部分 log 是没有必要去读的。当然在你配置有问题时可能就有必要了,但当配置有问题的时候,systemctl start strongswan.service 会失败,systemctl status strongswan.service 就会指出你配置问题所在的行号(=。=)...
所以你只要去查找“added configuration 'windows7'”,这里 windows7 是你配置的最后一个 conn 的名称,然后从那里往下看就好了。
另外连接失败是会把连接状态从 CONNECTING 变为 DELETEING 的,DELETEING 又会刷一大堆日志,但那些日志都是没用的。

[编辑] 服务器端调试

/var/log/strongswan-charon.log 文件

[编辑] Linux 调试

参照 strongswan 配置教学改 /etc/strongswan.conf,之后同服务器端调试。

[编辑] iOS 调试

越狱安装 iFile。编辑 /etc/racoon/racoon.conf 文件,找到 #log debug; 字段,改成:
log debug;
path logfile "/var/log/racoon.log";
保存。

[编辑] Android 调试

  • strongSwan 官方客户端提供了日志查看功能。
  • android 自带的 VPN 调试方法如下:
打开“终端模拟器”,输入 su,会弹出超级用户,允许。
cd /storage/sdcard0
logcat -f ./log.txt
然后用 Airdroid 等工具把 SD 卡中的 log.txt 传到电脑上,打开搜索 VPN 即可。

[编辑] Windows 调试

微软 technet:VPN Troubleshooting Tools

[编辑] 扩展阅读

[编辑] 计费软件

  • FreeRadius:账户认证和计费
  • daloRadius:用户账单管理
参考:使用 StrongSwan 搭建 IKEv1 IKEv2 VPN服务器|莓玩没了。注:该文的 strongswan 配置仅供参考(有很多冗余配置)。
  • MySQL:账户管理后台数据库
参考:SDB:搭建LAMP服务器

[编辑] 参考文献

配置选项:
设备/操作系统特殊要求:

from http://zh.opensuse.org/index.php?title=SDB:Setup_Ipsec_VPN_with_Strongswan&variant=zh-cn

---------------------------

StrongSwan配置IPSEC VPN备忘

这货配了很多次了,但是每次都要去网上找真是不爽……所以还是做个备忘吧,以免再次陷入如此蛋疼的境地……

P.S. 这个是在 Debian Wheezy 下完成的,所以其他平台概不负责:P

####下载、编译

其他貌似还好,只要到 StrongSwan 官网上弄最新的版本就好了……只是编译的配置是比较蛋疼的,虽说只是自用而已,但貌似这个可以用 Radius 的……所以看起来这个是比较适合我的:

./configure --sysconfdir=/etc --enable-eap-identity --enable-eap-mschapv2 --enable-md4 --enable-integrity-test --enable-test-vectors --disable-sql --disable-mysql --enable-xauth-eap --enable-eap-radius --enable-eap-md5 --prefix=/usr --enable-openssl --enable-shared --enable-eap-peap --enable-dhcp

后来的事情就比较简单了,直接去做 make && make install 就可以了。当然,如果在 configure 过程中出现错误提示只要根据提示去 apt-get 就好了。 ####StrongSwan配置

这个就是关键问题了……由于本人使用的习惯,采用了针对iOS使用证书+PSK、对其他平台采用 XAUTH PSK 的方式,由于 Windows 几乎不使用,所以暂时没有添加 ikev2。至于证书,为了方便,直接使用 StartSSL 提供的免费证书,然后以下为配置文件:

ipsec.conf

config setup
    uniqueids=never 

conn iOS_cert
    keyexchange=ikev1
    left=%defaultroute
    leftauth=pubkey
    leftsubnet=0.0.0.0/0
    leftcert=server.cert.pem
    right=%any
    rightauth=pubkey
    rightauth2=xauth
    rightsourceip=10.0.0.0/24
    rightcert=client.cert.pem
    auto=add

# also supports iOS PSK and Shrew on Windows
conn android_xauth_psk
    keyexchange=ikev1
    left=%defaultroute
    leftauth=psk
    leftsubnet=0.0.0.0/0
    right=%any
    rightauth=psk
    rightauth2=xauth
    rightsourceip=10.0.0.0/24
    auto=add

strongswan.conf

# strongswan.conf - strongSwan configuration file
charon {
       duplicheck.enable = no

       dns1 = 208.67.222.222
       dns2 = 208.67.220.220

       # for Windows only
       nbns1 = 208.67.222.222
       nbns2 = 208.67.220.220

       filelog {
               /var/log/strongswan.charon.log {
                   time_format = %b %e %T
                   default = 2
                   append = no
                   flush_line = yes
               }
               stderr {  
         			# more detailed loglevel for a specific subsystem, overriding the  
         			# default loglevel.  
         			ike = 3  
         			knl = 3  
         			# prepend connection name, simplifies grepping  
         			ike_name = yes  
       			}  
       }
}

ipsec.secrets

#
# ipsec.secrets
#
# This file holds the RSA private keys or the PSK preshared secrets for
# the IKE/IPsec authentication. See the ipsec.secrets(5) manual page.
#
: RSA server.key.pem
: PSK "PSK password"
username : XAUTH "user password"

剩下的就是把各种证书倾倒到 /etc/ipsec.d 下的 cacertscertsprivate中了。然后执行 ipsec start --nofork,查看是否能够正常运行。如若能运行的话,那么基本就没什么问题了。

####配置 iptables 这个就非常简单了,可以说就是一句话

iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

地址和接口根据自己实际情况修改即可。

当然,一个非常重要的事情,就是千万不要忘记对/etc/sysctl.conf的修改,开启 ip_forward,然后做一次 sysctl -p 以令更改生效。

其余的就没什么了,享受科学上网吧!

同时感谢以下来源的帮助:

使用 Strongswan 架设 Ipsec VPN

使用StrongSwan搭建 IKEv1 IKEv2 VPN服务器

------------------------------------------------------ ----------------------

支持国密sm1,sm2,sm3,sm4算法的ipsec vpn。  

strongSwan Configuration

Overview

1,这是一个基于strongswan的支持国密算法sm1,sm2, sm3,sm4 的开源ipsec vpn 2,添加了gmalg插件,用于支持软算法 sm2, sm3, sm4 3,修改了pki工具,添加了支持sm2的各种证书生成读取 4,pki工具也添加了crypto命令,用于测试国密算法 5,strongswan支持使用TUN设备的应用层IPSec功能和基于内核xfrm的IPSec功能,由于内核xfrm需 要内核加密支持另外写了一个soft_alg的内核加密驱动,使其内核支持sm3和sm4,便于测试, 后面测试案例采用,TUN设备的应用层IPSec,但内核xfrm也是完全支持的,仅需修改配置,加载 驱动即可
添加目录:build.sh 编译脚本 testing/tests/gmalg 这个是测试脚本 src/libstrongswan/plugins/gmalg 这是strongswan的加密算法插件框架 src/libstrongswan/plugins/gmalg/gmalg 这是sm2,sm3,sm4的软算法实现
为了方便,将软算法的源代码放在了gmalg插件里,但也可以改用动态库形式,只需在configuie 命令后 面添加 --with-gmalg_interior=no参数即可,但要提供libgmalg.so 动态库及gmalg.h 头文件
libgmalg.so可以有src/libstrongswan/plugins/gmalg/gmalg目录的源码生成,只需要在这个目录make就可 以, 生成文件在src/libstrongswan/plugins/gmalg/gmalg目录的.obj目录里面。如需替换软算法,修改 gmalg.c文件即可
编译软件: 1,在strongswan目录运行autogen.sh命令。生成configuie命令 2,在主机的根系统上创建 /ipsec 目录,添加权限 chmod 777 /ipsec 3,在strongswan目录运行autogen.sh命令。配置,编译及安装strongswan 4,将/ipsec目录打包拷贝到server和client上,必须解压到根目录,比如pki命令, /ipsec/bin/pki 5,尽量不要用软件默认路径安装,便于删除和更新
测试脚本在testing/tests/gmalg目录,测试步骤如下: 1,进入testing/tests/gmalg/ipsec_cert目录,运行sm2.sh命令,生成所需的所有证书,包括客户端和主机端 运行local.sh 加载文件到所需目录,这里注意,只生成一次,客户端和主机端加载的ca证书相同,不然验证不过 2,在服务端:运行src/libstrongswan/plugins/gmalg 目录下的init_server.sh脚本,初始化环境 3,在客户端:运行src/libstrongswan/plugins/gmalg 目录下的init_client.sh脚本,初始化环境 4,两端同时运行运行src/libstrongswan/plugins/gmalg 目录下的run.sh脚本,启动软件
ipsec规则设置:修改testing/tests/gmalg/swanctl目录里的ip地址,即可实际配置
使用内核xfrm 的配置: 编译soft_alg驱动模块并加载 服务端和客户端运行testing/tests/gmalg/libipsec/run_libipsec.sh脚本,修改配置即可.

from https://github.com/zhangke5959/strongswan
----

用 strongSwan 配一个支持 AEAD 的远程访问 IKEv2 VPN

前言
IKEv2/IPsec 是一套网络层数据加密方案,它可以配置为点到点、站到站、网状网(Cisco DMVPN)、远程访问。IKEv2/IPsec 远程访问 VPN 十分适合于远程办公的场景。
IKEv2/IPsec 有两个组成部分,IKEv2 负责对通信双方进行鉴权并协商临时密钥,IPsec 负责匹配给定的流量规则并加密数据。
IPsec 有两种模式,AH 和 ESP。AH 只进行真实性校验,不加密;ESP 既做真实性校验又加密。实际应用中,AH 因为不支持 NAT 穿隧而并没有什么用处。如果真的有不加密的需求,可以将 ESP 的加密模式设置成 null。
其中,ESP 也有两种模式,transport 和 tunnel。Transport 模式下,加密载荷里直接就是传输层段或者报文,因而只能加密两个端点之间的连接;tunnel 模式下,加密载荷里有第二层 IP 报头,不仅可以进行路由,还可以给 NAT 后的客户端分配虚拟 IP 地址。
综上所述,我们要配置的 IPsec 模式应为 ESP tunnel。
关于认证阶段
IKEv2 的认证分为两个阶段。
Phase 1:双方鉴权和协商 IKE_SA,使用 UDP 500 端口。对于远程访问 VPN 来说,客户端验证服务端的 PKI 证书,服务端验证客户端的用户名密码。
Phase 2:建立隧道和协商 CHILD_SA,使用 IP 50 协议或 UDP 4500 端口(若启用 NAT 穿隧)。双方根据配置好的规则来决定哪些流量需要加密。对于远程访问 VPN 来说,客户端会请求加密全部流量(0.0.0.0/0 和 ::/0)。
随后,双方配置操作系统的 IPsec Policy 来把流量加密转发到 IP 50 协议或 UDP 4500 端口上。
为了保证同一个临时密钥不使用太长时间,IKEv2 会每隔一段时间 rekey 一次。在本例,我们关闭服务端的 rekey,将 rekey 的任务交给客户端,否则会因为双方同时 rekey 而掉线。
软件环境
服务端:Debian testing (10.0pre),strongSwan 5.6.3,systemd 239,AppArmor 2.12。
客户端:Windows 10 Pro 1803、macOS High Sierra 10.13.6、iOS 11.4.1。
如果你在用旧版的 Debian 或者 Ubuntu,强烈建议你打开 updates 和 backports 源。其中 updates 包含版本内功能更新,backports 包含跨版本功能更新。
步骤一:安装依赖
sudo apt update
sudo apt install certbot charon-systemd iptables-persistent libcharon-extra-plugins libstrongswan-extra-plugins ndppd
本文使用了新版 strongSwan 的部分新功能,所以请务必确认 strongSwan 的版本高于 5.7.1。
步骤二:申请 Let's Encrypt 证书
如果你已经有在开 HTTPS 业务,那么直接把 TLS 证书拿来用就好。
没有的话用 certbot 申请一个 Let's Encrypt 的证书:
sudo certbot certonly --standalone -d example.com
sudo ln -s /etc/letsencrypt/live/example.com/privkey.pem /etc/swanctl/private/example.com.key
一切顺利的话证书已经躺在 /etc/letsencrypt/live 里了。证书需要每隔 90 天续期一次,幸运的是 systemd 的 certbot.timer 会自动启动 certbot 来续期。不过续期之后 strongSwan 并不会自动重启,你可以在 /etc/letsencrypt/renewal-hooks 里写个脚本。
步骤三:配置 AppArmor
Debian 会默认给 strongSwan 打开 AppArmor。这样的话 strongSwan 就读取不到我们的证书文件了。在 /etc/apparmor.d/local/usr.sbin.swanctl 里加入:
/etc/letsencrypt/       r,
/etc/letsencrypt/**     r,
步骤四:配置日志
在遇到问题的时候有日志看是很重要的,因此我们要先打开必要的日志。在 /etc/strongswan.d/charon-systemd.conf 里写上:
charon-systemd {

    # Section to configure native systemd journal logger, very similar to the
    # syslog logger as described in LOGGER CONFIGURATION in strongswan.conf(5).
    journal {

        # Loglevel for a specific subsystem.
        # =

        # Default loglevel.
        # default = 1

        cfg = 2
        ike = 2

    }

}
步骤五:配置 swanctl
strongSwan 有两套配置系统:旧的一套是 ipsec.conf,使用 stroke 插件来启动;新的一套是 swanctl.conf,使用 vici 插件来启动。我们将使用新的 swanctl.conf 系统。虽然网络上关于 swantl.conf 的文档和资料还比较少,但是配置起来更加灵活。
在 /etc/swanctl/swanctl.conf 里加入:
authorities {
    lets-encrypt {
        file = /etc/letsencrypt/live/example.com/chain.pem
    }
}

connections {
    ikev2 {
        version = 2
        local_addrs = %any
        remote_addrs = %any
        # 这是 Windows 10 和 macOS High Sierra 兼容的最优 Phase 1 加密套件。如果你的客户端支持更好的加密套件,可以在这里写上。
        proposals = chacha20poly1305-aes256gcm16-prfsha384-curve25519-ecp384-modp3072-ecp256,aes256-sha384-curve25519-ecp384-modp3072-ecp256,aes256gcm16-prfsha384-modp1024,aes256-sha256-ecp256
        dpd_delay = 30s
        send_certreq = no
        send_cert = always
        rekey_time = 0s
        pools = pool-ipv4,pool-ipv6
        local {
            certs = /etc/letsencrypt/live/example.com/cert.pem
            id = example.com
        }
        remote {
            eap_id = %any
            auth = eap-mschapv2
        }
        children {
            ikev2 {
                # 这是 Windows 10 和 macOS High Sierra 兼容的最优 Phase 2 加密套件。如果你的客户端支持更好的加密套件,可以在这里写上。
                esp_proposals = chacha20poly1305-aes256gcm16-prfsha384-curve25519-ecp384-modp3072-ecp256-modpnone-esn-noesn,aes256-sha384-curve25519-ecp384-modp3072-ecp256-modpnone-esn-noesn,aes256-sha256-sha1
                local_ts = 0.0.0.0/0,::/0
                rekey_time = 0s
                hw_offload = auto
            }
        }
    }
}

secrets {
    eap-1 {
        # 两个客户端不可以共用同一个用户名,否则会发生 IP 地址冲突。如果有多个客户端,请分配多个用户名。
        secret = 用户1和用户2共用的密码
        id-user1 = 用户名1
        id-user2 = 用户名2
    }
    eap-2 {
        secret = 用户3的密码
        id-user3 = 用户名3
    }
    private-1 {
        file = example.com.key
    }
}

pools {
    pool-ipv4 {
        # 这里也可以写 100.100.100.129-100.100.100.254 的格式,或者换成你想要的 IPv4 地址段。
        addrs = 100.100.100.128/25
        dns = 8.8.8.8,8.8.4.4
    }
    pool-ipv6 {
        # 改成上游 ISP 分配的 IPv6 子网的一小段。
        addrs = 2001:db8::/97
        dns = 2001:4860:4860::8888,2001:4860:4860::8844
    }
}
步骤六:配置 IPv4 NAT
在 /etc/iptables/rules.v4 加入:
*nat
:PREROUTING ACCEPT [31:5739]
:INPUT ACCEPT [31:5739]
:OUTPUT ACCEPT [28:3794]
:POSTROUTING ACCEPT [11:1486]
-A POSTROUTING -m policy --pol ipsec --dir out -j ACCEPT
-A POSTROUTING -s 100.100.100.128/25 -o eth0 -j MASQUERADE
COMMIT
步骤七:配置 IPv6 NDP Proxy
在 /etc/ndppd.conf 加入:
# 改成你的出站设备名
proxy eth0 {
    # 改成上游 ISP 分配的 IPv6 子网的一小段。
    rule 2001:db8::/97 {
        static
    }
}
步骤八:启用 IP 转发
在 /etc/sysctl.d/50-ip-forwarding.conf 里写上:
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
注意当开启 IPv6 转发的时候,SLAAC 会被默认关闭。如果你通过 SLAAC 从上游 ISP 收取 IPv6 地址,那么需要将其手动打开:(可选)
net.ipv6.conf.eth0.accept_ra = 2
或者,如果你使用 /etc/network/interfaces、NetworkManager、systemd-networkd 来配置网络,只需要打开 SLAAC 开关即可。
步骤九:启动服务
sudo systemctl restart apparmor
sudo systemctl restart netfilter-persistent ndppd strongswan-swanctl systemd-sysctl
sudo systemctl enable certbot.timer netfilter-persistent ndppd strongswan-swanctl
# 禁用旧版 ipsec.conf 配置服务
sudo systemctl disable strongswan
步骤十:连接客户端
在开始之前,我强烈建议在一台空闲的电脑上连接 VPN 网关,输入:
sudo journalctl -u strongswan-swanctl -f
来查看实时滚动日志。
Windows
在 Windows 设置里,进入 Network & Internet → VPN → Add a VPN connection。
VPN provider:
Windows (built-in)
Connection name:
随意
Server name or address:
服务器的域名
VPN type:
IKEv2
User name:
用户名
Password:
密码
如果提示 Error 13801: IKE authentication credentials are unacceptable,那么请用 certmgr.msc 导入 Let's Encrypt Authority X3 中间证书。
如果还是不行,就导入这条注册表项:
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RasMan\Parameters]
"DisableIKENameEkuCheck"=dword:00000001
macOS
在 macOS 系统偏好设置里,进入 Network,点击左边栏底部的「+」。
Interface:
VPN
VPN Type:
IKEv2
Service Name:
随意
Server Address:
服务器的域名或 IP 地址(如果填域名连接超时就填 IP 地址)
Remote ID:
服务器的域名,不能填 IP 地址
Local ID:
留空
Authentication Settings:
Username
Username:
用户名
Password:
密码
iOS
在 iOS 的设置里,进入 VPN → Add VPN Configuration。
Type:
IKEv2
Description:
随意
Server:
服务器的域名或 IP 地址(如果填域名连接超时就填 IP 地址)
Remote ID:
服务器的域名,不能填 IP 地址
Local ID:
留空
Uesr Authentication:
Username
Username:
用户名
Password:
密码
Linux 和 Android
Linux 用户只需要将 swanctl.conf 的内容反过来填就成了客户端配置。
对于 Android 用户,可以去 Google Play 下载 strongSwan 客户端。
如何配置默认网关
Windows 默认不把所有流量都发送到 VPN,macOS 和 iOS 则相反。如果要改变这个设置,可以根据以下步骤来操作。
Windows
IPv4:在 Windows 设置里,进入 Network & Internet → Status → Network and Sharing Center → Change adapter settings → VPN (IKEv2) → 右键属性 → Networking → TCP/IPv4 → Properties → Advanced → IP Settings → Use default gateway on remote network。
IPv6:虽然 TCP/IPv6 里也有这个名字的选项,但是实际上无效。要想设置 IPv6 的默认网关,请打开 PowerShell,输入:
Add-VpnConnectionRoute "连接名" ::/1
Add-VpnConnectionRoute "连接名" 8000::/1
macOS
VPN 已断开的状态下,在 macOS 系统偏好设置里,进入 Network,选择 VPN (IKEv2),点击 Advanced,在 Options 选项卡内,勾选 Send all traffic over VPN connection。
如何打开 AEAD(仅 Windows 10 支持)
AEAD 可以在同一个算法内实现加密和校验,能够提高连接的安全性。
请打开 PowerShell,输入:
Set-VpnConnectionIPsecConfiguration -ConnectionName "连接名" -AuthenticationTransformConstants GCMAES256 -CipherTransformConstants GCMAES256 -EncryptionMethod GCMAES256 -IntegrityCheckMethod SHA384 -PfsGroup ECP384 -DHGroup ECP384 -Force

备用:旧版 ipsec.conf 配置
这是过时的 ipsec.conf 配置文件,仅供参考,不要使用。
config setup
    charondebug = "cfg 2, ike 2"

ca lets-encrypt
    cacert = /etc/letsencrypt/live/example.com/chain.pem
    auto = add

conn ikev2
    left = %any
    leftauth = pubkey
    leftcert = /etc/letsencrypt/live/example.com/cert.pem
    leftid = @example.com
    leftsendcert = always
    leftsubnet = 0.0.0.0/0,::/0
    right = %any
    rightauth = eap-mschapv2
    rightdns = 8.8.8.8,8.8.4.4,2001:4860:4860::8888,2001:4860:4860::8844
    rightsendcert = never
    rightsourceip = 100.100.100.128/25,2001:db8::/97
    auto = add
    dpdaction = clear
    eap_identity = %any
    esp = chacha20poly1305-aes256gcm16-prfsha384-curve25519-ecp384-modp3072-ecp256-modpnone-esn-noesn,aes256-sha384-curve25519-ecp384-modp3072-ecp256-modpnone-esn-noesn,aes256-sha256-sha1!
    ike = chacha20poly1305-aes256gcm16-prfsha384-curve25519-ecp384-modp3072-ecp256,aes256-sha384-curve25519-ecp384-modp3072-ecp256,aes256gcm16-prfsha384-modp1024,aes256-sha256-ecp256!
    keyexchange = ikev2
    rekey = no
/etc/ipsec.secrets
# ln -s /etc/letsencrypt/live/example.com/privkey.pem /etc/ipsec.d/private/example.com.key
: RSA "example.com.key"

用户名1 : EAP "用户1的密码"
用户名2 : EAP "用户2的密码"
用户名3 : EAP "用户3的密码"

from http://m13253.blogspot.com/2018/07/strongswan-ikev2-vpn.html