序言:

故事是这样开始的

 前段时间,给Mac升级了系统的,恰巧在平常办公还需用到拨VPN的用户,想必也知道新的Mac系统里已经不再支持PPTP了。而是只支持l2tp,ikev2,ipsc这些协议详情可以点击这里:官方建议。巧的是我们的vpn就是pptp的…,而且领导们也都升级了系统,悲剧了吧。想想升级方案吧。本来是准备使用l2tp+ipsec的,但后来在搭建好后,用客户端进行测试时却一直出现809错误。此刻,有种香菇的感觉…

 不过想到了mac上面还有个IKEv2的vpn类型,当时是病急乱投医的感觉,其它方案都不可用,试试这个吧,于是GG搜了相关资料,也看了官方介绍,以及前辈大牛们的搭建文章,就像是郑和发现新大陆一样的心情。这个了不得呀,而且完全不用安装特殊客户端啊,多好的服务呀。好吧,少一点真诚,多一点套路。在整个学习搭建到后期实现,测试整套方案的过程,便有了这篇文章。如果有需要改正的,请一定留言告诉我哈。

strongSwan自述

strongSwan

strongSwan

 strongSwan是一个开源的IPsec实现项目。它最初是基于停产的FreeS / WAN项目(这里有介绍),我们开发了X.509补丁。为了有一个稳定的IPsec平台,立足于X.509能力的扩展,我们决定在2005年启动strongSwan项目。

 至此,新的IKE守护程序使用现代化面向对象的编码风格编写,使当前的代码已经不在和它的祖先共享。最初的守护进程仅支持IKEv2协议,而IKEv1则是由被FreeS / WAN的 pluto 守护程序的扩展版本处理。但是,由于其他厂商依然长期采用IKEv2协议,后来在strongSwan 5.0.0版本时,便增加了IKEv1的支持,加入到新的守护程序。

strongSwan最初设计用于Linux上,现在已经被移植到Android,FreeBSD,Mac OS X,Windows等平台上。

strongSwan的特点:

支持的客户端:

开始动刀吧

  1. 环境架构:可参考下图
    Topology

    arch Topology

系统:Centos7.0 minimal

公网IP: 192.168.30.57(根据实际更改)

使用IKEv2协议,客户端认证方式使用 用户名+密码 + 证书 结合的方式。

  1. 安装前配置系统

    sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
    setenforce 0
  2. 更新系统并安装需要的软件环境

    yum update -y
    yum install pam-devel openssl-devel make gcc curl tcpdump -y
  3. 安装最新版strongSwan软件

下载解压

wget -c https://download.strongswan.org/strongswan-5.5.1.tar.gz
tar -xf strongswan-5.5.1.tar.gz && cd strongswan-5.5.1

编译前的configure参数

./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-swanctl --enable-openssl --disable-gmp

备注:--enable-eap-radius 是为了后期与radius 结合时模块,如果你的radius 和ipsec不能一起工作,可检查编译安装时有没有开启这个模块。

编译安装

make && make install
  1. 生成相关证书文件(使用ipsec pki命令)

    • 创建证书存放目录 bash mkdir key_files && cd key_files    
    • 生成一个新的私钥,并用新私钥生成一个自签名的CA证书,有效期为10年

      ipsec pki --gen --outform pem > ca.pem
      ipsec pki --self --in ca.pem --dn "C=cn, O=ilove, CN=VPN CA" --ca --lifetime 3650 --outform pem >ca.cert.pem

      备注:C 表示国家,O 表示组织名,如guge。CN 为通用名。(在整个部署过程中要保持一致)

    • 生成一个新的私钥,创建服务器证书时需要。然后从刚生成的私钥中提取公钥,使用上一步自签名的CA证书文件,颁发一个服务器证书

      ipsec pki --gen --outform pem > server.pem
      ipsec pki --pub --in server.pem | ipsec pki --issue --lifetime 1200 --cacert ca.cert.pem --cakey ca.pem --dn "C=cn, O=ilove, CN=192.168.30.57" --san="192.168.30.57" --flag serverAuth --flag ikeIntermediate --outform pem > server.cert.pem

      备注:--CN=192.168.30.57 --san=192.168.30.57 可以替换成你的公网ip

    • 生成一个新的私钥,并用上一步自签名的CA证书颁发一个客户端证书

      ipsec pki --gen --outform pem > client.pem
      ipsec pki --pub --in client.pem | ipsec pki --issue --cacert ca.cert.pem --cakey ca.pem --dn "C=cn, O=ilove, CN=VPN Client" --outform pem > client.cert.pem

      备注:这里客户端的证书可以和ca 证书不一样。

  2. 将生成的证书文件拷贝到strongswan程序中的相关目录中

    cp ca.cert.pem /usr/local/etc/ipsec.d/cacerts/
    cp server.cert.pem /usr/local/etc/ipsec.d/certs/
    cp server.pem /usr/local/etc/ipsec.d/private/
    cp client.cert.pem /usr/local/etc/ipsec.d/certs/
    cp client.pem  /usr/local/etc/ipsec.d/private/
  3. 配置strongSwan IPsec服务

    • 配置ipsec,文件在/usr/local/etc/ipsec.conf,内容如下
# cat /usr/local/etc/ipsec.conf
config setup
    uniqueids=never 

conn iOS_cert
    keyexchange=ikev1
    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.0.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.1.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 ios_ikev2
    keyexchange=ikev2
    ike=aes256-sha256-modp2048,3des-sha1-modp2048,aes256-sha1-modp2048!
    esp=aes256-sha256,3des-sha1,aes256-sha1!
    rekey=no
    left=%defaultroute
    leftid=192.168.30.57
    leftsendcert=always
    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
    dpdaction=clear
    fragmentation=yes
    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

备注: 注意:leftid 要改为你自己的公网IP,切记。

config setup 所有项目共用配置项
uniqueids=never 允许多个客户端使用同一证书,即多设备同时在线
conn ios_ikev2 定义一个连接标识,用于ipsec status 查看连接时有所区别
left=%any     服务器端标识,%any表示任意
leftsubnet=0.0.0.0/0 服务器端虚拟ip, 0.0.0.0/0表示通配.
right=%any   客户端标识,%any表示任意
leftcert=server.cert.pem   服务器端证书
rightsourceip=10.31.2.0/24     分配给客户端的虚拟ip段
leftid=192.168.30.57  这里选择你的ip地址。必须和证书里填写的一致。
ike 密钥交换算法

详细的ipsec.conf 请参考官网

cat /usr/local/etc/strongswan.conf
charon {
        load_modular = yes
        duplicheck.enable = no
        compress = yes
        plugins {
                include strongswan.d/charon/*.conf
        }
        dns1 = 114.114.114.114
        dns2 = 8.8.8.8
        nbns1 = 8.8.8.8
        nbns2 = 8.8.4.4
}
include strongswan.d/*.conf

备注:

Duplicheck.enable = no    关闭冗余检查,同时连接多个设备
plugins strongswan 支持的插件配置,不建议在此文件里配置,应去charon目录下。
cat /usr/local/etc/ipsec.secrets
: RSA server.pem
: PSK "iloveworld"
: XAUTH "iloveworldPass"
testUserOne %any : EAP "testOnePass"

备注:

RSA  服务器的私钥
PSK  共享密钥(可用于ios 10上直接使用Cisco的 IPSec连接)
testUserOne 是用户名, testOnePass 是用户名密码,可填写多行,添加多个用户时,需要重启ipsec
  1. 配置linux系统内核开启转发功能,并配置iptables规则

8.1 开启内核转发,暂时生效:

sysctl -w net.ipv4.ip_forward=1

或者让其永久生效:

echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p

8.2 添加iptables 规则

先清除原有规则(线上的话建议先备份,并保证22端口可连接,此步骤可不做。)

iptables -F
iptables -X

转发规则

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 10.31.0.0/24  -j ACCEPT
iptables -A FORWARD -s 10.31.1.0/24  -j ACCEPT
iptables -A FORWARD -s 10.31.2.0/24  -j ACCEPT

入站规则(注意:-i 你的网卡名称)

iptables -A INPUT -i eno16777984 -p esp -j ACCEPT
iptables -A INPUT -i eno16777984 -p udp -m state --state NEW --dport 500 -j ACCEPT
iptables -A INPUT -i eno16777984 -p udp -m state --state NEW --dport 4500 -j ACCEPT
iptables -A INPUT -i eno16777984 -p udp -m state --state NEW --dport 1701 -j ACCEPT
iptables -A INPUT -i eno16777984 -p tcp -m state --state NEW --dport 1723 -j ACCEPT

Nat规则

iptables -t nat -A POSTROUTING -s 10.31.0.0/24 -o eno16777984 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.31.1.0/24 -o eno16777984 -j MASQUERADE
iptables -t nat -A POSTROUTING -s 10.31.2.0/24 -o eno16777984 -j MASQUERADE

保存iptables规则

service iptables save

备注:在这个环境里,我是卸载了7的 firewalld程序,并安装了iptables-services程序。注意:-i 网卡名称(填写你自己的网卡名称,7以前的是ethxx)

这里完整的iptables 规则,可以参考:

cat /etc/sysconfig/iptables
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [342:64390]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -i eno16777984 -p esp -j ACCEPT
-A INPUT -i eno16777984 -p udp -m udp --dport 500 -j ACCEPT
-A INPUT -i eno16777984 -p udp -m udp --dport 4500 -j ACCEPT
-A INPUT -i eno16777984 -p udp -m udp --dport 1701 -j ACCEPT
-A INPUT -i eno16777984 -p tcp -m tcp --dport 1723 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -s 10.31.0.0/24 -j ACCEPT
-A FORWARD -s 10.31.1.0/24 -j ACCEPT
-A FORWARD -s 10.31.2.0/24 -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
*nat
:PREROUTING ACCEPT [24:10065]
:INPUT ACCEPT [5:241]
:OUTPUT ACCEPT [18:1422]
:POSTROUTING ACCEPT [18:1422]
-A POSTROUTING -s 10.31.0.0/24 -o eno16777984 -j MASQUERADE
-A POSTROUTING -s 10.31.1.0/24 -o eno16777984 -j MASQUERADE
-A POSTROUTING -s 10.31.2.0/24 -o eno16777984 -j MASQUERADE
COMMIT

9.启动ipsec程序

ipsec start
Starting strongSwan 5.5.1 IPsec [starter]...

其它一些可用命令:

ipsec start   #启动服务
ipsec stop    #关闭服务
ipsec restart #重启服务
ipsec reload  #重新读取
ipsec status  #查看状态
ipsec --help  #查看帮助
  1. 服务器安装配置完的基本信息
VPN服务器:192.168.30.57
VPN用户:testUserOne
VPN密码:testOnePass
PSK:       iloveworld

客户端使用ca证书:ca.cert.pem(可修改为.cer结尾,发送给每个vpn用户进行证书安装,后面有安装步骤)

现在让用户验证吧

  1. Windows 用户安装测试

将ca.cert.pem证书修改后缀为.cer,然后拷贝到windows系统中,并命令行里打开mmc,添加证书管理单元,选择计算机账户,之后点击导入该证书,如下图:

证书

Windows 导入证书示例

打开网络共享中心面板,新建一个VPN连接,如下图:

new vpn

控制面板

创建新连接

new vpn

创建新连接

使用我的Internet连接

new vpn

使用新连接

这里选择稍后连接,因为还要配置下安全选项。

输入用户名和密码

new vpn

用户名和密码

点击创建,之后点击关闭,然后去右键该连接的属性。点击安全,修改vpn类型为IKEv2如下图:

new vpn

安全属性

设置完成后就可以连接啦。连接完成检查下vpn连接状态,如下:

new vpn

链接状态

  1. Mac OS 用户测试

先将证书拷贝到mac系统内,双击打开。如下:

new vpn

安装证书

此处注意 修改使用此证书时: 始终信任。 可能需要输入系统管理员的密码!

之后,打开网络偏好设置,添加VPN,如下图:类型选择IKEv2

new vpn

VPN类型

再之后输入vpn信息,服务器地址和远程ID均输入VPN服务器公网ip,点击鉴定设置,输入用户名和密码。点击连接即可

new vpn

VPN 用户名和密码

最后查看本机ip配置,类似下图,已经获得ip,并且可以正常上网。

new vpn

链接状态

  1. iOS客户端

证书安装:

将证书放置在手机浏览器可以访问下载的地方(我是直接在这个vpn服务器开个80,让手机去下载的证书),用safari访问,打开,之后输入手机密码进行证书的安装。添加VPN方法和mac类似。不在叙述 注: ios 手机端可以选择IKEv2,也可以选择IPSec。 IPSec配置方式如下:

new vpn

手机配置ipsec

这里的密钥就是 PSK,在密码认证文件里,这里的PSK密钥为 iloveworld(推荐设置复杂高强度)OK,上面就是记录整个strongSwan安装到使用的过程。想着既然vpn升级了,本身就是大工程,那何不做完善点?

于是便有了这个 利用开源软件strongSwan实现支持IKEv2的企业级IPsec VPN,并结合FreeRadius实现AAA协议(下篇), 我擦,这名字真长,真不知道我是怎么想出来的 💣….

下篇文章的内容,记录的主要是利用freeradius 软件来实现radius的 3A(即认证、授权、计费)功能,并结合DaloRadius进行web管理。(daloradius 的web界面有几处与centos7 系统算是不兼容吧,我对php的个别页面进行了修改)。过几天发下篇吧。到时大家再细看吧。

参考

https://www.strongswan.org/blog/2016/10/21/strongswan-5.5.1-released.html

https://wiki.strongswan.org/projects/strongswan/wiki/IpsecPKI

https://www.lowendtalk.com/discussion/44964/vpn-everywhere-ipsec-without-l2tp-with-strongswan-even-in-openvz

https://libreswan.org/

https://wiki.strongswan.org/projects/strongswan/wiki/Win7Certs

https://wiki.strongswan.org/projects/strongswan/wiki/Win7Config

https://wiki.strongswan.org/projects/strongswan/wiki/Win7Connect

https://wiki.strongswan.org/projects/strongswan/wiki/WindowsVista

https://wiki.strongswan.org/projects/strongswan/wiki/AppleClients#iOS-client-configuration

https://zh.wikipedia.org/wiki/IPsec

https://blogs.technet.microsoft.com/ianhamer/2007/02/20/an-ipsec-is-an-ipsec-is-an-ipsec-redux/

https://zh.wikipedia.org/wiki/RADIUS

http://freeradius.org/

https://wiki.archlinux.org/index.php/StrongSwan_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)

https://zh.opensuse.org/SDB:Setup_Ipsec_VPN_with_Strongswan

https://www.kiritostudio.com/running-a-strongswan-server-with-radius-on-your-vps/

http://bao3.blogspot.com/2013/05/racoonstrongswanvpn.html

https://zh.opensuse.org/index.php?title=SDB:Setup_Ipsec_VPN_with_Strongswan&variant=zh

https://www.gitbook.com/book/akagi201/freeradius-beginners-guide/details

https://wiki.strongswan.org/projects/strongswan/wiki/AppleClients

https://github.com/quericy/one-key-ikev2-vpn/issues/36#issuecomment-240609434

https://sourceforge.net/p/daloradius/discussion/684101/

http://pig.made-it.com/AAA.html