单包授权#
作者:Michael Rash
译者:BlueDog
摘要#
单数据包授权填补了端口敲门中的空白。
由于无数个软件、协议及其错综复杂的相互依赖关系形成了一个庞大系统,这种结构的复杂性使得确保系统的任何特定属性 — 特别是安全性,就变得极其困难。即便是那些专门设计以增强安全性的软件,在拥有深入洞察力的专家的挑剔眼光下,也可能被发现存在潜在的弱点。从防火墙到 SSH 协议的实现中都发现了漏洞。例如,OpenSSH 是由世界上一些最注重安全性的开发人员开发出来的,但它偶尔也会包含可远程利用的漏洞。这是一个需要注意的重要事实,表明安全性非常难实现,因此支持纵深防御方法。本文研究了单数据包授权 (SPA) 的概念,作为一种超越端口敲门的下一代被动身份验证技术。
当攻击者试图利用服务器软件(而不是客户端软件)中的漏洞时,第一步是侦察,即攻击者需要找到一个目标。Nmap 已出色地实现了这一过程的自动化,因此很容易构建一个可能易受攻击的目标系统列表。如果您碰巧正在运行的服务器软件中存在零日漏洞,那么您肯定不想出现在此目标列表中!端口敲门技术和单数据包授权技术都使用以默认丢弃方式配置的数据包过滤器,同时仅向能够通过被动机制证明其身份的 IP 地址提供服务。无需 TCP/IP 堆栈访问即可通过这种被动方式验证远程 IP 地址。以这种方式进行保护时,Nmap 甚至无法判断服务器是否正在运行,即使攻击者拥有零日漏洞,他们也无能为力。
本文是关于单数据包授权的两部分系列文章的第一部分,它为单数据包授权奠定了理论基础,并解释了它为何是超越端口敲门的下一代被动授权技术。下一章将提供有关如何使用 fwknop 为 SSH 守护程序提供单数据包授权保护的实践指导。
端口敲门简介#
端口敲门是一种早期技术,它利用 TCP 和 UDP 数据包头中的端口字段来传递信息。通常,这些协议用于封装应用程序层数据,但端口敲门通过使用端口号本身作为数据字段,将信息编码为发送到各个端口的数据包序列。这些数据包通常通过防火墙日志或数据包捕获机制(如 libpcap)进行监控。通常情况下,会有一个端口敲门客户端和一个端口敲门服务器。在这种情况下(以及本文的其余部分中,除非另有说明),术语客户端和服务器分别指发送和监控数据包的软件组件。客户端负责生成端口序列,服务器负责被动接收序列,并在收到有效序列后重新配置数据包过滤器以允许连接到受保护的服务。
典型的端口敲门场景是端口敲门服务器配置数据包过滤器以阻止对服务(如 SSH)的所有访问,直至端口敲门客户端发送特定的端口敲门序列。例如,服务器可能要求客户端按以下顺序向以下端口发送 TCP SYN 数据包:
- 23400
- 1001
- 2003
- 65501
如果服务器监视此敲门序列,则会重新配置数据包过滤器,以允许来自发出该序列的 IP 地址的 SSH 连接。利用数据包过滤器提供的连接跟踪机制(如 Netfilter 中的 conntrack 系统),即使敲门服务器创建的初始规则在超时后被删除,SSH 会话仍然可以保持建立状态。端口敲门序列可以加密,许多实现已在 http://www.portknocking.org 上列出。有关端口敲门操作的图形表示,请参见图 1。
图 1. 端口敲门操作
端口敲门的局限性#
端口敲门可以有效限制对服务的访问,但局限性在哪里呢?首先,加密敲门序列不可避免地会带来信息传输,而信息量的大小与加密算法有关。对于对称加密算法,加密数据量至少与块大小相当(例如,高级加密标准中采用的 Rijndael 对称块密码,块大小为 128 位)。对于非对称加密算法,加密数据量会更大。
例如,GnuPG 中使用的原始 ElGamal 算法在对数据进行加密时,密文长度是明文长度的两倍。即便 GnuPG 采用了压缩技术(有时可以使密文长度小于原始明文长度),但 GnuPG 密钥通常较大,导致即使是短小消息的密文也会达到数百字节。
端口敲门场景下尤为重要。由于 TCP 和 UDP 头部仅提供 16 位宽度的端口字段,因此端口敲门序列中每个数据包仅能承载两个字节的信息(假设包头中其他字段不参与承载数据,即便参与,承载量级也远小于数据载荷)。因此,对于分组密码而言,密码序列至少需要包含 B/(2*8) 个数据包,其中 B 为分组大小(以比特为单位)。从当前网络的普遍速度和可靠性来看,这本身并不可怕,真正的问题在于乱序投递。
乱序投递数据对解密造成困难,由于端口敲门客户端与服务端不存在类似 TCP 意义上的 “连接” 概念,因此服务端无法对乱序数据包进行重新排序。
数据包可能走不同的路由,部分路由可能是慢的,因此客户端必须求助一种人为机制来尽量减小乱序到达的可能性:时间。在敲门序列中每个数据包之间引入时间间隔(比如半秒),通常可以保证数据包到达服务端时仍然是有序的。现在,对于 128 位块大小,对应的端口敲门序列为 128/(2*8) = 8 个数据包。当考虑半秒的延迟时,仅仅传递序列就需要四秒。对于更大的消息(比如非对称密码产生的消息),这样的数据传输速度是不可接受的。
数据传输能力的限制还给端口敲门方案带来另一个限制。很难有效防御重放攻击。任何能够监视客户端发往服务器的敲门序列的人都可以自由地针对服务器重放该序列,以试图获得相同的访问权限。如果该序列通过 NAT 设备传递,并且服务端的数据包过滤规则允许的源 IP 是外部的 NAT 地址,则这是一个特别严重的问题。比如,如果端口敲门客户端位于 RFC 1918 子网比如 10.10.1.0/24,而端口敲门服务器位于只能通过公网访问的远端网络上,那么服务器必须允许来自 NAT IP 的访问。那么,相同子网上的任何人只要能重放该序列,就可以获得相同的访问权限。另外,只要规则存在,相同子网上的任何人都有相同的访问权限,一旦实例化规则以接受来自 NAT 地址的连接(此时不需要序列重放,SPA 也是如此)。
为了尝试解决重放问题,人们对传统的端口敲门进行了各种修改,例如引入时间窗口、使用 S/Key 风格的哈希迭代,甚至在每次使用后简单地更改加密密钥。然而,这些方法都需要端口敲门客户端和服务器维护某种状态,并且当涉及多个用户时,其可扩展性并不是很好。
端口敲门的另一个限制是,恶意第三方只需将一个额外的数据包伪装成客户端通过线路发送的端口序列,就极易破坏敲门序列。攻击者只需将数据包的源地址设置为与真实客户端的源地址相同,并选择与客户端发送的最后一个数据包相同的端口号。这个额外的包会破坏敲门序列,因此服务器不会允许合法客户端进行任何其他访问。尽管人们实际执行此操作的可能性相对较小(他们仍然需要能够监视从客户端发出的数据包),但主要问题是此类攻击非常容易执行。只需一个数据包,攻击者甚至不需要与原始数据包数据路径处于同一链路上。
最后,任何能够监视客户端和服务器之间流量的入侵检测系统 (IDS) 都可以轻松地将敲门序列检测为端口扫描。对于加密的敲门序列尤其如此,它们往往比简单的共享序列更长。对于 IDS 而言,端口敲门看起来就像是从单个 IP 地址在相对较短的时间内对各种端口进行一系列探测,这非常符合端口扫描的定义。
单包授权#
综上所述,端口敲门提供了增强安全性的诸多好处,但也存在一些需要解决的严重局限性。单包授权是一种相对较新的协议,它保留了端口敲门的所有好处,但修复了上面讨论的局限性。第一个公开可用的 SPA 实现于 2005 年 5 月发布,作为称为 fwknop(http://www.cipherdyne.org/fwknop)的软件的一部分。最初创建于 2004 年的 fwknop 是第一个将被动操作系统指纹识别和端口敲门相结合的端口敲门实现(这使得可以执行诸如 “仅接受来自 Linux-2.4 系统的敲门序列” 之类的操作),但 SPA 方法现在是 fwknop 提供的最流行(也是默认的)身份验证方法。需要注意的是,fwknop 提供身份验证和授权服务,但本文的范围不包括对两者之间差异的全面讨论。
单数据包授权要求与端口敲门类似的体系结构。二者均有客户端和服务器组件,服务器控制默认丢弃数据包的过滤器,并且服务器被动监视数据包。然而,端口敲门和 SPA 的体系结构相似性也仅限于此。
单数据包授权将数据传输转移至其所属的位置 —— 应用层。这意味着,SPA 能够在每个数据包中发送多达最小 MTU 值(以太网网络上的 1500 字节)的数据,而端口敲门只能在每个数据包中发送两个字节的数据。这远远超过了端口敲门可能的数据传输速率,并且能够轻松访问如此数量的数据包数据,从而开辟了巨大的可能性。本文其余部分讨论了 fwknop 实现的单数据包授权。
fwknop 在应用程序层定义了以下数据包格式:
- 16 字节随机数据
- 客户端用户名
- 客户端时间戳
- fwknop 版本
- 模式(访问模式 / 命令模式)
- 访问(或命令字符串)
- MD5 校验和
SPA 数据包格式中许多字段长度可变,但以 “:” 字符分割(字段经过 base64 编码,因此嵌入的冒号不会破坏此语法)。fwknop 客户端构建上述数据包格式后,整个数据包将使用两种加密算法之一进行加密:具有 128 位共享密钥的 Rijndael 对称分组密码或使用 GnuPG 生成的具有高达 2048 位公钥 / 私钥对的非对称 ElGamal 算法。fwknop 客户端默认通过 UDP 端口 62201 发送 SPA 数据包,但这可以通过命令行轻松更改;请参阅 --Server-port 参数。(fwknop 提供了许多配置选项 —— 请参阅资源以获取文档和手册页的链接。)有关 SPA 操作的图形表示,请参见图 2。
图 2. SPA 操作
16 字节的随机数据解决了端口碰撞中最高优先级的限制之一 —— 重放问题。每个 SPA 数据包加密前添加 16 字节随机数据,fwknop 服务器解密后,缓存整个数据包的 MD5 校验和。随机数据使每个 SPA 数据包都不同(即使发送相同的访问指令),因此每个数据包的 MD5 校验和也不同。若新数据包的 MD5 校验和与先前数据包匹配,fwknop 服务器不采取任何操作,并写入 syslog 警告消息。因此,被第三方拦截的 SPA 数据包无法在网络上重播以绕过默认丢弃数据包的过滤器。
fwknop 将客户端用户名和时间戳放入数据包中,fwknop 服务器使用用户名为远程用户维护不同的授权级别。fwknop 可安装在多用户系统上,每个用户可被授权通过远程 fwknop 服务器连接到不同的服务。fwknop 版本字段用于保持向后兼容性。新版本中可添加或删除字段,但通过使用版本号,fwknop 服务器可与旧客户端构建 SPA 数据包的方式兼容。模式字段告诉 fwknop 服务器客户端是要访问服务还是执行命令(下一个字段使用特定的访问控制指令或命令)。例如,要访问 TCP 端口 22,访问字段将包含字符串,tcp/22,其中 <IP 地址> 是客户端选择放入数据包的任意 IP 地址。最后,MD5 校验和字段包含客户端在传输前未加密的数据包的 MD5 校验和。服务器在解密后使用此字段验证消息完整性。
SPA 数据包传输更多数据解决了重放问题和端口敲门方案中极低的数据传输速率。端口敲门中的另外两个限制也可以被解决。首先,SPA 协议的单数据包性质意味着恶意第三方无法仅仅通过欺骗数据包到与受监视的 SPA 数据包发送的相同端口来破坏身份验证方案。最后,由于 SPA 协议只需要一个数据包,因此对于任何中间 IDS,它看起来都不像端口扫描。任何 IDS 都只能看到一个看似毫无意义的数据块,似乎是随机发送到某个 IP 地址的。
结论#
单数据包授权在保护服务方面提供了类似端口敲门的安全优势,这些服务使用默认丢弃策略配置的数据包过滤器。任何人以这种方式扫描受保护的目标服务时,都无法检测到此类服务正在监听,这使得利用零日漏洞也更加困难。SPA 为端口敲门实现的诸多限制提供了巧妙的解决方案。这些解决方案使 SPA 能够解决重放问题、实现支持非对称加密使用的数据传输速率、挫败简单的欺骗攻击,并避开监视网络端口扫描的入侵检测系统的侦察。
请参阅下个月的 LJ,了解本文的第二部分,其中将详细展示如何使用 SPA。
参考资料#
- Krzywinski, M. 2003.“端口敲门:跨越关闭端口的网络认证”。SysAdmin 杂志 12:12-17
- ElGamal 加密:http://en.wikipedia.org/wiki/ElGamal_encryption
- 在我撰写本文时,我所知道的其他 SPA 实现只有一个,可从 http://www.unspecific.com/spa 获得
- 另一个名为 Tumbler(http://tumbler.sourceforge.net)的实现使用单个数据包,但它使用哈希有效负载而不是加密有效负载,这导致了截然不同的架构
- fwknop 文档和手册页:http://www.cipherdyne.org/fwknop/docs