全能IPSec

下午好朋友。众所周知,我们中的许多人至少有一次,但是不得不处理配置VPN的需求。作为Habr的活跃读者,我注意到,尽管有很多关于IPSec的文章,但对于许多人来说,它似乎仍然是一件复杂而繁重的事情。在本文中,我将以我自己的完全有效的配置为例,消除这些神话。在四个示例中,我们将完整地介绍最流行的Linux(Strongswan)解决方案,从带有使用PSK密钥进行侧面身份验证的简单隧道到基于基于Let's Encrypt的证书进行双方身份验证的主机到主机连接。有趣?欢迎来到猫!

背景


最初,仅针对在父母的小型路由器与同时充当路由器的家用“床头”服务器之间的通道组织来规划VPN。

短时间后,Keenetic从两个设备添加到该公司。
但是一旦开始,它就变得很难停止,很快电话和一台笔记本电脑就出现在图表上,他们想躲开MT_Free和其他未加密的WiFi网络广为人知的广告眼。

然后,心爱的ILV最终变得更强大了,他难以置信地爱上了四面八方的摇摆人Banhammer,并且为了抵消对凡人的担忧,他不得不支持外国IT部门在国外收购VPS。
此外,一定公民谁看起来像Shapoklyak,运行到处她的手提袋由包,可能认为“谁帮助的人,是在浪费时间。您不能以善行而出名,“我想偷偷窥视别人的交通,并用铅笔记录下来。在这种情况下,我们还必须严格按照医生的命令为自己防御这种未经请求的爱和VPN。

总结一个简短的总结。有必要找到一种理想情况下可以一次关闭多个任务的解决方案:

  • Linux路由器之间的互连
  • 在Linux和Keenetic Household之间建立隧道
  • 使来自不受信任网络的可穿戴设备(电话,笔记本电脑)可以访问家庭资源和Internet
  • 创建到远程VPS的安全加密隧道

不要忘记奇妙的KISS原理-保持简单,愚蠢。涉及的组件越少,每个组件的配置就越容易-越可靠。

现有解决方案概述


简要回顾一下现在的情况: 所有协议的

PPTP

祖父列宁。死于“霉菌和菩提树蜂蜜的腐烂”。

L2TP

除了一个提供程序,任何人都可以使用吗?

Wireguard

项目正在开发中。积极锯。在具有静态IP的两个对等点之间创建隧道很容易。在其他情况下,拐杖,带方轮的自行车和蓝色胶带总是可以帮助您,但这不是我们的方法。

OpenVPN

优点:

  • 支持多种平台-Windows,Linux,OpenWRT及其衍生版本,Android
  • 强大的加密和证书支持。
  • 定制的灵活性。

缺点:

  • 完全在用户空间中工作。
  • 家用路由器的支持有限-Mikrotik上的krenenko-kosenko(在不影响腺体的其他优势的情况下)和OpenWRT中的正常功能。
  • 设置移动客户端的困难:您需要下载或创建自己的安装程序,将配置复制到某个地方。
  • 如果有多个隧道,则在服务器上编辑systemd单元等待舞蹈。

OpenConnect(Cisco Anyconnect协议的开源实现)
不幸的是,一个非常有趣的解决方案是大量的信息。

优点:

  • 对各种平台的相对广泛的支持-基于商店中基于Cisco Anyconnect本机应用程序的Windows,Android和Mac-是提供对可穿戴设备的内部网络的访问的理想选择。
  • 强大的加密,证书支持,2FA连接
  • 该协议本身完全基于TLS(与OpenVPN不同,它很容易在端口443上检测到)。除TLS外,还支持DTLS-在建立的会话期间,客户端可以切换为通过UDP传输数据,反之亦然。
  • 使用sniproxy在VPN和成熟的Web服务器的一个端口上实现出色的共存。
  • 易于配置服务器和客户端。

这里也并非没有缺点:

  • 完全在用户空间中工作。
  • TCP之上的TCP是一个坏主意。
  • 客户级设备不提供支持。
  • 在两个Linux之间安装隧道的复杂性:理论上可行,实际上-最好花一些时间在更有用的东西上。
  • 如果有多个隧道,则正在等待具有多个配置和编辑systemd单元的舞蹈。

这似乎是一个死胡同,但是经过仔细研究并花了一些时间研究之后,我意识到基于IKEv2的IPSec能够替代其他所有内容。

IKEv2 IPSEC

优点:

  • 随着IKEv2的出现,与以前的版本相比,该协议本身已变得更易于配置,但代价是失去了向后兼容性。
  • 归功于标准化,可以在任何地方和任何地方提供工作-列表可以无限期维护。Linux,Mikrotik(在最新版本的RouterOS中),OpenWRT,Android,iPhone。从Windows 7开始,Windows还具有本机支持。
  • 高速:完全在内核空间中进行流量处理。用户空间部分仅用于设置连接参数和监视通道的运行状况。
  • 使用多种身份验证方法的能力:同时使用PSK和证书,以及任意组合。
  • 几种操作模式:隧道和运输。可以阅读它们的不同之处,包括在Habré上。
  • 中间节点的设置要求不高:如果在IKE的第一个版本中存在由NAT引起的问题,则IKEv2具有内置的机制来克服NAT和IKE消息的本机分段,从而使您可以在具有MTU曲线的通道上建立连接。展望未来,我要说的是,实际上,我从来没有遇到过WiFi网络,无论客户端可以在哪里建立连接。

但是,缺点还包括:

  • 您需要花费一些时间来研究和理解其工作原理。
  • 可能会使新手感到困惑的功能:与传统的VPN解决方案不同,IPSec无法创建网络接口。仅设置流量处理策略,其他所有内容均通过防火墙解决。

在进行设置之前,我们假设读者已经对基本概念和术语有所了解。为了帮助初学者,您可以推荐Wikipedia和Habr本人的文章,关于该主题的文章已经非常有趣和有用。

开始设定


决定后,我们继续进行配置。在我的情况下,网络图具有以下形式(在扰流板下删除)

网络图

ipsecgw.example.com是作为网络中心的主服务器。外部IP 1.1.1.1。内部网络10.0.0.0/23和另一个地址10.255.255.1/30,用于与VPS设置专用BGP会话;
mama是一种Linux路由器,它基于父母安装的小型静音上网本。 ISP发出一个动态IP地址。内部网络10.0.3.0/24;
keenetic-安装了IPSec的Keenetic路由器。 ISP发出一个动态IP地址。内部网络10.0.4.0/24;
道路战士 -从不受信任的网络连接的便携式设备。从内部池(10.1.1.0/24)连接时,地址会动态发布给客户端;
rkn.example.com-受尊敬的ILV管辖范围之外的VPS。外部IP-5.5.5.5,内部地址10.255.255.2/30,用于设置专用BGP会话。

第一步。从简单到复杂:使用预共享密钥(PSK)的隧道


在两个Linux机器上,我们都安装必需的软件包:

sudo yum install strongswan

在两台主机上,打开端口500 / udp,4500 / udp并允许ESP协议通过。
编辑文件/etc/strongswan/ipsec.secrects(在主机端ipsecgw.example.com)并添加以下行:

mama@router.home.local: PSK "Very strong PSK"

在第二面,类似地:

root@root.mama.local: PSK "Very strong PSK"

在这种情况下,该ID是虚拟的电子邮件地址。可以在官方Wiki上找到更多信息

秘密已保存,继续前进。

在ipsecgw.example.com主机上,编辑/etc/strongswan/ipsec.conf文件:

config setup //   charon
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0" //  
conn %default //    
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2 //      - IKEv2
    dpdaction = hold
    dpddelay = 5s // 5   DPD (Dead Peer Detection)   
    mobike = yes // Mobile IKE -     IP    
conn mama //  
    left = %defaultroute //Left -  .  %defaultroute       IKE- ,    default route
    right = %any //     IP-
    authby = psk //   -   
    leftid = mama@router.home.local // ID,   ipsec.secrets
    rightid = root@router.mama.local //ID  
    leftsubnet = 10.0.0.0/23,10.1.1.0/24 
    rightsubnet = 10.0.3.0/24
    type = tunnel 
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519! 
    auto = add //  charon        

同样,我们在远程对等体/etc/strongswan/ipsec.conf上进行编辑:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn mama
    left = %defaultroute
    right = ipsecgw.example.com
    authby = psk
    leftid = root@router.mama.local
    rightid = mama@router.home.local
    leftsubnet = 10.0.3.0/24
    rightsubnet = 10.0.0.0/23,10.1.1.0/24
    type = tunnel
    ike = aes128gcm16-sha384-x25519!
    esp = aes128gcm16-sha384-x25519!
    auto = route

如果比较配置,可以看到它们几乎是镜像的,只有对等方的定义可以互换。auto = route

指令使charon为落入left / rightsubnet(流量选择器)指令的流量设置陷阱。在给定条件下出现流量之后,将立即开始协调隧道参数和交换密钥。 在防火墙设置的ipsecgw.example.com服务器上,我们禁止伪装10.0.3.0/24网络。允许在10.0.0.0/23和10.0.3.0/24之间转发数据包,反之亦然。在远程主机上,我们通过禁用10.0.0.0/23网络的伪装并设置转发来执行类似的设置。 我们在两台服务器上重新启动Strongswan,然后尝试ping中央节点:





sudo systemctl restart strongswan
ping 10.0.0.1


确保一切正常:
sudo strongswan status
Security Associations (1 up, 0 connecting):
        mama[53]: ESTABLISHED 84 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{141}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c4eb45fe_i ca5ec6ca_o
        mama{141}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


确保在所有对等点的/etc/strongswan/strongswan.d/charon.conf文件中将make_before_break参数设置为yes也是有用的。在这种情况下,服务于IKEv2协议的charon守护程序不会在密钥更改过程中删除当前的安全关联,而是会首先创建一个新的安全关联。

第二步 Keenetic的外观


令人惊喜的是,官方Keenetic固件中内置了IPSec VPN。要激活它,只需转到KeeneticOS组件设置并添加IPSec VPN软件包

为此,我们在中央节点上准备设置:

编辑/etc/strongswan/ipsec.secrects并添加新对等方的PSK:

keenetic@router.home.local: PSK "Keenetic+PSK"

编辑/etc/strongswan/ipsec.conf并在末尾添加另一个连接:

conn keenetic
    left = %defaultroute
    right = %any
    authby = psk
    leftid = keenetic@router.home.local
    rightid = root@router.keenetic.local
    leftsubnet = 10.0.0.0/23
    rightsubnet = 10.0.4.0/24
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add

在Keenetic方面,配置是通过以下路径在WebUI中完成的:Internet-> Connections->
Other Connections
很简单
(3张图片)






如果计划通过隧道驱动大量流量,则可以尝试启用硬件加速,许多型号都支持这种方式。CLI中crypto engine hardware命令启用使用通用CPU指令禁用和处理加密和哈希过程- 加密引擎软件

保存设置后,我们恢复了Strongswan并让Keenetic思考了半分钟。然后在终端中,我们看到一个成功的连接:

一切正常:
sudo strongswan status
Security Associations (2 up, 0 connecting):
    keenetic[57]: ESTABLISHED 39 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{146}:  INSTALLED, TUNNEL, reqid 29, ESP SPIs: ca8f556e_i ca11848a_o
    keenetic{146}:   10.0.0.0/23 === 10.0.4.0/24
        mama[53]: ESTABLISHED 2 hours ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{145}:  INSTALLED, TUNNEL, reqid 27, ESP in UDP SPIs: c5dc78db_i c7baafd2_o
        mama{145}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24


第三步 保护移动设备


阅读了一堆手册和一堆文章之后,我们决定停止从Let's Encrypt获得一堆免费证书,以通过客户端的登录名和密码来认证服务器和经典授权。因此,通过在受信任列表中安装自签名证书,我们无需维护自己的PKI基础结构,监视密钥的到期以及对移动设备执行不必要的手势。

安装缺少的软件包:

sudo yum install epel-release
sudo yum install certbot

我们获得了独立证书(别忘了先在iptables设置中打开80 / tcp):

sudo certbot certonly --standalone -d ipsecgw.example.com

certbot完成工作后,我们必须教Strongswan查看我们的证书:

  • 在目录/etc/strongswan/ipsec.d/cacerts中创建2个符号链接:一个到/ etc / pki / tls / certs中受信任证书的根存储;第二个名称为ca.pem,指向/etc/letsencrypt/live/ipsecgw.example.com/chain.pem
  • 在/etc/strongswan/ipsec.d/certs目录中还创建了两个符号链接:第一个符号名为certificate.pem,它指向文件/etc/letsencrypt/live/ipsecgw.example.com/cert.pem。第二个名为fullchain.pem,链接到/etc/letsencrypt/live/ipsecgw.example.com/fullchain.pem
  • 在/etc/strongswan/ipsec.d/private目录中,将key.pem符号链接指向certbot生成的私钥,并沿着路径/etc/letsencrypt/live/ipsecgw.example.com/privkey.pem放置

通过RSA向ipsec.secrets添加身份验证,并为新用户添加大量登录名/密码:

ipsecgw.example.com     : RSA key.pem
username phone          : EAP "Q1rkz*qt"
username notebook       : EAP "Zr!s1LBz"

我们重新启动Strongswan,当调用sudo strongswan listcerts时,我们应该看到证书信息:

List of X.509 End Entity Certificates

  subject:  "CN=ipsecgw.example.com"
  issuer:   "C=US, O=Let's Encrypt, CN=Let's Encrypt Authority X3"
  validity:  not before May 23 19:36:52 2020, ok
             not after  Aug 21 19:36:52 2020, ok (expires in 87 days)
  serial:    04:c7:70:9c:a8:ce:57:cc:bf:6f:cb:fb:d3:a9:cf:06:b0:a8
  altNames:  ipsecgw.example.com
  flags:     serverAuth clientAuth
  OCSP URIs: http://ocsp.int-x3.letsencrypt.org
  certificatePolicies:
             2.23.140.1.2.1
             1.3.6.1.4.1.44947.1.1.1
             CPS: http://cps.letsencrypt.org

然后,我们在ipsec.conf中描述新的连接

conn remote-access
    dpddelay = 30s //   DPD ,     
    left = %defaultroute
    leftid = "CN=ipsecgw.example.com"
    leftcert = fullchain.pem //         
    leftsendcert = always
    leftsubnet = 0.0.0.0/0 //      
    right = %any
    rightid = %any
    rightauth = eap-mschapv2 // ,  EAP-MSCHAP2
    rightsendcert = never
    eap_identity = %identity 
    rightsourceip = 10.1.1.0/24 //Strongswan       
    rightdns = 10.0.0.1,10.0.0.3 //   DNS
    type = tunnel
    ike = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha384-x25519!
    esp = aes256-aes192-aes128-sha256-sha384-modp2048-modp3072-modp4096-modp8192,aes128gcm16-sha256-sha384-x25519!
    auto = add //      
    dpdaction = restart // ,      DPD

不要忘记编辑文件/ etc / sysconfig / certbot,这表明我们还将证书更新为独立证书,并在其中添加了CERTBOT_ARGS =“ -standalone”。

另外,不要忘记打开certbot-renew.timer计时器并设置挂钩以在发出新证书的情况下重新启动Strongswan。为此,可以在/ etc / letsencrypt / renewal-hooks / deploy /中放置一个简单的bash脚本,或者再次编辑/ etc / sysconfig / certbot文件。

我们重新启动Strongswan,在iptables中开启对10.1.1.0/24网络的伪装,然后继续配置移动设备。

安卓系统


从Google Play安装Strongswan应用程序

我们启动并创建一个新的

轮廓


我们保存了个人资料并连接,一秒钟后,我们不必担心有人会监视我们。

我们检查:
sudo strongswan statusall
Security Associations (3 up, 0 connecting):
remote-access[109]: ESTABLISHED 2 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{269}:  INSTALLED, TUNNEL, reqid 55, ESP in UDP SPIs: c706edd1_i e5c12f1d_o
remote-access{269}:   0.0.0.0/0 ::/0 === 10.1.1.1/32
        mama[101]: ESTABLISHED 34 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{265}:  INSTALLED, TUNNEL, reqid 53, ESP in UDP SPIs: c8c83342_i c51309db_o
        mama{265}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
    keenetic[99]: ESTABLISHED 36 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{263}:  INSTALLED, TUNNEL, reqid 52, ESP SPIs: c3308f33_i c929d6f1_o
    keenetic{263}:   10.0.0.0/23 === 10.0.4.0/24


视窗


当前版本的Windows令人惊讶。通过调用两个PowerShell cmdlet对新VPN进行所有配置:

Add-VpnConnection -Name "IKEv2" -ServerAddress ipsecgw.example.com -TunnelType "IKEv2"
Set-VpnConnectionIPsecConfiguration -ConnectionName "IKEv2" -AuthenticationTransformConstants SHA256128 -CipherTransformConstants AES128 -EncryptionMethod AES128 -IntegrityCheckMethod SHA256 -PfsGroup PFS2048 -DHGroup Group14 -PassThru -Force

还有一件事,如果将Strongswan配置为向客户端发布IPv6地址(是的,他也可以这样做):

Add-VpnConnectionRoute -ConnectionName "IKEv2" -DestinationPrefix "2000::/3"

第四部分,决赛。我们开了通往欧洲的窗户


看到提供者的存根“该站点因博格扎比县特鲁多耶·莫佐利村的第五副检察官的左脚脚跟的决定而被封锁”,一个小的,不起眼的VPS出现了(域名很好,域名为rkn.example.com),距喜欢用长锤和大小不一的网络波动的猴子一千公里。 /一次16。 NIC.CZ上名为BIRD的同事们创造了这个小型VPS。第一版的鸟因警棍活动而不断死于恐慌,猴子在劳动活动的高峰期禁止近4%的互联网访问,因此在重新配置过程中需要深思熟虑,因此将其更新为2.0.7版。如果读者感兴趣,我将发表一篇有关从BIRD过渡到BIRD2的文章,其中配置格式发生了巨大变化,但是新版本变得更快了,并且使用大量路由进行重新配置没有任何问题。并且由于我们使用动态路由协议,因此必须有一个网络接口,您需要通过该接口来路由流量。默认情况下,IPSec不会创建接口,但是由于其灵活性,我们可以使用经典的GRE隧道,将来我们将对其进行保护。作为奖励,ipsecgw.example.com和rkn.example.com主机将使用Lets Encrypt自我更新证书对彼此进行身份验证。没有PSK,只有证书,只有核心,没有太多的安全性。默认情况下,IPSec不会创建接口,但是由于其灵活性,我们可以使用经典的GRE隧道,将来我们将对其进行保护。作为奖励,ipsecgw.example.com和rkn.example.com主机将使用Lets Encrypt自我更新证书对彼此进行身份验证。没有PSK,只有证书,只有核心,没有太多的安全性。默认情况下,IPSec不会创建接口,但是由于其灵活性,我们可以使用经典的GRE隧道,将来我们将对其进行保护。作为奖励,ipsecgw.example.com和rkn.example.com主机将使用Lets Encrypt自我更新证书对彼此进行身份验证。没有PSK,只有证书,只有核心,没有太多的安全性。

我们认为已经准备好VPS,已经安装了Strongswan和Certbot。

在ipsecgw.example.com主机(其IP为1.1.1.1)上,我们描述了新的gif0接口:
sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="1.1.1.1"
PEER_OUTER_IPADDR="5.5.5.5"
MY_INNER_IPADDR="10.255.255.1/30"
PEER_INNER_IPADDR="10.255.255.2/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

在主机vps.example.com上镜像(其IP为5.5.5.5):

sudo vi /etc/sysconfig/network-scripts/ifcfg-gif0
DEVICE="gif0"
MY_OUTER_IPADDR="5.5.5.5"
PEER_OUTER_IPADDR="1.1.1.1"
MY_INNER_IPADDR="10.255.255.2/30"
PEER_INNER_IPADDR="10.255.255.1/30"
TYPE="GRE"
TTL="64"
MTU="1442"
ONBOOT="yes"

我们提出了接口,但是由于iptables没有允许GRE协议的规则,因此流量不会消失(这是我们所需要的,因为GRE内部没有针对任何立法“程序包”的支持者的保护措施)。

烹饪VPS


首先,我们获得另一个域名rkn.example.com的证书。如上一节所述,在/etc/strongswan/ipsec.d中创建符号链接。

通过向其添加一行来编辑ipsec.secrets:

rkn.example.com     : RSA key.pem

编辑ipsec.conf:

config setup
    charondebug = "dmn 0, mgr 0, ike 0, chd 0, job 0, cfg 0, knl 0, net 0, asn 0, enc 0, lib 0, esp 0, tls 0, tnc 0, imc 0, imv 0, pts 0"
    strictcrlpolicy = yes
conn %default
    reauth = yes
    rekey = yes
    keyingtries = %forever
    keyexchange = ikev2
    dpdaction = restart
    dpddelay = 5s
    mobike = yes
conn rkn
    left = %defaultroute
    right = ipsecgw.example.com
    authby = pubkey
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    leftid = "CN=rkn.example.com"
    rightid = "CN=ipsecgw.example.com"
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route

在主机端,还将在设置部分的strictcrlpolicy = yes参数中将ipsecgw.example.com添加到ipsec.conf,其中包括严格的CRL检查。并描述另一个连接:

conn rkn
    left = %defaultroute
    right = rkn.example.com
    leftcert = fullchain.pem
    leftsendcert = always
    leftauth = pubkey
    rightauth = pubkey
    rightrsasigkey = /etc/strongswan/ipsec.d/certs/rkn.exapmle.com.pem
    leftid = "CN=ipsecgw.example.com"
    rightid = "CN=rkn.example.com"
    leftsubnet = %dynamic
    rightsubnet = %dynamic
    type = transport
    ike = aes256gcm16-sha384-x25519!
    esp = aes256gcm16-sha384-x25519!
    auto = route
    dpdaction = restart

配置几乎是镜像的。细心的读者可能已经注意到了以下几点:

  • left / rightsubnet =%动态-指示Strongswan对对等体之间的所有流量类型应用策略
  • rightrsasigkey. IKE SA IKE AUTH ERROR , Strongswan RSA- . openssl. (ipsecgw RKN) sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > ~/ipsecgw.example.com.pem sudo /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > ~/rkn.example.com.pem, scp ,

不要忘记配置防火墙和自动更新证书。在两台服务器上重新启动Strongswan后,开始对GRE隧道的另一端执行ping操作,并看到成功的连接。在VPS(rkn)上:

sudo strongswan status
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   5.5.5.5/32 === 1.1.1.1/32
Security Associations (1 up, 0 connecting):
         rkn[33]: ESTABLISHED 79 minutes ago, 5.5.5.5[CN=rkn.example.com]...1.1.1.1[CN=ipsecgw.example.com]
         rkn{83}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: cb4bc3bb_i c4c35a5a_o
         rkn{83}:   5.5.5.5/32 === 1.1.1.1/32


在主机端ipsecgw
在扰流板下
Routed Connections:
         rkn{1}:  ROUTED, TRANSPORT, reqid 1
         rkn{1}:   1.1.1.1/32 === 5.5.5.5/32
Security Associations (4 up, 0 connecting):
remote-access[10]: ESTABLISHED 5 seconds ago, 1.1.1.1[CN=ipsecgw.example.com]...4.4.4.4[phone]
remote-access{12}:  INSTALLED, TUNNEL, reqid 7, ESP in UDP SPIs: c7a31be1_i a231904e_o
remote-access{12}:   0.0.0.0/0 === 10.1.1.1/32
    keenetic[8]: ESTABLISHED 22 minutes ago, 1.1.1.1[keenetic@router.home.local]...3.3.3.3[root@router.keenetic.local]
    keenetic{11}:  INSTALLED, TUNNEL, reqid 6, ESP SPIs: cfc1b329_i c01e1b6e_o
    keenetic{11}:   10.0.0.0/23 === 10.0.4.0/24
        mama[4]: ESTABLISHED 83 minutes ago, 1.1.1.1[mama@router.home.local]...2.2.2.2[root@router.mama.local]
        mama{8}:  INSTALLED, TUNNEL, reqid 3, ESP in UDP SPIs: c4a5451a_i ca67c223_o
        mama{8}:   10.0.0.0/23 10.1.1.0/24 === 10.0.3.0/24
         rkn[3]: ESTABLISHED 83 minutes ago, 1.1.1.1[CN=ipsecgw.example.com]...5.5.5.5[CN=rkn.example.com]
         rkn{7}:  INSTALLED, TRANSPORT, reqid 1, ESP SPIs: c4c35a5a_i cb4bc3bb_o
         rkn{7}:   1.1.1.1/32 === 5.5.5.5/32


通道已安装,可以ping通,在tcpdump中可以看到主机之间只有ESP。似乎很高兴。但是,如果不检查所有内容,您将无法放松。我们正在尝试重新签发VPS证书并...

厨师都坏了


我们开始理解并偶然发现Let's Encrypt的一项令人不快的功能,该功能在其他所有功能中都很漂亮-随证书的任何重新发行,与之相关的私钥也会更改。私钥已更改-公钥已更改。乍一看,这种情况对我们来说是无望的:即使我们可以使用certbot中的钩子在重新颁发证书的过程中轻松提取公钥并通过SSH将其传递给远程端,也不清楚如何使远程Strongswan重新读取它。但是帮助来自他们没有等待的地方-systemd可以监视对文件系统的更改并运行与事件关联的服务。这就是我们将要使用的。

我们将在权限最受限制的每个主机上创建一个keywatcher服务用户,为每个主机生成SSH密钥,并在主机之间交换它们。

在ipsecgw.example.com主机上,创建/ opt / ipsec-pubkey目录,在其中放置2个脚本。

sudo vi /opt/ipsec-pubkey/pubkey-copy.sh

#!/bin/sh
if [ ! -f /home/keywatcher/ipsecgw.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/ipsecgw.example.com/privkey.pem -pubout > /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/ipsecgw.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/ipsecgw.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/ipsecgw.example.com.pem rkn.example.com:/home/keywatcher/ipsecgw.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/ipsecgw.example.com.pem;
    logger "Public key ipsecgw.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key ipsecgw.example.com.pem has not been uploaded to remote host due to error";
  fi
  else
    logger "Public key ipsecgw.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh

#!/bin/sh
/usr/bin/cp /home/keywatcher/rkn.example.com.pem /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/rkn.example.com.pem
logger "Public key of server rkn.example.com has been updated, restarting strongswan daemon to re-read it"
/usr/bin/systemctl restart strongswan
exit 0

在VPS(主机rkn.example.com)上,我们类似地创建一个具有相同名称的目录,在该目录中,我们还创建了相似的脚本,仅更改了密钥的名称。代码,以免使文章混乱

扰流板
须藤vi /opt/ipsec-pubkey/pubkey-copy.sh
#!/bin/sh
if [ ! -f /home/keywatcher/rkn.example.com.pem ]; then
  /usr/bin/openssl rsa -in /etc/letsencrypt/live/rkn.example.com/privkey.pem -pubout > /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chown keywatcher:keywatcher /home/keywatcher/rkn.example.com.pem;
  /usr/bin/chmod 0600 /home/keywatcher/rkn.example.com.pem;
  sudo -u keywatcher /usr/bin/scp /home/keywatcher/rkn.example.com.pem ipsecgw.example.com:/home/keywatcher/rkn.example.com.pem;
  status=$?;
  if [ $status -eq 0 ]; then
    rm -f /home/keywatcher/rkn.example.com.pem;
    logger "Public key rkn.example.com.pem has been successfully uploaded to remote host";
  else
    logger "Public key rkn.example.com.pem has not been uploaded to remote host";
  fi
  else
    logger "Public key rkn.example.com.pem already exist on /home/keywatcher directory, something went wrong";
fi
exit 0

sudo vi /opt/ipsec-pubkey/key-updater.sh


#!/bin/bash
/usr/bin/cp /home/keywatcher/ipsecgw.example.com.pem /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem;
/usr/bin/chown root:root /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
/usr/bin/chmod 0600 /etc/strongswan/ipsec.d/certs/ipsecgw.example.com.pem
logger "Public key of server ipsecgw.example.com has been updated, restarting connection"
/usr/bin/systemctl restart strongswan
exit 0


需要pubkey-copy.sh脚本来提取密钥的公共部分,并在颁发新证书时将其复制到远程主机。为此,请在两台服务器上的/ etc / letsencrypt / renewal-hooks / deploy目录中,创建另一个微脚本:


#!/bin/sh
/opt/ipsec-pubkey/pubkey-copy.sh > /dev/null 2>&1
/usr/bin/systemctl restart strongswan
exit 0

解决了一半问题,重新颁发了证书,提取了公钥并在服务器之间进行了复制,现在已经有了使用路径单元进行systemd的时间。

在/ etc / systemd / system目录中的ipsecgw.example.com服务器上,创建keyupdater.path文件。

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/rkn.example.com.pem
[Install]
WantedBy=multi-user.target

同样在VPS主机上:

[Unit]
Wants=strongswan.service
[Path]
PathChanged=/home/keywatcher/ipsecgw.example.com.pem
[Install]
WantedBy=multi-user.target

最后,在每台服务器上,我们都创建一个与此单元关联的服务,该服务将在满足条件(PathChanged)时启动-更改文件并在记录后关闭它。我们创建文件/etc/systemd/system/keyupdater.service并编写:

[Unit]
Description= Starts the IPSec key updating script
Documentation= man:systemd.service
[Service]
Type=oneshot
ExecStart=/opt/ipsec-pubkey/key-updater.sh
[Install]
WantedBy=multi-user.target

不要忘记使用sudo systemctl daemon-reload重新读取systemd配置,并通过sudo systemctl enable keyupdater.path && sudo systemctl start keyupdater将自动启动分配给路径单元。

一旦远程主机将包含公共密钥的文件写入keywatcher用户主目录,并且文件描述符关闭,systemd将自动启动相应的服务,该服务会将密钥复制到所需位置并重新启动Strongswan。隧道将使用第二侧的正确公共密钥进行安装。

您可以呼气并欣赏结果。

而不是结论


正如我们刚才看到的地狱 IPSec是不是可怕,因为它是画。已描述的全部是当前正在使用的完全可操作的配置。即使没有很多知识,您也可以配置VPN并可靠地保护数据。

当然,设置iptables的时间仍然不在本文讨论的范围之内,但是文章本身已经足够多了,关于iptables的文章也很多。

文章中有几点可以改进,因为它拒绝重新启动Strongswan守护程序,重新读取其配置和证书,但我无法实现。

但是,守护进程的重启并不可怕:对等端之间一两个ping丢失,移动客户端自行恢复连接。

希望评论中的同事会提示正确的解决方案。

All Articles