转载 - 使用Strongswan来搭建IPSec VPN

本文主要是备份之前一直存储在为知笔记上的一篇文章, 不知道原作者是谁, 我每次安装strongswan都是参考这篇文章, 这篇文章写得很详细, 照着做就能搭建出来. 如果作者看到了, 文章下方评论下, 我将加上转载链接, 同时本文将在原文基础上改为CentOS, 并保留原Ubuntu的文体, 便于原作者辨认, 同时辅以Linode Japan2的真实操作为示例.

(English version translate by GPT-3.5)

本来Strongswan搭建IKEv2 VPN有一篇很好的教程(在nsshell.com上),但是貌似nsshell.com貌似挂了(反正我打不开),于是我就做个搬运,把教程拿过来。。正好原文中有一两处遗漏,我也好补上去。

软件

Strongswan 5.7.2 MD5: d449aa1936218a42e34c32494947308b 官网下载 RuterFu My Storage

条件:

RAM大小合适的VPS或者服务器(96MB RAM就足够了,64MB RAM未测试)
可以是OpenVZ,但注意看教程中标注的针对OpenVZ的特殊步骤。

本文采用Linode Japan2服务器作为其安装环境, 系统CentOS 7.6

p.s. Linode还有20多美元反正安装下就几毛而已…

isLinode

这个Ping还是一如既往的不稳定…

LindoePing

附系统版本

1
2
3
[root@li****-18 ~]# cat /etc/centos-release
CentOS Linux release 7.6.1810 (Core)
[root@li****-18 ~]#

过程

  1. 准备工作

    请在虚拟机或服务器上安装好CentOS操作系统,32位、64位均可,本文使用7.6的版本,执行以下命, 将PAM库和SSL库安装在系统中

    1
    yum install pam-devel openssl-devel make gcc wget -y
  2. 下载最新的strongswan源代码

    1
    2
    3
    [root@li****-18 ~]# wget -c https://download.strongswan.org/strongswan-5.7.2.tar.gz
    [root@li****-18 ~]# tar -zxvf strongswan-5.7.2.tar.gz
    [root@li****-18 ~]# cd strongswan-5.7.2
  3. 编译

    OpenVZ执行

    1
    2
    3
    4
    5
    6
    ./configure  --enable-eap-identity --enable-eap-md5 --enable-eap-mschapv2 \
    --enable-eap-tls --enable-eap-ttls --enable-eap-peap --enable-eap-tnc \
    --enable-eap-dynamic --enable-eap-radius --enable-xauth-eap \
    --enable-xauth-pam --enable-dhcp --enable-openssl --enable-addrblock \
    --enable-unity --enable-certexpire --enable-radattr --enable-tools \
    --enable-openssl --disable-gmp --enable-kernel-libipsec

    其他服务器执行(本文执行这段)

    1
    2
    3
    4
    5
    6
    ./configure  --enable-eap-identity --enable-eap-md5 --enable-eap-mschapv2 \
    --enable-eap-tls --enable-eap-ttls --enable-eap-peap --enable-eap-tnc \
    --enable-eap-dynamic --enable-eap-radius --enable-xauth-eap --enable-xauth-pam \
    --enable-dhcp --enable-openssl --enable-addrblock --enable-unity \
    --enable-certexpire --enable-radattr --enable-openssl --disable-gmp \
    --prefix=/usr/local/strongswan

    当输出以下内容, 表示成功

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ..........
    config.status: creating config.h
    config.status: executing depfiles commands
    config.status: executing libtool commands

    strongSwan will be built with the following plugins
    -----------------------------------------------------
    libstrongswan: aes des rc2 sha2 sha1 md5 random nonce x509 revocation constraints pubkey pkcs1 pkcs7 pkcs8 pkcs12 pgp dnskey sshkey pem openssl fips-prf curve25519 xcbc cmac hmac
    libcharon: attr kernel-netlink resolve socket-default stroke vici updown eap-identity eap-md5 eap-mschapv2 eap-dynamic eap-radius eap-tls eap-ttls eap-peap eap-tnc xauth-generic xauth-eap xauth-pam dhcp certexpire radattr addrblock unity counters
    libtnccs: tnc-tnccs
    libtpmtss:

    [root@li****-18 strongswan-5.7.2]#

    等待这个过程结束后,执行以下命令(make会进行源码编译操作, 受主机性能影响, 需要点时间):

    1
    make && make install

    耐心地等待编译,性能不同编译所需时间也有所不同

    创建环境变量

    1. 进入/usr/local/strongswan/sbin/目录

      1
      [root@li****-18 strongswan-5.7.2]# cd /usr/local/strongswan/sbin/
    2. 记下这个目录, 然后编辑/etc/profile, 添加export PATH=/usr/local/strongswan/sbin:$PATH

      1
      2
      3
      4
      vi /etc/profile
      追加
      export PATH=/usr/local/strongswan/sbin:/usr/local/strongswan/bin:$PATH
      按:wq保存并退出
    3. 生效环境变量 source /etc/profile

      1
      2
      3
      4
      5
      6
      7
      8
      9
      [root@li****-18 sbin]# source /etc/profile
      [root@li****-18 sbin]#

      这时候运行ipsec version就会出现以下内容
      [root@li****-18 sbin]# ipsec version
      Linux strongSwan U5.7.2/K3.10.0-957.el7.x86_64
      University of Applied Sciences Rapperswil, Switzerland
      See 'ipsec --copyright' for copyright information.
      [root@li****-18 sbin]#
  4. 配置strongswan和证书

    1. 生成CA证书, 生成私钥

      1
      2
      在这里之前建议到一个新的目录, 我这里选择/home/ssl目录(自己创建), 然后接着以下命令
      ipsec pki --gen --outform pem > ca.pem
    2. 利用私钥,签名CA证书

      1
      ipsec pki --self --in ca.pem --dn "C=com, O=myvpn, CN=VPN CA" --ca --outform pem >ca.cert.pem
    3. 服务器证书 生成私钥

      1
      ipsec pki --gen --outform pem > server.pem
    4. 用CA证书签发服务器证书
      首先确认访问服务器的IP地址或域名,连接时不可使用其它地址,只能使用证书中的地址,请将下面一句命令中的123.123.123.123替换为自己服务器的IP地址或域名,连接时使用,一共需要替换两处。

      1
      2
      3
      4
      ipsec pki --pub --in server.pem | ipsec pki --issue --cacert ca.cert.pem \
      --cakey ca.pem --dn "C=com, O=myvpn, CN=123.123.123.123" \
      --san="123.123.123.123" --flag serverAuth --flag ikeIntermediate \
      --outform pem > server.cert.pem
    5. 客户端证书 生成私钥

      1
      ipsec pki --gen --outform pem > client.pem
    6. 利用CA签名客户端证书

      1
      ipsec pki --pub --in client.pem | ipsec pki --issue --cacert ca.cert.pem --cakey ca.pem --dn "C=com, O=myvpn, CN=VPN Client" --outform pem > client.cert.pem
    7. 生成pkcs12证书

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "client" -certfile ca.cert.pem -caname "VPN CA"  -out client.cert.p12
      这里需要输入密码, 随便输入一个即可, 注意2次密码要一致, 至此, 运行的命令如下

      [root@li****-18 sbin]# cd /home
      [root@li****-18 home]# mkdir ssl
      [root@li****-18 home]# cd ssl
      [root@li****-18 ssl]# ipsec pki --gen --outform pem > ca.pem
      [root@li****-18 ssl]# ipsec pki --self --in ca.pem --dn "C=com, O=myvpn, CN=VPN CA" --ca --outform pem >ca.cert.pem
      [root@li****-18 ssl]# ipsec pki --gen --outform pem > server.pem
      [root@li****-18 ssl]# ipsec pki --pub --in server.pem | ipsec pki --issue --cacert ca.cert.pem \
      > --cakey ca.pem --dn "C=com, O=myvpn, CN=139.***.***.18" \
      > --san="139.***.***.18" --flag serverAuth --flag ikeIntermediate \
      > --outform pem > server.cert.pem
      [root@li****-18 ssl]# ipsec pki --gen --outform pem > client.pem
      [root@li****-18 ssl]# ipsec pki --pub --in client.pem | ipsec pki --issue --cacert ca.cert.pem --cakey ca.pem --dn "C=com, O=myvpn, CN=VPN Client" --outform pem > client.cert.pem
      [root@li****-18 ssl]# openssl pkcs12 -export -inkey client.pem -in client.cert.pem -name "client" -certfile ca.cert.pem -caname "VPN CA" -out client.cert.p12
      Enter Export Password:
      Verifying - Enter Export Password:
      [root@li****-18 ssl]#
    8. 安装证书

      1
      2
      3
      4
      5
      cp -r ca.cert.pem /usr/local/strongswan/etc/ipsec.d/cacerts/
      cp -r server.cert.pem /usr/local/strongswan/etc/ipsec.d/certs/
      cp -r server.pem /usr/local/strongswan/etc/ipsec.d/private/
      cp -r client.cert.pem /usr/local/strongswan/etc/ipsec.d/certs/
      cp -r client.pem /usr/local/strongswan/etc/ipsec.d/private/
    9. 证书安装完成,接下来配置strongswan,编辑/usr/local/strongswan/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
      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
      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.31.2.0/24
      rightcert=client.cert.pem
      auto=add

      conn android_xauth_psk
      keyexchange=ikev1
      left=%defaultroute
      leftauth=psk
      leftsubnet=0.0.0.0/0
      right=%any
      rightauth=psk
      rightauth2=xauth
      rightsourceip=10.31.2.0/24
      auto=add

      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.31.2.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.31.2.0/24
      rightsendcert=never
      eap_identity=%any
      auto=add
    10. 编辑/usr/local/strongswan/etc/strongswan.conf

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      charon {
      load_modular = yes
      compress = yes
      plugins {
      include strongswan.d/charon/*.conf
      }
      dns1 = 8.8.8.8
      dns2 = 8.8.4.4
      nbns1 = 8.8.8.8
      nbns2 = 8.8.4.4
      }
      include strongswan.d/*.conf
    11. 编辑/usr/local/strongswan/etc/ipsec.secrets中的用户名、密码

      1
      2
      3
      4
      : RSA server.pem
      : PSK "[预共享密钥]"
      : XAUTH "[预共享密钥]"
      [用户名] %any : EAP "[密码]"

      注意将PSK、XAUTH处的预共享密钥编辑为唯一且私密的字符串,并且将[用户名]改为自己想要的登录名,[密码]改为自己想要的密码[]符号去掉,可以添加多行,得到多个用户。

  5. 修改系统转发以及防火墙配置

    1. 首先编辑/etc/sysctl.conf,将net.ipv4.ip_forward=1一行前面的#号去掉,保存后执行sysctl -p, 输出如下

      1
      2
      3
      4
      [root@li****-18 etc]# vi /etc/sysctl.conf 
      [root@li****-18 etc]# sysctl -p
      net.ipv4.ip_forward = 1
      [root@li****-18 etc]#
    2. 接下来修改iptables。

      OpenVZ执行

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
      iptables -A FORWARD -s 10.31.2.0/24 -j ACCEPT
      iptables -A INPUT -i venet0 -p esp -j ACCEPT
      iptables -A INPUT -i venet0 -p udp --dport 500 -j ACCEPT
      iptables -A INPUT -i venet0 -p tcp --dport 500 -j ACCEPT
      iptables -A INPUT -i venet0 -p udp --dport 4500 -j ACCEPT
      iptables -A INPUT -i venet0 -p udp --dport 1701 -j ACCEPT
      iptables -A INPUT -i venet0 -p tcp --dport 1723 -j ACCEPT
      iptables -A FORWARD -j REJECT
      iptables -t nat -A POSTROUTING -s 10.31.2.0/24 -o venet0 -j MASQUERADE

      其它服务器执行

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
      iptables -A FORWARD -s 10.31.2.0/24 -j ACCEPT
      iptables -A INPUT -i eth0 -p esp -j ACCEPT
      iptables -A INPUT -i eth0 -p udp --dport 500 -j ACCEPT
      iptables -A INPUT -i eth0 -p tcp --dport 500 -j ACCEPT
      iptables -A INPUT -i eth0 -p udp --dport 4500 -j ACCEPT
      iptables -A INPUT -i eth0 -p udp --dport 1701 -j ACCEPT
      iptables -A INPUT -i eth0 -p tcp --dport 1723 -j ACCEPT
      iptables -A FORWARD -j REJECT
      iptables -t nat -A POSTROUTING -s 10.31.2.0/24 -o eth0 -j MASQUERADE

      由于CentOS7的防火墙由firewall-cmd接管, 此处使用firewall-cmd进行配置

      参考文章 IPSEC VPN on Centos 7 with StrongSwan

      1
      2
      3
      4
      5
      6
      7
      8
      firewall-cmd --zone=dmz --permanent --add-rich-rule='rule protocol value="esp" accept'
      firewall-cmd --zone=dmz --permanent --add-rich-rule='rule protocol value="ah" accept'
      firewall-cmd --zone=dmz --permanent --add-port=500/udp
      firewall-cmd --zone=dmz --permanent --add-port=4500/udp
      firewall-cmd --permanent --add-service="ipsec"
      firewall-cmd --zone=dmz --permanent --add-masquerade
      firewall-cmd --set-default-zone=dmz
      firewall-cmd --reload

    3. 接下来(公共部分)保存iptables配置并配置开机自动载入 如果使用了firewall-cmd配置, 跳过此项

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      iptables-save > /etc/iptables.rules
      将以下内容保存到/etc/rc.local

      iptables-restore < /etc/iptables.rules

      chmod +x /etc/rc.d/rc.local

      以上命令如下
      [root@li****-18 etc]# iptables-save > /etc/iptables.rules
      [root@li****-18 etc]# vi /etc/rc.local
      保存上面 iptables-restore这一段, :wq保存并退出
      [root@li****-18 etc]# chmod +x /etc/rc.d/rc.local
      [root@li****-18 etc]#
  6. 启动strongswan

    1
    2
    3
    [root@li****-18 etc]# ipsec start
    Starting strongSwan 5.7.2 IPsec [starter]...
    [root@li****-18 etc]#
  7. 尝试连接

    WindowsPhone, 木有设备, 就不做示例了

    WP8.1手机安装ca.cert.pem,进入设置-VPN添加IKEv2连接,地址为证书中的地址或IP,通过用户名-密码连接。

    Windows

    Windows连接也是一样,但注意将证书导入本地计算机而不是当前用户的“受信任的证书颁发机构”。

    1. 安全地复制服务器的ca.cert.pem到本地目录

    2. Win + R打开运行, 输入mmc
      openMMC

    3. 文件 - 添加/删除管理单元

    ![openMMC](https://oss.ruterfu.com/blog/2024/05/16/lZztBy6Cxi6aKKiE3g7tZv5WivGAoUIpR5d.webp)
    
    1. 添加证书 - 计算机账户 - 本地计算机(运行此控制台的计算机) - 确定
      addCert

    2. 打开证书 - 受信任的根证书颁发机构 - 证书右键 - 所有任务 - 导入
      importCert

    3. 导入ca.cert.pem, 文件 - 将所有证书导入到受信任的根证书颁发机构 - 完
      import ca.cert.pem

    4. 打开设置 - 网络 - VPN - 添加VPN连接
      1. VPN提供商 - Windows内置
      2. 连接名称 - 随意
      3. 服务器名称或地址 - 填写服务器IP地址
      4. VPN类型 - IKEv2
      5. 登陆信息的类型 - 用户名和密码(不要选证书)
      6. 用户名 密码 - 填写服务器的用户名密码

    5. 点击连接, 连接会成功, 但是无法上网

      此时windows还是没有走VPN, 查询后得到Windown10会默认开启Split-Tunneling 的玩意, 导致流量不走VPN, 解决方案如下
      参考官方文档 Introduction to strongSwan: Forwarding and Split-Tunneling
      参考文章 WIN10能连上VPN,却无法访问网页

    1.  打开PowerShell, 输入命令: `Set-VpnConnection "第七步的 连接名称" -SplitTunneling 0`
    2. 参考[WIN10能连上VPN,却无法访问网页](https://blog.csdn.net/gaojinshan/article/details/51249147)解决
    
    1. 问题解决后, 再次连接, 完成.
    ![windowsSuccess](https://oss.ruterfu.com/blog/2024/05/16/TulEsIQQwPHHY7uUyqfSY8x7N3JB2oBI5YX.webp)
    

    iPhone

    iOS/Android/Mac OS X设备添加Cisco IPSec PSK验证方式,预共享密钥是/usr/local/strongswan/etc/ipsec.secrets中PSK后的字符串(不含引号),用户名密码同上,可以通过任意域名或IP连接,不需要证书

    iPhoneConnection

    Mac 连接

    macConnect