Giblets IPsec,我们针对TLS 1.3,GOST和Go进行了测量

问候!我想给大家介绍一下现代的设备的IPsec堆栈ESPv3IKEv2的协议在我看来,IPsec无可避免地绕过了许多方面,而且我还没有看到对它的工作,协议和俄语能力的详细分析。另外,我会做一些奇怪的事情-将IPsec ESPv3IKEv2(均为2005年)与2018年最新的,时髦的,最新的TLS 1.3进行比较





为什么我对IPsec如此充满热情-可以说是用于保护网络的最复杂的协议栈?毕竟,复杂性是可靠性和安全性的主要敌人!首先,与开发人员通常的“拐杖驱动拐杖”和解决严重问题(直到雷声爆发)的解决方案形成鲜明对比的是,您对它的协议(尤其是IKEv2)了解得越多,就越了解它的可能性,并且对它的周到印象深刻。其次,从加密的角度考虑了IPsec协议,实际上,即使是旧的ESP / IKEv1,也是唯一没有严重漏洞的工业上广泛使用的协议。相同的SSL(1995)仅在版本1.3中才被考虑在内。由于IKEv1的复杂性,许多人不喜欢IPsec,在v2中不再存在。



理想情况下,如果操作系统的开发人员在IPsec和IPv6的实现和实现上不放慢时间(因为计算机的可用性,因此没有NAT),那么原则上就不会出现SSL / TLS。事实证明这并不是一个完美的世界,但是现在开箱即用的IPsec(至少是堆栈中的SA / SP + ESP)在任何至少广泛使用的操作系统中(我个人只知道DragonFly BSD,由于缺少开发人员来支持它,所以喝了IPsec),在某些发达国家,IPv6可以立即供绝大多数人使用。



IPsec是协议,API调用,框架的堆栈,以便应用程序和/或管理员可以告知他们在通信过程中需要什么安全性,并且可以在网络级别上透明地确保它(IP security)。我们可以讨论仅一个套接字的IP数据包(例如TCP连接),也可以讨论整个网络之间的流量。



流量安全性意味着:确保数据机密性,数据的真实性/完整性并防止重放攻击像几乎所有协议一样,IPsec具有保护IP数据包的传输部分,以及与密钥,参数,各方的配置和身份验证有关的握手部分。



TLS 1.3:仅为TCP连接提供每个套接字的数据保护。DTLS可以为数据报提供保护(DTLS 1.3还不是标准),但是并非每个库都支持此功能。



运输协议



IPsec传输使用IP协议:



  • AH(身份验证标头)。我不会再进一步​​讨论AH,因为它不提供数据机密性,据我所知,它只是以某种方式“加入”了1990年代一些国家关于限制使用加密的法律。加密相对于其他所有东西都是轻量级的,因此牺牲它是没有意义的。但是几乎所有提到ESP的地方,AH的意思也是如此。
  • ESP(封装安全性有效载荷)。ESP随时间推移略有发展,现在使用其ESPv3版本,该版本通常是向后兼容的,与以前的版本没有什么不同。


IP流量仅由传输层保护。而且,由于我们每秒可以谈论数百万个数据包,因此实际上,ESP至少在操作系统的内核级别(在其网络堆栈中)实现,以免在内核和用户空间之间进行昂贵的上下文切换(这通常在TLS中发生) ,SSH,OpenVPN等)。



我强调AH和ESP是IP层协议,网络,而不是传输。为什么不使用UDP?校验和是多余的,会烧毁CPU,而加密技术无论如何都会确保完整性。但是,如果您的NAT对ESP一无所知(他也不知道),那么所有这些对他都不起作用。后来他们想出了NAT-T拐杖 (NAT穿越),当IPsec流量被封装在端口4500上的UDP数据包中并且能够通过NAT时,但这是不必要的开销,并且需要在内核中编辑IPsec堆栈,因为它应该已经了解了这些特殊的UDP数据包并为其提取ESP定期处理。



SP,SA,SPI和我们的首个IPsec加密



内核如何知道如何处理IP数据包:是使用某些密钥对其进行加密,解密传入的ESP,还是让其通过而不接触它?为此,内核具有安全策略(SP)。这些规则就像在防火墙中一样。除了它们之外,核心还包含安全关联(SA):用于执行加密操作(密钥,计数器,窗口重播等)的上下文。通常,SP既不是特定于IPsec的,也不是SA的-它们可用于其他任务/协议(例如OSPF)。



可以通过特殊的API(PF_KEYv2)或通过一些setkey实用程序手动配置SP / SA 。例如,如果我们要告诉内核所有IP数据包来自必须通过ESP保护fc :: 321上的fc :: 123地址,然后可以通过在命令行中调用来轻松实现:



$ echo "spdadd fc00::123 fc00::321 any -P out ipsec esp/transport//require;" | setkey -c


在执行此命令之前,我们看到了ping命令:



IP6 fc00::123 > fc00::321: ICMP6, echo request, seq 0, length 16
IP6 fc00::321 > fc00::123: ICMP6, echo reply, seq 0, length 16
IP6 fc00::123 > fc00::321: ICMP6, echo request, seq 1, length 16
IP6 fc00::321 > fc00::123: ICMP6, echo reply, seq 1, length 16


稍后我们将不会看到它,因为内核尚不知道要加密的“内容”。您需要添加SA,​​这也可以手动完成,设置AEAD加密算法和一个随机的160位密钥以简化AES-GCM-16



echo "add fc00::123 fc00::321 esp 0xdeadbabe -E aes-gcm-16 0x0c09d1d90f804b0b4cef80e255e29c0894db1928 ;" | setkey -c


如果我们在远程主机上执行相同的命令(只是不要忘记在中指定-P),我们将看到:



IP6 fc00::123 > fc00::321: ESP(spi=0xdeadbabe,seq=0x1), length 52
IP6 fc00::321 > fc00::123: ICMP6, echo reply, seq 0, length 16
IP6 fc00::123 > fc00::321: ESP(spi=0xdeadbabe,seq=0x2), length 52
IP6 fc00::321 > fc00::123: ICMP6, echo reply, seq 1, length 16


请求由ESP加密,但回复未加密。由于ESP默认情况下以“一种方式”工作并且用于双向通讯,因此有必要为相反的方向添加另一个SP / SA。在此示例中,



0xdeadbabe是安全参数索引(SPI)-两个IP地址之间的ESP“隧道”的唯一标识符,内核可以在该IP地址处找到相应的SA上下文并从中获取解密密钥。ESP /运输//要求是在传输模式下使用ESP(更多的下面)的要求。



Giblets ESP



ESP软件包的结构如下:



  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---
|               Security Parameters Index (SPI)                 | ^
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | A
|                      Sequence Number                          | | u
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | t
~                       IV (variable)                           ~ | h
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | e -----
|                    Payload Data  (variable)                   | | n   ^ E
~                                                               ~ | t   | n
|                                                               | | i   | c
+               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | c   | r
|               |         TFC Padding * (optional, variable)    | | a   | y
+-+-+-+-+-+-+-+-+         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | t   | p
|                         |        Padding (0-255 bytes)        | | e   | t
+-+-+-+-+-+-+-+-+-+-+-+-+-+     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | d   | e
|                               |  Pad Length   | Next Header   | v     v d
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ---------
~         Integrity Check Value-ICV   (variable)                ~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


  • SPI -ESP会话/隧道/ IP地址之间的连接的32位唯一标识符。通常,{SrcIP,DstIP,SPI}是SA和加密上下文。
  • SeqNum — 32- . . , replay attack.
  • payload — ESP, .
  • TFC padding — (Traffic Flow Confidentiality), , - , . TFC , , payload , . , payload IP , . TFC - , .
  • Padding — ESP payload 32- , . , ( CBC) . . .
  • Pad Length — 8- Padding .
  • Next Header — 8- IP payload. «no next header», ESP- — , . TFC — .
  • ICV — Integrity Check Value, (MAC).


有效负载下一个报头的数据包的整个部分都加密。除MAC之外的所有内容均已通过身份验证。 ICV的长度,是否存在IV(初始化向量)取决于所使用的加密和认证模式/算法。



TLS 1.3:仅在1.3版中出现了将数据填充到给定大小的可选操作。否则,加密和身份验证完全相似。 TLS 1.3只能使用正确且良好的AEAD算法。 ESP支持AEAD,但是可以选择更多的古老解决方案。类型字段SPISeqNum否,因为TCP保证顺序和传递,此外,实际上,没有显式传输初始化矢量-TLS记录层数据包因此略短。 DTLS已经包含SeqNum以及消息分段数据。



实际上,32位数据包的数量可能太短。这只是4+十亿个IP数据包,以10+ Mpps的速度可以在数分钟内飞行。计数器溢出时会发生什么?它将重置为零。但是,这意味着SPI + SeqNum的值将开始为我们重复,并且先前截获的ESP数据包可用于重放攻击。为了解决这个问题,发明了ESN(扩展序列号)。这是一个64位计数器,但是只有其中的“低” 32位传输到SeqNum字段,而高32位存储在内存中。ESN的全部价值都经过验证-因此,各方有义务事先同意使用ESN。



ESP加密



例如,在使用AES-GCM-16时,ESP数据包的加密/身份验证是如何进行的?要与ESP一起使用,它使用位于有效负载开头的64位初始化向量。它还使用32位盐作为密钥材料的一部分。在setkey的示例中我没有提供128位密钥,而是提供了128 + 32位密钥。在某些情况下,密钥会被重用,并且IV会填充错误的伪随机数生成器(PRNG),其值可以重复。盐旨在防止这种最危险的情况发生,这种潜在情况可能导致对截获的数据包进行解密。 AES-128-GCM-16-ESP模式下的ESP加密/认证本身如下:



AES-GCM(
    key             = 128-bit key,
    plaintext       = 64-bit IV || payload || TFC || pad || padLen || NH,
    nonce           = 32-bit salt || IV,
    associated-data = SPI || {ESN  SeqNum},
) -> encrypted-payload || 128-bit ICV

ESP = SPI || SeqNum || IV || encrypted-payload || ICV


对于俄罗斯的GOST算法(岩浆或Grasshopper密码),输入数据相似。两种密码都在MGM模式下使用(我会说是GCM的改进版本),并且使用HMAC-Stribog-256进行常规的ESPTREE密钥材料旋转。这样可以减轻按键的负担。主要是在IPsec的上下文中,这并没有增加其使用时间,而是减少了通过侧通道的攻击面。例如,由于密钥网格划分(一种类似的恒定密钥旋转技术),结果证明具有64位块大小的GOST 28147-89块密码不受SWEET32攻击。



从安全角度来看,对于使用AEAD算法的ESP并没有抱怨。但是对于AEAD算法,I​​V只是一个64位计数器,与每个数据包一起显式传递,这浪费了数据包中的空间。SeqNum太短,并且ESN不能完全传输,尽管它完全可以作为IV。对于非AEAD算法,I​​V可能已经是必需的并且具有不可预测的值,但绝不是计数器。这是传统,要消耗掉包装中的宝贵空间并且重量不会影响此处的可靠性。







如果AEAD的IV可以具有128位的值,那么可以使用具有192位随机数的XSalsa20 / XChaCha20之类的算法,其中128位是在启动时伪随机生成的,其余的64位可以用作计数器... 对于丢失了计数器状态但想继续使用现有密钥的系统来说,这可能是一个救命稻草。



TLS 1.3:XOR用作消息计数器和使用密钥生成的初始化向量之间的随机数。由于仪表和IV均未明确传输,因此TLS 1.3更加紧凑。如果ESP使用非AEAD算法,则它们可能需要生成不可预测的IV,这可能会占用大量CPU。



隧道和运输方式



包裹有效载荷中包含什么?这取决于ESP是在传输模式还是隧道模式下运行传输模式使用具有此有效负载的ESP替换已传输IP数据包的有效负载。也就是说,它是:



---------------------------------------
| orig IP hdr |[ext hdrs]| TCP | Data |
---------------------------------------


成为:



---------------------------------------------------------
| orig |hop-by-hop,dest*,|   |dest|   |    | ESP   | ESP|
|IP hdr|routing,fragment.|ESP|opt*|TCP|Data|Trailer| ICV|
---------------------------------------------------------
                             |<--- encryption ---->|
                         |<---- authenticity ----->|


在隧道模式下,整个IP数据包完全封装在ESP中,并且通常会使用新的标头和SrcIP / DstIP地址来形成一个新的IP数据包。此模式用于在网络之间建立数据包隧道。



----------------------------------------------------------
| new* |new ext|   | orig*|orig ext|   |    | ESP   | ESP|
|IP hdr| hdrs* |ESP|IP hdr| hdrs * |TCP|Data|Trailer| ICV|
----------------------------------------------------------
                   |<--------- encryption --------->|
               |<---------- authenticity ---------->|


例如,通过设置setkey我可以指定之间的所有数据包2001:AC :: / 642001:直流:: / 64网络应该通过隧道的两个端点与地址通过加密2001 :: 1232001 :: 321 ...



spdadd 2001:ac::/64 2001:dc::/64 any -P out ipsec esp/tunnel/2001::123-2001::321/require ;
spdadd 2001:dc::/64 2001:ac::/64 any -P in  ipsec esp/tunnel/2001::321-2001::123/require ;


传输模式通常称为主机到主机连接。如果某些GRE或IPv * -over-IPv *协议用于隧道传输,而该协议已经在两个端点之间运行,则在这种情况下,在IPsec级别上使用隧道模式是没有意义的。但是,传输模式不会验证IP标头。通常,这并不重要,也不重要,但是,如果要确保未更改扩展的IPv6标头或数据包的流标签,则即使在两个主机之间,也应使用隧道模式,但这样做会增加开销。



ISAMP



如果我重新启动计算机,SA的所有计数器值都从它们的内存中消失,然后再次用双手加载旧的SP / SA命令会怎样?首先,与IV匹配的数据包可以被解密,因为这等同于两次使用密码垫。其次,由于SPI / salt / ESN / SeqNum匹配,因此所有先前拦截的数据包都将得到有效的身份验证,您可以重播它们。重复使用此类setkey SA对于安全性而言是灾难性的。第三,特别是如果不使用ESN(例如,在撰写本文时在FreeBSD中,尚不支持ESN),并且SA操作较长,则您可能不会注意到计数器已“用完”。



所有这些意味着我们需要定期更改ESP密钥。并且还协商加密算法,ESN,TFC,传输/隧道模式,SPI值的存在。实际上,为此使用了ISAKMP协议(Internet安全协会和密钥管理协议)。虽然,您可以轻松地使用OTR / PGP / OMEMO身份验证加密来加密某些IM,然后只需将Shell脚本setkey命令发送到服务器,该服务器通过读取/ dev / urandom生成密钥。内核如何达成协议并不重要。与OpenVPN一样:具有证书和密钥协商的X.509身份验证通常通过TLS进行,并且VPN传输协议本身已经是它自己的了。



ISAKMP的格式为“纯”,因为其中没有加密。为了对对话者进行身份验证并生成密钥材料,使用了将ISAKMP封装在自身内部的第三方协议。我知道:



  • KINK -键的使用Kerberos的网络谈判,其中第三个值得信赖的Kerberos KDC用于身份验证和谈判。除了来自Wikipedia的描述之外,我对KINK一无所知,也没有看到它的现场直播。
  • IKE(v1)-Internet密钥交换即使它是1998年创建的,它仍然可能是最受欢迎的协议。
  • IKEv2是2005年的第二个IKE版本。


由于存在大量不同的有效负载类型,因此IKE协议非常可扩展。 IKEv1具有大量选项,仅配置一个隧道即可工作。十几个RFC描述了带有公共有效负载的一堆ISAKMP和IKEv1。令人生畏的复杂性。加上能够轻松搞乱非安全配置的能力,以及众所周知的IKEv1只有在几乎完全复制配置文件的情况下才能工作的神话,这是当之无愧的。



幸运的是,IKEv2出现了:一个方便的RFC(针对大多数功能),一种显着简化的协议(用于协商参数及其配置)的协议。通常,与IKEv1相比,它在整个握手和密钥协商过程中的往返次数要少。因此,将只考虑它,因为IKEv1不再具有任何意义(但是,由于它们已经起作用,因此几乎不值得追求替换已经运行并正在运行的实例)。与IKEv1不同,IKEv2使用绝对相似的算法和方法来像ESP一样加密自己的消息。它还引入了EAP身份验证以及各方使用不同方法进行身份验证的能力(例如,客户端使用PSK,而X.509服务器使用证书)。



IKE守护程序



      +-------------+
      |  |
      +-------------+
       |           |
       |           |
       |           |      /userspace
=====[PF_KEY]====[PF_INET]====================
       |           |                    
+-----------+   +-------------+
| |   |TCP/IP,      |
|  SA  SP  |---| IPsec|
+-----------+   +-------------+
                     |
                 +-----------+
                 |    |
                 |  |
                 +-----------+


IPsec堆栈的这一部分已经在用户空间中运行。首先,它们不是高负载的守护程序:它们可以每天至少相互通信一次,并且初始握手需要通过UDP进行几次往返。其次,ISAKMP / IKE功能的数量要比完整的SA / SP / ESP实现中的代码多数百倍。 ISAKMP守护程序的实现方式很多:strongSwan(IKEv1 / v2)(以及OpenswanLibreswan),isakmpd(IKEv1),OpenIKED(IKEv2),racoon(IKEv1),racoon2(IKEv1 / v2,KINK)等。



注意:正确编写和说出“ Daemons»(daemons),就像我在小说翻译中看到的那样。但是在讲俄语的技术圈中,“恶魔”已经扎根。



TLS 1.3:通常,整个TLS堆栈都是库函数,可在每个单独的应用程序中运行并将密钥材料存储在其自己的内存中。所有加密都是通过切换到用户空间来完成的,这是巨大的开销。但是,至少当FreeBSD和Linux已经具有TLS的内核卸载实现时,类似于IPsec,当传输部分完全在内核中处理,并且握手发生在用户空间中时。



IKEv2在默认情况下在端口500(isakmp服务)。守护程序创建安全通道,相互认证,协商/创建/删除ESP SA / SP,更新密钥,执行心跳(Dead Peer Detection(DPD))等。守护程序之间的所有通信都以一对请求/响应消息交换的形式进行。任何要求都必须得到答复。由于这是UDP,如果丢包了怎么办?在您的状态下考虑这一点,在没有收到响应的超时后重新发送请求,对重复的请求重新发送响应,忽略重复的响应。数据包可能以混乱的顺序到达,它们可能会意外地消失-IKEv2标准中考虑了很多,并描述了如何在各种竞争条件下表现。



TLS 1.3注意:TLS的TCP性质负责消息的顺序和传递。但是TCP在OS内核中占用了大量资源,并且大量的TCP会话可能是一个问题(与UDP不同)。但是在DTLS中,所有类似的问题都将以与IKE中相同的方式出现,并且将添加具有处理碎片消息的痔疮。更改UDP端点的IP地址不是问题。通常,IKE连接的寿命很长(IKE状态很小,并且仅存储在用户空间守护程序的内存中),因此需要较少的握手,而在TLS中,丢失TCP连接后,您就必须这样做(尽管如果状态不是这种状态,还有加速会话继续的方法)丢失,例如重新启动程序时)。由于IKE守护程序是整个系统的守护程序(通常),因此如果某些应用程序想要与之安全地通信,与已经有IKE连接的某人联系,那么他可以立即使用它,或者守护程序在一次往返中为该应用程序创建一个附加的ESP SA。



Giblets IKE



守护程序的第一个交换(请求-响应)将是IKE_SA_INIT,这将创建IKE SA以进行进一步的安全通信。请注意,ESP SA是“存储”在内核中,而IKE SA是在用户空间守护程序中。然后是IKE_AUTH交换,在此对各方进行身份验证。在同一交换中,创建了子SA(子SA,该子SA用于ESP SA。通常,这两个交换足以验证各方并使用密钥协商ESP SA参数,然后在计算机之间驱动加密的ESP通信。在这种情况下,正常运行的IKE SA会在守护程序之间保留很长时间。此外,他们可以随时进行CREATE_CHILD_SA交换,以创建更多子SA,以及INFORMATIONAL交换(各种目的)。



所有IKEv2消息头均具有以下结构:



                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       IKE SA Initiator's SPI                  |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       IKE SA Responder's SPI                  |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Next Payload |    Version    | Exchange Type |     Flags     |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                          Message ID                           |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Length                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


  • SPIi -64位IKE SA发起方SPI。由IKE会话的发起者随机生成的标识符。
  • SPIr -64位IKE SA响应器SPI。同样,但只有来自响应方的SPI。在来自发起方的第一条消息中,该字段填充了零字节。
  • NP -8位下一个有效载荷。标头后的有效负载标识符。
  • 版本-IKE协议的8位版本。
  • ExchType -IKE交换的8位类型:IKE_SA_INITIKE_AUTHCREATE_CHILD_SAINFORMATIONAL
  • Flags — 8- . .
  • MsgID — 32- . , , replay-. — request/response MsgID. , .
  • Len — 32- ( + ).


SPIi + SPIr为128位。当ESP仅分配32位时,为什么要这么多呢?首先,由于它们不匹配,而是伪随机生成的,因此一侧的64位将足以避免冲突。其次,ESP也绑定到IP地址,而IKE会话通常不绑定-各方可以轻松更改其IP地址(移动客户端)并继续进行通信。



TLS 1.3:更改IP地址将断开连接。即使使用iPSK,您也需要进行重新握手,以节省非对称密码的资源,这是1.5次往返以及建立TCP连接的往返。在已经建立的IKE连接(未绑定地址)中,在新IP地址上创建子ESP SA只需一次往返(+往返以删除旧的ESP SA,但这已经在新的有效ESP SA的背景下发生)。



IKE标头后跟一个或多个有效负载。每个有效载荷都有一个通用格式头,后跟特定于其类型的内容。内容是32位对齐的。通用的标头:



                     1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Payload  |C|  RESERVED   |         Payload Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


  • Next Payload — 8- . payload- . payload. payload IKE . Encrypted Payload, payload- NP ( payload IKE ), payload- .
  • C — «» payload. IKEv2 payload , IKE . payload . IKE vendor-specific , .
  • Len — 16- payload ( + ).


因此,IKE消息由IKE头和有效载荷组成,它们链接在一起。守护程序可以忽略非关键和未知的有效负载。Nonce类型的有效负载内容(在标头之后)只是一组随机数据,而不是固定大小。但是也有更复杂的结构。在IKE标准中,可接受有效载荷类型的简短指定(例如,对于随机数消息,为N *,其中“ *”为“ i”(发起者)或“ r”(响应者)。



适马



从加密角度来看,IKEv1 / IKEv2属于STS,ISO / IEC IS 9798-3和SIGMA(SIGn和MAc)认证密钥交换协议类。这些都是经过充分研究和数学验证(SIGMA)的解决方案。在我的“一个晚上的P2P F2F E2EE IM”文章中,我已经描述了SIGMA-I协议的操作和实现原理。IKEv2完全相似。当我们讨论握手协议的安全性时,我们期望什么?



  • 传输消息的机密性;
  • 传输消息的真实性和完整性-必须检测其更改;
  • 防止重放攻击-必须检测消息丢失或重放的事实;
  • ;

    perfect forward secrecy (PFS) — PSK ( IKE ESP SA). ;

    / ( ) IKE . / ( ) ;

    , , . .



在进行这样的IKE_SA_INIT交换之后,守护进程具有彼此的地址,即SPIi + SPIr IKE会话值,SA协商的算法(对于IKE,它们是密钥协商(DH),消息加密/认证(ENCR),密钥生成(PRF算法),另一侧的公钥(DH)。这足以将状态保存在内存中并执行密钥协商(Diffie-Hellman,GOST R 34.10-VKO,curve25519等),生成对称密钥以加密后续IKE消息的有效负载。



TLS 1.3:握手消息的格式非常不同,有很多遗留问题,但从根本上讲没有什么突出。使用随机字段代替随机数。除了有效载荷,还有许多扩展。代替复杂的SA提议结构,使用密码套件标识符,它更加紧凑和简单。我认为,SA提议的灵活性过高,但是在IKEv2中这仍然不是问题,并且与密码套件相似的值已写入配置文件中。只有使用TLS 1.3版本的DH交换才是强制性的。



IKE密钥材料



IKE_SA_INIT之后生成SKEYSEED

SKEYSEED = PRF(Ni [:8] || Nr [:8],DH-KEY)


在IKE SA中选择了PRF算法。例如,对于GOST IKEv2,这是HMAC-Stribog-512函数。 PRF密钥是每个随机数的64位块。



它看起来很琐碎,因为随机数是公开传输的,这意味着任何拦截流量的人都知道此PRF的密钥。但是PRF在这里专门用于根据DH计算DH-KEY结果生成密钥,攻击者已经不知道了。 DH函数的结果可能是巨大且不均匀的熵值,它可能是椭圆曲线上的一个点-所有这些都不能用作短的高熵对称密钥。因此,您需要DH-KEY(这只是SKEYSEED)中提取,然后展开(扩展到所需的键数:



PRF+(SKEYSEED, Ni || Nr || SPIi || SPIr) ->
    SK_d || SK_ai || SK_ar || SK_ei || SK_er || SK_pi || SK_pr

PRF+(K,S) = T1 || T2 || T3 || T4 || ...
T1 = PRF(K,       S || 0x01)
T2 = PRF(K, T1 || S || 0x02)
T3 = PRF(K, T2 || S || 0x03)
T4 = PRF(K, T3 || S || 0x04)


这是具有提取/扩展阶段的所有经典密钥派生操作,类似于HKDF函数。但是,如果HKDF假定使用哈希函数,则此PRF / PRF +结构可以简单地与对称密码一起使用-在常见的AES-GCM + AES-XCBC-PRF的情况下,我们根本不会在任何地方使用哈希函数,而是少量使用哈希函数使用的原语总是好的。



生成以下密钥:



  • SK_d键,用于为子ESP SA生成密钥。
  • IKE消息验证的SK_a [ir]键。如果同意AEAD算法(AES-GCM,Grasshopper / Magma-MGM,ChaCha20-Poly1305等),则不会生成/不使用。
  • SK_e[ir] IKE .
  • SK_p[ir] AUTH.


TLS 1.3:具有更复杂的密钥调度。熵立即从整个握手消息中挤出,而不是从单个字段中挤出。生成的扩展序列不仅被切成多个键(需要时用+盐表示),而且对于使用这些键或生成的IV的每种情况,还伴随有带有标签(标签)的HMAC转换。将文本标签/应用程序/上下文用于任何种类的生成值是一种很好的现代实践,并且比总是想知道是否需要它更容易实现。散列遇到的所有内容也是一种很好的做法,“它不会变得更糟”。但是,这并不意味着IKEv2的安全性更差,或者至少可以很容易地提出一种远程理论上的情况,即缺少标签可能在攻击者的手中。在IKEv2中,这种方法是最小的,而在TLS 1.3中,它是“更好的替代方法”(因为在该协议的早期版本中有多少门槛或困难!)。 IKEv2仍然使用经过验证的方法和原语,对所需的所有内容进行身份验证,压缩/考虑所有已传输的熵,并为每一面和任务使用不同的密钥。



IKE_AUTH



接下来,执行IKE_AUTH交换,认证双方并协商ESP SA:



    SK{IDi, [CERT, ...], [CERTREQ], [IDr], AUTH, SAi2, TSi, TSr} -->
<-- SK{IDr, [CERT, ...],                   AUTH, SAr2, TSi, TSr}


  • IKE消息包含一个加密的(SK)有效负载,所有其他有效负载都位于其中。
  • 发起方提供其标识符(IDi),认证方(AUTH),ESP的SA优惠(SAi2)和发起方/响应方对,即流量选择器(TS *)。它还可以选择发送预期的响应者标识符,该标识符可以视为来自TLS的一种SNI模拟。
  • 作为响应,它接收响应者的标识符,协商的ESP SA提议,经过验证的流量选择器和验证者。
  • 此后,双方都经过相互考虑,在ESP SA上达成协议,必须属于该ESP的流量,并且已经可以向内核发出命令以创建SA以及可能的SP(有些守护进程根本不处理SP)。


现在更详细地介绍这些有效负载:



  • ID-参与者标识符。包含标识类型和特定于它的数据。可以通过多种方式来识别参与方:IPv4 / IPv6地址,FQDN(全限定域名,只是字符串,是最流行的方式),RFC822电子邮件地址,ASN.1 DER专有名称(使用X.509证书时最常用的方式)或通用名称以及特定于供应商的信息。
  • AUTH — . PRF ( MAC-), (pre-shared key (PSK)), . (TBS*):



    TBSi = Msg0 || Nr || PRF(SK_pi, IDi)
    TBSr = Msg1 || Ni || PRF(SK_pr, IDr)
    


    (Msg0), nonce (Nr), (IDi), «» . , SK_pi ( ). «».



    / . . ( Ni Nr), . , , .



    , . ( ), . , - . round-trip-. SIGMA- , IKEv2, ESP SA, . , , . SIGMA MAC c ( SK_*). IKEv2 PRF, . , PRF(ID*) , brute-force ( ) .



    PSK, :



    AUTHi = PRF(PRF(PSK, "Key Pad for IKEv2"), TBSi)
    AUTHr = PRF(PRF(PSK, "Key Pad for IKEv2"), TBSr)
    


    PRF(PSK) PSK ? PSK PRF . PSK , /. PRF() «» . PRF(PSK) PSK PSK , ( Argon2, Balloon ).

  • SA*2 — SA , ESP .
  • TS* — . : IPv4/IPv6 , IP (), / (), / . :



    TSi = ((proto=17, port=100, fc::123 - fc::123),
           (proto=17, port=200, fc::123 - fc::123))
    TSr = ((proto=17, port=300, :: - ffff:..:ffff),
           (proto=17, port=400, :: - ffff:..:ffff))
    


    , UDP ( = 17), 100- 200- fc::123 , UDP 300 400. , IP . , , IP , ( , ICMP ). , .



    UDP . , , , 100 300-, ESP SA .



    响应方发送其确认的选择器选择,该选择器匹配或选择范围可能更窄。


第一次消息交换后,所有这些有效负载均由IKE SA生成的密钥加密。必须进行加密以公开隐藏各方的传输标识符,其证书和其他私人信息。但是,活跃的攻击者可以阻止第一次IKE_SA_INIT交换并查看此信息,尽管他不再能够继续会话。



TLS 1.3



  • application ( ServerHello ||… || Finished, , , ), (Client Finished). IKEv2 ESP SA round-trip-, TCP/SCTP handshake.
  • , (IDr ), SNI, ClientHello . IKEv2 . ESNI, , DNS, DPI.
  • IKEv2 , «»/«» ( ), PSK, , EAP. TLS 1.3 X.509 . TLS 1.3 X.509 . RFC TLS 1.3 «» . IKEv2 / .
  • TLS 1.3 , , application ClientHello (EarlyData), application Client Finished . TLS 1.3 EarlyData .
  • TLS (session resumption), iPSK , , . IKEv2 , RFC 5723 . IKE , , ( TCP/SCTP/whatever ) IP .
  • TLS . IKEv2 IKE SA ESP SA . , () high-grade , . , , , . - ChaCha20-Poly1305, AES-256-GCM-16, -MGM . IKE SA ESP - NIST-.


使用AEAD密码的SK有效载荷 加密并不困难,并且与ESP完全相似,例如,对于AES-GCM(其中,与AES-GCM-ESP类似,盐是关键材料的一部分):



AES-GCM(
    key             = SK_*e,
    plaintext       = 64-bit IV || payloads || pad || 8-bit padLen,
    nonce           = 32-bit salt || IV,
    associated-data = IKEHdr || unencrypted payloads
) -> ciphertext


使用EDS进行身份验证



如果任何一方要使用签名和X.509证书进行身份验证怎么办?为此,已经在IKE_SA_INIT中发送了CERTREQ有效负载,请求另一端以CERT有效负载的形式提供证书CERTCERTREQ包含证书格式标识符和格式特定的内容。通常,证书可以显示为ASN.1 DER或证书+ URL的SHA1散列,可以从中下载证书。由于UDP的大小受MTU的限制,并且证书的大小可能更大,因此此处使用hash + URL选项非常有用(尽管可以将其视为拐杖)。



除了DER编码的X.509证书和SHA1 + URL外,IKEv2 RFC单独列出:PKCS#7包装的X.509证书,PGP证书,DNS签名密钥,SPKI证书,X.509属性证书,原始公共密钥。如果要以与最常见的用例TLS相同的方式使用IPsec:通过X.509证书进行身份验证的服务器和匿名客户端,则在IKEv2中,无法不对任何一方进行身份验证。但是RFC 5386描述了一种“无为而治”的方法,其中“客户端”可以使用裸露的公开密钥,而服务器可以将其视为匿名。



此外,标准支持EAP身份验证,从而增加了IKE_AUTH的往返行程交换。EAP既可以告知对方是否已通过身份验证,也可以生成IKEv2将考虑和使用的密钥。我将仅向您显示EAP的工作原理图:



                 SAi1, KEi, Ni  -->
                                <--  SAr1, KEr, Nr
SK{IDi, [IDr], SAi2, TSi, TSr}  -->
                                <--  SK{IDr, AUTH, EAP}
                       SK{EAP}  -->
                                <--  SK{EAP(success)}
                      SK{AUTH}  -->
                                <--  SK{AUTH, SAr2, TSi, TSr}


TLS 1.3:在其中,签名(或Finished消息中的MAC )位于所有参与握手的可见消息的哈希值上方。也是一种简单可靠的好方法。没有各种各样的身份验证方法。但是我希望看到一些强大的身份验证密码密钥协议(PAKE)协议,例如俄语SESPAKEOPAQUE



ESP SA密钥材料及其更新



因此,我们已经验证了身份验证,验证了密钥协议正确,协商了ESP SA和流量选择器。它仍然可以为ESP生成对称密钥,并且可以在内核中安装所需的SA / SP:

PRF +(SK_d,Ni || Nr)-> KEYMAT0 || 键盘1


双向通信需要两个ESP SA,因此IKEv2一次生成两个密钥材料,这些材料已直接传输到相应SA中的核心。材料的长度取决于所使用的ESP算法(例如,AES-GCM-ESP除要求密钥外,还要求32位盐)。SPI值是ESP SA提议中各方指定的SPI值。



如果我们需要在几个ESP SA / SP的认同,例如,因为不是所有的愿望可以指定在一个单一的TSI / TSR为此,使用CREATE_CHILD_SA交换交换在IKE_AUTH之后的任何时间进行在以下交换中创建子SA:



    SK {SA,Ni,[KEi],TSi,TSr}->
<-SK {SA,Nr,[KEr],TSi,TSr}


提出要约,立即发送流量选择器。一切都和以前一样。密钥材料已经使用这些新的随机数生成。(可选)您可以使用密钥交换有效负载,这会增加熵并迫使各方使用甚至更多的非对称加密。可能需要经常观察PFS属性(在OTR协议中,临时DH密钥与每个消息一起发送)。在这种情况下,关键材料将按以下方式制定:



PRF +(SK_d,DH-KEY || Ni || Nr)-> KEYMAT0 || 键盘1


如果我们要续订连接的IKE SA,该怎么办?我们进行以下CREATE_CHILD_SA交换:



    SK {SA,Ni,KEi}->
<-SK {SA,Nr,KEr}


SA已包含IKE SA建议的地方,并将开发新的SKEYSEED



PRF(SK_d_old,DH-KEY || Ni || Nr)-> KEYSEED


通过创建新的ESP SA(具有不同的SPI)并删除旧的ESP SA密钥,或通过发送特殊通知(有关此通知的信息),来更新ESP SA密钥。将流量切换为使用新的ESP SA将是透明且无损的。在短时间内,双方将具有两个活动的ESP SA,这将允许处理仍在通信信道上传输的流量。



删除ESP SA的方法是,在随后列出包含要删除的SPI的INFORMATIONAL交换中发送DELETE有效负载由于所有ESP SA成对存在(用于双向通信),因此每一侧仅向负责传出流量的ESP SA发送SPI值。作为响应,接收传入流量的SPI ESP SA值。



    SK {D(SPIi)}->
<-SK {D(SPIr)}


删除IKE SA也可以通过DELETE来完成,但是要使用IKE SPI并接受经过验证的空响应:



    SK {D}->
<-SK {}


TLS 1.3:存在一种通过KeyUpdate消息旋转密钥的机制,但是不可能添加额外的熵或执行DH。 TLS显然不是为寿命很长的连接而设计的。充其量,您只能中断会话并使用iPSK-ECDHE握手继续/创建一个新会话。



IKEv1具有单独的IKE密钥更新过程和单独的用于重新认证的过程。 IKEv2中没有重新认证。为此,只需从头开始创建新的IKE SA,然后通过DELETE删除旧的IKE SA



TLS 1.3:在握手后的任何时候都具有握手后客户端身份验证功能(已完成消息),服务器可以使用X.509证书发送客户端身份验证请求。例如,一位客户在网站上徘徊,转到了他的个人帐户页面。在IKEv2中,这是不可能的-仅在握手时执行身份验证。



通知



那么,如何协商隧道/传输模式,TFC?为此,将“ notification” NOTIFYN)的有效负载添加到请求中。仅IKEv2 RFC中就有数十种通知类型。警报用于发出错误,协商SA,提案,流量选择器等的问题。



为了发出在协商的ESP SA中使用传输模式的信号,发起者和响应者都添加了N(USE_TRANSPORT_MODE)通知以确认模式协商。N(ESP_TFC_PADDING_NOT_SUPPORTED)个警报信号表示不支持TFC。和N(HTTP_CERT_LOOKUP_SUPPORTED)表示下载从URL证书支持。



在不创建新ESP SA的情况下更新ESP SA密钥的能力类似于创建子ESP SA的过程,但是启动器会添加一个N(REKEY_SA)警报,其中包含当前ESP SA的SPI:

    SK {N(REKEY_SA),SA,Ni,[KEi],TSi,TSr}->
<-SK {SA,Nr,[KEr],TSi,TSr}





DPD



与空SK的INFORMATIONAL交换用于死对等检测(DPD),作为守护程序之间的心跳。如果IKE守护程序长时间不可用,则很可能已丢失其状态,因此没有人在对面监视ESP SA,或者它们不再处于活动状态。因此,当很明显远程侧不可用时,删除所有关联的ESP / IKE SA是有意义的。空的SK表示其中没有有效负载,但其中包含经过身份验证的数据(至少具有计数器的IKE头),因此对此类数据包的身份验证是生命的可信赖标志。



    SK {}->
<-SK {}


但是,如果一方迅速重新启动,丢失状态并从头开始建立IKE连接该怎么办?另一端甚至可能不会注意到另一端不可用,并且它会认为它决定重新验证或在另一个IKE连接中创建新的子SA。没有什么灾难性的,但是旧的ESP SA仍然可以存活很长一段时间。发起方可以在其IKE_AUTH交换中放置一个N(INITIAL_CONTACT)警报,表明这是到该侧的唯一已知IKE连接。看到经过身份验证的通知,您可以清楚地删除所有旧的IKE / ESP SA。



DoS与不良KE



IKE_SA_INIT的最开始就已经发送了带有临时DH公钥KEi有效载荷。但是发起方尚未交换IKE SA,他如何知道接收方支持哪种算法?它只能在长期记忆中做出猜测或记住,以前用于与此地址关联的内容。如果响应者不支持该算法,则它将向N(INVALID_KEY_PAYLOAD)发送通知,该通知将指示首选DH算法的标识符。发起者将不得不重复他的请求,但是要使用新的KEi



TLS 1.3:可以使用不同的算法一次发送多个临时公共密钥,也许有些可以。但是这些都是资源和流量。他可能根本不会发送公钥,服务器将通过HelloRetryRequest及其首选项来回复-优点是,直到了解了首选的服务器算法,才完全不使用昂贵的非对称密码,但要付出额外的往返费用。如果客户端最初提供了不合适的公钥算法,则与IKEv2中一样,它将收到HelloRetryRequest以及可供选择的算法。



但是,如果您从发起方发送相同的初始数据包怎么办?每次都可以在那里生成一个新的SPIi...响应者将至少诚实地执行DH计算并以IKE_AUTH响应。 DH是一项非常耗费资源的操作,会消耗CPU和熵的来源-因此转发器可能会损坏。



在IKEv2(而非IKEv1)中,有一种针对此的保护措施,其形式为响应N(COOKIE),并带有包含cookie字符串通知,此后发起方必须重复他的请求,但要向其添加此N(COOKIE)有效负载:



           SAi1, KEi, Ni -->
                         <-- N(COOKIE)
SAi1, KEi, Ni, N(COOKIE) -->
                         <-- SAr1, KEr, Nr, [CERTREQ]


该请求必须具有与第一个相同的SPI / Ni只需用有效负载对其进行补充就足够了。响应者可以保存有关请求和发送给它的cookie之间的连接状态,只有在它们匹配之后,发起者完成将cookie添加到请求中的工作之后,响应者才能例行继续进行IKE_AUTH交换。



但是可以将状态直接存储在cookie中,从而使其成为“自我认证”。它可以包含以下事实:响应者看到了发起的请求(至少NiSPIi看到了):

Cookie = MAC(某些秘密,Ni || SPIi ||时间戳)


因此,DoS爱好者将必须存储状态并回收其重复的消息,这使攻击变得更加昂贵。仅在怀疑有DoS攻击时才启用cookie保护,以免强迫每个人执行额外的往返。



TLS 1.3:具有类似的可选安全性。服务器可以包含Cookie扩展名消息来响应HelloRetryRequest,客户端必须将其插入重复的ClientHello2中



CP



IKEv2允许您协商IP网络/地址的配置。配置有效载荷(CP)允许您请求接收配置(CFG_REQUEST / CFG_REPLY数据包类型),并将配置设置为相反的一侧(CFG_SET / CFG_ACK类型)。配置请求包含该方想知道/设置的属性。属性可以是:“内部”地址,DNS地址,DHCP,子网知识或相关RFC中描述的其他类型。例如,IKE_AUTH交换中的发起者可以发出请求,以向他发出Intranet地址(连接到公司网络)和DNS服务器:



    SK{IDi, [IDr], AUTH, CP(CFG_REQUEST), SAi2, TSi, TSr} -->
<-- SK{IDr,        AUTH, CP(CFG_REPLY),   SAr2, TSi, TSr}

CP(CFG_REQUEST) =
  INTERNAL_IP6_ADDRESS()
  INTERNAL_IP6_DNS()
TSi = (proto=0, port=0-65535, :: - ffff:...:ffff)
TSr = (proto=0, port=0-65535, :: - ffff:...:ffff)

CP(CFG_REPLY) =
  INTERNAL_IP6_ADDRESS(2001:db8::5/64)
  INTERNAL_IP6_DNS(2001:db8::1)
  INTERNAL_IP6_SUBNET(2001:db8:abcd::/64)
TSi = (proto=0, port=0-65535, 2001:db8::5 - 2001:db8::5)
TSr = (proto=0, port=0-65535, 2001:db8::0 - 2001:db8::ffff:ffff:ffff:ffff)


  • 2001:db8 :: 5地址分配给启动器
  • ESP SA 2001:db8::/64 .
  • 2001:db8::1 DNS .
  • 2001:db8:abcd::/64 , , ESP SA, 2001:db8:: .


Go?



为了测试使用GOST算法的IPsec堆栈的现代国内实现,我们决定编写一个完全独立的(与Linux,FreeBSD,strongSwan和其他堆栈无关)实现。并通过Go语言的GoGOST库的现有实现实现Go语言的开发速度和便捷性。以前,我已经有将GOST集成crypto / tlscrypto / x509 Go库的TLS 1.3实现中的经验gostipsec



项目是由两个守护程序组成的免费软件:ESPER(ESPv3)和IKER(IKEv2):



          ┌──────┐          ┌────┐          ┌─────┐          ┌────┐
          │remote│          │iker│          │esper│          │ipfw│
          └──┬───┘          └─┬──┘          └──┬──┘          └─┬──┘
             │                │                │               │
╔══════╤═════╪════════════════╪════════════╗   │               │
║ UDP  │     │                │            ║   │               │
╟──────┘     │    IKEv2...    │            ║   │               │
║            │ <───────────────            ║   │               │
║            │                │            ║   │               │
║            │    IKEv2...    │            ║   │               │
║            │ ───────────────>            ║   │               │
╚════════════╪════════════════╪════════════╝   │               │
             │                │                │               │
             │                │                │               │
             │    ╔═══════════╪══╤═════════════╪════════════╗  │
             │    ║ UNIX-SOCKET  │             │            ║  │
             │    ╟─────────────setkey-commands│            ║  │
             │    ║           │ ───────────────>            ║  │
             │    ╚═══════════╪════════════════╪════════════╝  │
             │                │                │               │
             │                │                │               │
             │                │   ╔════════════╪═══╤═══════════╪════════════╗
             │                │   ║ DIVERT-SOCKET  │           │            ║
             │                │   ╟──────────────encrypted ESP │            ║
             │                │   ║            │ <──────────────            ║
             │                │   ║            │               │            ║
             │                │   ║            │ decrypted ESP │            ║
             │                │   ║            │ ──────────────>            ║
             │                │   ║            │               │            ║
             │                │   ║            │ unencrypted IP│            ║
             │                │   ║            │ <──────────────            ║
             │                │   ║            │               │            ║
             │                │   ║            │  encrypted IP │            ║
             │                │   ║            │ ──────────────>            ║
             │                │   ╚════════════╪═══════════════╪════════════╝
             │                │                │               │


目前,ESPER仅可与DIVERT套接字配合使用(在Linux下我找不到任何简单的东西),因此仅FreeBSD(可能是OpenBSD,未检查)操作系统支持它。 ESPER与IKER一样,不使用PF_KEYv2(它需要C绑定)作为ESP <-> IKE绑定之间的接口,但类似于本文开头提到的类似于setkey的文本接口。因此,也可以通过调用实际的setkey命令,IKER用于协商内核ESP实现的密钥。这些用于ESPER的命令如下所示:



add fc00::ac fc00::dc esp 0x12345678 -u 123 -E aes-gcm-16 0xd3537e657fde5599a2804fbb52d1aaed94b65d3e ;
add fc00::dc fc00::ac esp 0x12345679 -u 234 -E aes-gcm-16 0x9a2dae68e475eacb39d41f23c3cbef890e9f6276 tfc:1320 ;

spdadd fc00::ac/128 fc00::dc/128 all -P in ipsec esp/transport//unique:123 ;
spdadd fc00::dc/128 fc00::ac/128 all -P out ipsec esp/transport//unique:234 ;


ESPER支持:AES-128 / 256-GCM-16,岩浆/蚱Grass-MGM,ESN,TFC,传输/隧道模式,IPv6 / IPv4(对后者的支持,复杂得多,尚未经过全面测试,谁需要IPv4用于新项目?),防止重放攻击。IKER可让您进行匹配:AES-128 / 256-GCM-16 + AES-XCBC + curve25519,岩浆/蚱hopper -MGM + HMAC-Stribog-512 + GOST R 34.10-2012-VKO-256 / 512,ESN / TFC /运输/隧道模式,使用PSK和X.509数字签名(ECDSA,GOST R 34.10-2012)进行身份验证。由单个Hjson文件配置



{
    IKEAlgos: [
        gost128-vko512
        aes256gcm16-aesxcbc-curve25519
        aes128gcm16-aesxcbc-curve25519
    ]
    ESPAlgos: [
        gost128-esn
        gost64-esn
        aes256gcm16-esn
        aes256gcm16-noesn
        aes128gcm16-esn
        aes128gcm16-noesn
    ]
    SigHashes: [
        streebog512
        streebog256
        sha512
        sha256
    ]
    DPDTimeout: 300
    Peers: [
        {
            Autostart: true
            OurIP: fc00::dc
            TheirIP: fc00::ac
            OurId: our.company.net
            TheirId: CN=example.com
            OurTSS: [
                fc00::dc/128[tcp]
                fc00::dc/128[udp/53]
            ]
            TheirTSS: [
                fc00::ac/128
            ]
            Mode: transport
            # Won't be used, because of X.509 signature authentication
            PSK: DEADBABE
            TheirCertHash: a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447
            OurCert: our.company.net.cer.pem
            OurPrvKey: our.company.net.key.pem
            TFC: 1200
        }
    ]
}


在此示例中,我们设置了唯一已知的成员:



  • 哪个守护程序将自动连接到
  • 每五分钟进行一次死角检测
  • ESN, fallback- , TFC 1200 .
  • TCP DNS fc00::dc fc00::ac .
  • X.509 , CN=example.com subject- SHA256 SubjectPublicKeyInfo . OurId OurCert .
  • OurCert/OurPrvKey , PSK FQDN OurId.


IKER尚不支持IKEv2的所有功能的全部集合(CREATE_CHILD_SA,重新生成密钥),不监视数据包丢失,也不在乎DO N'T PANIC原则。因此,它还不能被认为是“工业”用途的候选者。



Tarball gostipsec已经包含所有依赖项,已编译的.info文档以及重做构建系统的目标,尽管通过常规的go build调用可以轻松地构建可执行文件



Hjson?



Holywar主题,但无论如何我都会给我phi:



  • INI不允许您指定这样的清除结构,.ini文件没有标准
  • capabilities database , termcap-like, BSD , (, , ), C. IKER .
  • XML — .
  • JSON — , Python Go . , . - !
  • YAML — , , . , . , YAML , , , . . . - . YAML ( ) - ( StrictYAML ).
  • TOML — : , , , . , :



    [[foo.bar]]
    baz = 123
    
    [[foo.bar]]
    abc = 123
    




    :



    {
      "foo": {
        "bar": [
          {"baz": 123 },
          {"abc": 123 }
        ]
      }
    }
    


    «» / , . , TOML, NNCP , . , , .
  • Hjson — JSON ( , ), Hjson. github.com/hjson/hjson-go Hjson JSON, . . , . , JSON Hjson.




通常,如果实现类似于TLS 1.3的功能的子集(仅通过PSK和X.509证书进行身份验证,无需进行认真的密钥更改),那么从IKEA的角度来看,带有IKEv2和IPv6的ESPv3(使用起来要容易得多!)会稍微困难一些。在实施中。 RFC甚至没有义务支持CREATE_CHILD_SA交换。如果没有TLS 1.3可能引起争议和危险的操作模式,其安全性将非常出色。 IPsec解决方案的性能通常会更高,这要归功于核级传输和长期的IKE会话。



可以看出,在IPsec中,所有内容都得到了完善,以保护整个网络之间的巨大流量,但是BTNS(安全要比没有安全好)IETF工作组编写了多个RFC,证明IPsec可以毫无问题地用于每个套接字的连接,而其中一方(客户端)是匿名的,因此完全质疑使用TLS的可行性。在这种情况下,连接闩锁将允许任何网络应用程序通过发出简单的系统调用(例如setsockopt)来指示它需要FQDN = bank.com地址的ESP ,并将其自身作为X.509证书(或保持匿名)呈现,然后透明,快速且透明在此bank.com上安全地工作,而不会为每个应用程序库提供用户空间传输形式的麻烦。



谢尔盖Matveevcypherpunk,Python / Go / C开发人员,FGUP STC Atlas首席专家。



All Articles