使用StrongSwan配置IPSec

使用StrongSwan对IPSec进行研究,是一种很好的理解IPSec的实践。然而StrongSwan在使用的过程中实在是有太多的坑,网上的教程也多有不完整的地方,几乎没有能彻彻底底说明白每一步的,导致我在使用StrongSwan的过程中各种抓耳挠腮。程序员自然要造福程序员,在这里特将StrongSwan使用中所遇到的完整步骤记录下来,希望有所帮助。

准备工作

准备工作可不是简单地装个StrongSwan就完事儿了的,不知道要准备些什么,直接去看StrongSwan的配置,其实也是白搭的,最终还是什么都搞不出来,白忙活一场。其实准备工作的工作量还是挺大的:

准备一:场景

想知道怎么配置StrongSwan,首先要知道自己想搭建一个什么样的场景。在StrongSwan的官网上,我们可以在左侧找到TestScenarios,这里有许多场景,我们需要决定我们到底要再现哪一个。进去之后点开strongSWan test suits,在https://www.strongswan.org/testresults.html中有很多列表,我们打开ikev2,选择其中的net2net-psknet2net-rsa进行场景再现。

准备二:组网

PSK组网图
从net2net-psk的组网图,我们可以看到我们至少需要两个客户机Alice和Bob,两个网关Moon和Sun。net2net-rsa的组网与此相同。因此可以创建四台虚拟机ABCD,其中BC作为两个网关,AD作为左右子网的客户机。

总体为:A --子网1-- B ==子网2== C --子网3-- D

虚拟机使用VMware创建,在这里使用的是vmware12,虚拟机系统为Ubuntu16.10。

步骤:

  1. 装机
    安装一台虚拟机;

  2. 克隆
    在创建完虚拟机A之后,使用VMware的Clone直接克隆出BCD,比较方便;

  3. 调整网卡
    BC要作为网关存在,所以需要有两块网卡,因此要在设置里给BC再添加一块网卡;

  4. 配置网段
    在VMware的Edit选项中,选择Virtual Network Editor,添加三个虚拟网段vmnet2/vmnet3/vmnet4,类型为Host-Only,添加网段为上图的子网123的网段;DHCP选项关掉,不让自主分配IP;

  5. 虚拟机接入子网
    将虚拟机A的网卡类型设置为Custom,选择vmnet2,则A接入子网1,将B的两块网卡一块设为vmnet2,一块设为vmnet3,则B同时接入了子网1和子网2;同理,设置C和D;

  6. 配置虚拟机
    四台机器都开机,使用图形界面,照着上图配置机器的IP地址和子网掩码,其中A和D别忘了配置默认网关为B和C的IP,毕竟B和C是充当网关的;

  7. 开启转发
    非常重要,既然B和C充当网关,需要在B和C中修改/etc/sysctl.conf文件,将net.ipv4.ip_forward=1那一行的注释取消,这样才能发挥其路由器的功能。

准备三:安装StrongSwan

组网完成之后,才到了装StrongSwan的步骤了。Ubuntu装StrongSwan很简单,直接 sudo apt-get install strongswan即可。

至此,准备工作才算完毕。其中,光组网这一部就要费不少功夫。

Tips:
一定别忘了给四台Ubuntu虚拟机配置和宿主机之间的双向复制粘贴功能,也别忘了和宿主机设置一个共享文件夹,要不然接下来往虚拟机里加东西是很痛苦的!建议安装VMware提供的增强工具,具体可以自行搜索。如果还是不行别忘了sudo apt-get install open-vm-tools-desktop

配置

配置net2net-psk

先说psk的配置,因为psk的配置很简单。只需要使用Pre-Shared-Key进行认证就行了。这个预先设置好的key放在了ipsec.secrets中。

配置文件

  1. 配置网关B
    只需要把https://www.strongswan.org/testing/testresults/ikev2/net2net-psk/index.html上所提供的moonipsec.confipsec.secretsstrongswan.conf三个配置文件分别放到网关B的/etc/ipsec.conf/etc/ipsec.secrets/etc/strongswan.conf的位置即可。
  2. 配置网关C
    同B。只不过这次使用sun的配置文件。

启动

启动之前,A和D分别在不同的子网下,显然是不可能ping通的。

  1. 网关Bsudo ipsec startsudo ipsec restart,启动/重启StrongSwan,C也一样;
  2. 在网关B或C中运行sudo ipsec up net-net,即开启名字为net-net的连接,而net-net的具体配置在ipsec.conf中。

如果没什么意外,会显示隧道建立成功的提示,这时候使用sudo iptables -nvL --line-numbers可以看到网关的iptables中多了两条转发规则:

lgl@A ~> sudo iptables -nvL --line-numbers
Chain INPUT (policy ACCEPT 26 packets, 2100 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  ens38  *       10.1.0.0/24          10.2.0.0/24          policy match dir in pol ipsec reqid 1 proto 50
2        0     0 ACCEPT     all  --  *      ens38   10.2.0.0/24          10.1.0.0/24          policy match dir out pol ipsec reqid 1 proto 50

Chain OUTPUT (policy ACCEPT 27 packets, 3056 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

正是有了这两条规则,再试试拿主机A去ping主机D,二者可以通了。

配置net2net-rsa

配置rsa比较麻烦,主要是rsa需要进行公钥私钥的认证,还要有CA签发证书。具体的原理需要学习“非对称加密”,这里只说如何配置。

生成必要证书

建议在宿主机生成到和虚拟机的共享文件夹中,然后在虚拟机中将文件放到合适的位置。以下所有的命令均需要root权限,要不然会报错:command not found: ipsec

生成CA证书
生成私钥

ipsec pki --gen --outform pem > ca.pem

自签发CA证书

ipsec pki --self --in ca.pem --dn "C=CN, O=NetworkLab, CN=NetworkLab CA" --ca --outform pem > ca.cert.pem

这里–self表示自签证书,–in是输入的私钥,–dn是判别名,–ca表示生成 CA,其它同上。
- C 表示国家名,同样还有 ST 州/省名,L 地区名,STREET(全大写) 街道
- O 表示组织名
- CN 为通用名

生成服务器证书
其实就是给我们的网关B和C生成证书。这里,我们让B代表moon,C代表sun。
以sun为例
私钥

ipsec pki --gen --outform pem > sun.server.pem

签发服务器证书

ipsec pki --pub --in sun.server.pem | ipsec pki --issue --cacert ca.cert.pem --cakey ca.pem --dn "C=CN, O=NetworkLab, CN=sun.com" --san="sun.com" --flag serverAuth --flag ikeIntermediate --outform pem > sun.server.cert.pem

moon
同sun,不过要把所有的字符串sun换成moon。

ipsec pki --pub --in sun.server.pem就是从刚生成的私钥里把公钥提取出来。然后我们用公钥去进行后面的服务器证书签发。

生成客户端证书
同生成服务器的证书相对应,也是分为B和C的,这里依旧以sun为例。
sun
私钥

ipsec pki --gen --outform pem > sun.client.pem

签发客户端证书

ipsec pki --pub --in sun.client.pem | ipsec pki --issue --cacert ca.cert.pem --cakey ca.pem --dn "C=CN, O=NetworkLab, CN=client" --outform pem > sun.client.cert.pem

moon
同sun,不过要把所有的字符串sun换成moon。

至此,我们生成了以下文件:

ca.cert.pem
ca.pem

moon.client.pem
moon.server.cert.pem
moon.server.pem
moon.client.cert.pem

sun.client.pem
sun.client.cert.pem  
sun.server.pem  
sun.server.cert.pem

配置文件

安装证书

B和C两个网关是互为server和client的,因此,对于B来讲,它需要有:
1. CA证书(认证用)
2. moon的server私钥、moon的server证书(因为B是作为C的服务器,接收C的请求的)
3. sun的client私钥、sun的client证书(因为B同时作为C客户端,向C发出请求)

C则类似,但恰好相反:CA证书、sun的server私钥和证书、moon的client私钥和证书。

理清了这个关系之后,我们就把证书放到相应的位置。
对于B:

cp -r ca.cert.pem /etc/ipsec.d/cacerts/
cp -r moon.server.cert.pem /etc/ipsec.d/certs/
cp -r moon.server.pem /etc/ipsec.d/private/
cp -r sun.client.cert.pem /etc/ipsec.d/certs/
cp -r sun.client.pem /etc/ipsec.d/private/

C同理,不再赘述。

设置配置文件

这一步骤同psk的配置文件的安放位置是相同的,不再赘述,但是这里我们需要修改几个地方,因为我们的证书名称以及@id的名称都跟官网的略有区别,为了方便参考,将修改后的文件贴出来:
B:

lgl@A ~/s/n2n-rsa> cat /etc/ipsec.conf
# /etc/ipsec.conf - strongSwan IPsec configuration file

config setup

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    keyexchange=ikev2
    mobike=no

conn net-net
    left=192.168.0.1
    leftcert=moon.server.cert.pem
    leftsubnet=10.1.0.0/24
    leftid=@moon.com
    leftfirewall=yes
    right=192.168.0.2
    rightsubnet=10.2.0.0/24
    rightid=@sun.com
    auto=add
lgl@A ~/s/n2n-rsa> cat /etc/ipsec.secrets
# /etc/ipsec.secrets - strongSwan IPsec secrets file

: RSA moon.server.pem
lgl@A ~/s/n2n-rsa> cat /etc/strongswan.conf
# /etc/strongswan.conf - strongSwan configuration file

charon {
  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default updown
  multiple_authentication = no
  signature_authentication = no
}

C:

lgl@A ~> cat /etc/ipsec.conf
# /etc/ipsec.conf - strongSwan IPsec configuration file

config setup

conn %default
    ikelifetime=60m
    keylife=20m
    rekeymargin=3m
    keyingtries=1
    keyexchange=ikev2
    mobike=no

conn net-net
    left=192.168.0.2
    leftcert=sun.server.cert.pem
    leftsubnet=10.2.0.0/24
    leftid=@sun.com
    leftfirewall=yes
    right=192.168.0.1
    rightsubnet=10.1.0.0/24
    rightid=@moon.com
    auto=add
lgl@A ~> cat /etc/ipsec.secrets
# /etc/ipsec.secrets - strongSwan IPsec secrets file

: RSA sun.server.pem
lgl@A ~> cat /etc/strongswan.conf 
# /etc/strongswan.conf - strongSwan configuration file

charon {
  load = aes des sha1 sha2 md5 pem pkcs1 gmp random nonce x509 curl revocation hmac stroke kernel-netlink socket-default updown
  multiple_authentication = no
  signature_authentication = no
}

启动

启动方式跟psk相同。
1. 网关Bsudo ipsec startsudo ipsec restart,启动StrongSwan,C也一样;
2. 在网关B或C中运行sudo ipsec up net-net,即开启名字为net-net的连接,而net-net的具体配置在ipsec.conf中。

成功的话,大致是这样的:

bishe2016@A ~/s/n2n-rsa> sudo ipsec up net-net
initiating IKE_SA net-net[1] to 192.168.0.2
generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) ]
sending packet: from 192.168.0.1[500] to 192.168.0.2[500] (668 bytes)
received packet: from 192.168.0.2[500] to 192.168.0.1[500] (457 bytes)
parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) CERTREQ ]
received cert request for "C=CN, O=NetworkLab, CN=NetworkLab CA"
sending cert request for "C=CN, O=NetworkLab, CN=NetworkLab CA"
authentication of 'moon.com' (myself) with RSA signature successful
sending end entity cert "C=CN, O=NetworkLab, CN=moon.com"
establishing CHILD_SA net-net
generating IKE_AUTH request 1 [ IDi CERT N(INIT_CONTACT) CERTREQ IDr AUTH SA TSi TSr N(EAP_ONLY) ]
sending packet: from 192.168.0.1[500] to 192.168.0.2[500] (1484 bytes)
received packet: from 192.168.0.2[500] to 192.168.0.1[500] (1292 bytes)
parsed IKE_AUTH response 1 [ IDr CERT AUTH SA TSi TSr N(AUTH_LFT) ]
received end entity cert "C=CN, O=NetworkLab, CN=sun.com"
  using certificate "C=CN, O=NetworkLab, CN=sun.com"
  using trusted ca certificate "C=CN, O=NetworkLab, CN=NetworkLab CA"
checking certificate status of "C=CN, O=NetworkLab, CN=sun.com"
certificate status is not available
  reached self-signed root ca with a path length of 0
authentication of 'sun.com' with RSA signature successful
IKE_SA net-net[1] established between 192.168.0.1[moon.com]...192.168.0.2[sun.com]
scheduling reauthentication in 3289s
maximum IKE_SA lifetime 3469s
connection 'net-net' established successfully

同样,我们可以查看iptables,并使用A成功ping同D。

也可以使用sudo ipsec statusall查看连接状态:

lgl@A ~/s/n2n-rsa> sudo ipsec statusall
Status of IKE charon daemon (strongSwan 5.3.5, Linux 4.8.0-41-generic, x86_64):
  uptime: 3 hours, since Mar 22 11:33:30 2017
  malloc: sbrk 2420736, mmap 0, used 241824, free 2178912
  worker threads: 11 of 16 idle, 5/0/0/0 working, job queue: 0/0/0/0, scheduled: 3
  loaded plugins: charon aes sha1 sha2 md5 pem pkcs1 gmp random nonce x509 revocation hmac stroke kernel-netlink socket-default updown
Listening IP addresses:
  192.168.90.130
  10.1.0.1
  192.168.0.1
Connections:
     net-net:  192.168.0.1...192.168.0.2  IKEv2
     net-net:   local:  [moon.com] uses public key authentication
     net-net:    cert:  "C=CN, O=NetworkLab, CN=moon.com"
     net-net:   remote: [sun.com] uses public key authentication
     net-net:   child:  10.1.0.0/24 === 10.2.0.0/24 TUNNEL
Security Associations (1 up, 0 connecting):
     net-net[4]: ESTABLISHED 25 minutes ago, 192.168.0.1[moon.com]...192.168.0.2[sun.com]
     net-net[4]: IKEv2 SPIs: 6fba3bd57680d6d4_i* 17339e6111cf6564_r, public key reauthentication in 28 minutes
     net-net[4]: IKE proposal: AES_CBC_128/HMAC_SHA1_96/PRF_HMAC_SHA1/MODP_2048
     net-net{14}:  INSTALLED, TUNNEL, reqid 4, ESP SPIs: ceac4ddb_i c9645c64_o
     net-net{14}:  AES_CBC_128/HMAC_SHA1_96, 0 bytes_i, 0 bytes_o, rekeying in 4 minutes
     net-net{14}:   10.1.0.0/24 === 10.2.0.0/24

猜你喜欢

转载自blog.csdn.net/puppylpg/article/details/64918562