单包授权
无数的软件、协议和复杂的相互依赖关系共同构成了一个系统,很难保证任何特定的属性,尤其是安全性。即使是专门为增强安全性而设计的软件,也可能在掌握详细知识的聪明人的指使下,对其造成损害。从防火墙到安全外壳(SSH)协议的实现,各种安全软件都曾被发现存在漏洞。例如,OpenSSH 由世界上一些最具安全意识的开发人员开发,但它偶尔也会包含可远程利用的漏洞。这是一个需要注意的重要事实,因为它似乎表明安全很难实现,因此,加强了深度防御方法的理由。本文探讨了单包授权(SPA)的概念,作为一种超越端口敲门的下一代被动身份验证技术。
当攻击者试图利用服务器软件(相对于客户端软件)中的漏洞进行攻击时,第一步是侦察;攻击者需要定位目标。Nmap 巧妙地自动化了这个过程,因此很容易构建一个可能容易受到攻击的目标系统列表。如果攻击者在您恰好正在运行的服务器软件中发现了一个零日漏洞,您肯定不希望出现在此目标列表中!端口敲门和单包授权都使用配置为默认丢弃姿态的数据包过滤器,并同时仅向那些可以通过被动机制证明其身份的 IP 地址提供服务。通过这种被动方式验证远程 IP 地址无需 TCP/IP 堆栈访问。即使攻击者拥有零日漏洞,Nmap 也无法判断服务器是否正在运行,这无关紧要。
本文是关于单包授权的两部分系列文章的第一篇,它为单包授权奠定了理论基础,并阐述了为什么它是一种超越端口敲门的下一代被动授权技术。下一篇文章将动手介绍如何使用 fwknop 为您的 SSH 守护程序提供单包授权保护。
端口敲门是第一代技术,它使用 TCP 和 UDP 数据包头中的端口字段来传递信息。通常,这些协议用于封装应用层数据,但端口敲门通过使用端口号本身作为字段来传输数据,从而在发送到不同端口的数据包序列中编码信息。这些数据包通常通过防火墙日志或数据包捕获机制(例如 libpcap)进行监控。通常,存在端口敲门客户端和端口敲门服务器。在这种情况下(以及本文的其余部分,除非另有说明),术语客户端和服务器分别指发送和监控数据包的软件组件。客户端负责生成端口序列,服务器负责被动收集序列并在收到有效序列后重新配置数据包过滤器,以允许连接到受保护的服务。
典型的端口敲门场景是,端口敲门服务器配置数据包过滤器以阻止对服务(例如 SSH)的所有访问,直到端口敲门客户端发送特定的端口敲门序列。例如,服务器可能要求客户端按以下顺序向以下端口发送 TCP SYN 数据包
23400
1001
2003
65501
如果服务器监控到此敲门序列,则数据包过滤器将重新配置以允许来自发送该序列的 IP 地址的 SSH 连接。通过利用数据包过滤器提供的连接跟踪机制(例如 Netfilter 中的 conntrack 系统),在敲门服务器创建的初始规则在超时后被删除后,SSH 会话可以保持建立状态。端口敲门序列可以加密,并且在 www.portknocking.org 列出了许多实现。有关端口敲门操作的图形表示,请参见图 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)上,并且端口敲门服务器位于只能通过开放 Internet 访问的远程网络上,则服务器必须允许访问 NAT IP 地址。同一子网上的任何人都可以重放该序列,都将被授予相同的访问级别。此外,只要规则存在(在这种情况下不需要序列重放,这对于 SPA 也仍然适用),同一子网上的任何人一旦实例化规则以接受来自 NAT 地址的连接,就具有相同的访问级别。
已经对传统的端口敲门进行了各种修改,以尝试为重放问题提供解决方案,例如使时间成为重要因素,使用 S/Key 风格的哈希函数迭代,甚至只是在每次使用后更改加密密钥。但是,这些方法中的每一种都要求端口敲门客户端和服务器都维护某种状态,并且当涉及多个用户时,它不能很好地扩展。
端口敲门的另一个局限性是,恶意第三方只需在客户端通过线路发送端口序列时,通过欺骗一个额外的数据包到端口序列中,就非常容易破坏敲门序列。攻击者只需将数据包上的源地址设置为与真实客户端的源地址相同,并选择与客户端发送的最后一个数据包相同的端口号。这个额外的数据包会破坏敲门序列,因此服务器不会允许合法的客户端进行任何额外的访问。尽管人们实际上会这样做的可能性相对较小(他们仍然需要能够监视来自客户端的数据包),但主要问题是这种攻击非常容易执行。只需要一个数据包,攻击者甚至不需要内联到原始数据包数据路径。
最后,任何能够监视客户端和服务器之间流量的入侵检测系统(IDS)都很容易将敲门序列检测为端口扫描。对于加密的敲门序列尤其如此,加密的敲门序列往往比简单的共享序列更长。对于 IDS 而言,端口敲门看起来就像在相对较短的时间内从单个 IP 地址到各个端口的一系列探测,这非常符合端口扫描的定义。
以上讨论的最终结果是,端口敲门提供了一些真正的好处,可以增强安全性,但是还需要解决一些严重的局限性。单包授权是一种相对较新的协议,它保留了端口敲门的所有优点,但修复了上面讨论的局限性。第一个公开可用的 SPA 实现于 2005 年 5 月作为名为 fwknop 的软件发布 (www.cipherdyne.org/fwknop)。fwknop 最初创建于 2004 年,是第一个结合被动操作系统指纹识别和端口敲门的端口敲门实现(这使得可以执行诸如“仅接受来自 Linux-2.4 系统的敲门序列”之类的操作),但是 SPA 方法现在是 fwknop 提供的最流行(和默认)的身份验证方法。请注意,fwknop 同时提供身份验证和授权服务,但是对两者之间差异的全面讨论超出了本文的范围。
单包授权要求与端口敲门类似的架构。两者都具有客户端和服务器组件,服务器维护默认丢弃数据包过滤器的控制,并且服务器被动地监视数据包。但是,这是端口敲门和 SPA 之间架构相似性开始分歧的地方。
单包授权将数据传输移动到它所属的位置——应用层。这意味着,与端口敲门的情况不同,SPA 每个数据包能够发送最多相当于最小 MTU 的数据量(以太网网络上为 1,500 字节),而不是每个数据包只能发送两个字节的数据。这远远超过了端口敲门可能实现的数据传输速率,并且轻松访问如此大的数据包数据量开辟了巨大的可能性。本文的其余部分讨论了 fwknop 实现的单包授权。
fwknop 在应用层定义了以下数据包格式
16 字节的随机数据
客户端用户名
客户端时间戳
fwknop 版本
模式(访问或命令)
访问(或命令字符串)
MD5 校验和
SPA 数据包格式中的许多字段都具有可变长度,但以 : 字符分隔(字段采用 base64 编码,因此嵌入的冒号不会破坏此语法)。一旦 fwknop 客户端构建了上述数据包格式,整个数据包将使用两种加密算法之一进行加密:Rijndael 对称块密码,带有 128 位共享密钥;或者非对称 ElGamal 算法,带有 GnuPG 生成的最多 2,048 位公钥/私钥对。默认情况下,fwknop 客户端通过 UDP 端口 62201 发送 SPA 数据包,但是可以很容易地从命令行更改此设置;请参阅 --Server-port 参数。(fwknop 提供了许多配置选项——有关文档和手册页的链接,请参见“资源”)。有关 SPA 操作的图形表示,请参见图 2。
那么,所有这些字段都是做什么用的呢?首先,16 字节的随机数据允许解决端口敲门中最高优先级的局限性之一——重放问题。每个 SPA 数据包在加密之前都预先添加了 16 字节的随机数据,然后在 fwknop 服务器成功解密后,整个数据包的 MD5 校验和将被缓存。随机数据允许每个 SPA 数据包都不同(即使发送相同的访问指令),因此每个数据包的 MD5 校验和也很有可能不同。如果任何新数据包的 MD5 校验和与先前数据包的校验和匹配,则 fwknop 服务器将不执行任何操作,并将警告消息写入 syslog。因此,第三方拦截的任何 SPA 数据包都无法在网络上重放,以努力通过默认丢弃数据包过滤器获得访问权限。
客户端用户名和时间戳由 fwknop 放置在数据包中,用户名由 fwknop 服务器用于维护远程用户的不同授权级别。fwknop 可以安装在多用户系统上,并且每个用户都可以被授权连接到远程 fwknop 服务器的不同服务。fwknop 版本字段用于维护向后兼容性。可以在新版本的 fwknop 中添加或删除字段,但是通过使用版本号,fwknop 服务器可以保持与旧客户端构建 SPA 数据包的方式兼容。模式字段告诉 fwknop 服务器客户端是想访问服务还是执行命令(访问字段中包含特定的访问控制指令或命令)。例如,要获得对 TCP 端口 22 的访问权限,“访问”字段将包含字符串<IP>,tcp/22其中 <IP> 是客户端选择放入数据包中的任何 IP 地址。最后,MD5 校验和字段包含客户端传输之前未加密数据包的 MD5 校验和。服务器使用它在解密后验证消息完整性。
我们已经看到了可以通过 SPA 数据包传输的增加的数据量如何解决重放问题以及端口敲门方案中极低的数据传输速率。端口敲门中还有两个剩余的局限性需要解决。首先,SPA 协议的单数据包性质意味着恶意第三方不能仅仅通过欺骗一个数据包到监视的 SPA 数据包发送到的同一端口来破坏身份验证方案。最后,由于 SPA 协议只需要一个数据包,因此它不会像端口扫描一样出现在任何中间 IDS 中。任何 IDS 只能看到看似随意发送到某个 IP 地址的难以理解的数据 blob。
单包授权在保护配置为默认丢弃姿态的数据包过滤器中的服务方面,提供了与端口敲门类似的安全优势。任何扫描以查找受此方式保护的目标服务的人都将无法检测到此类服务正在侦听,这使得即使利用零日漏洞也更加困难。SPA 为端口敲门实现中的许多局限性提供了优雅的解决方案。这些解决方案使 SPA 能够解决重放问题,实现使使用非对称加密成为可能的数据传输速率,阻止简单的欺骗攻击,并保持在监视网络端口扫描的入侵检测系统的雷达之下。
请参阅下个月的LJ,了解本文的第二部分,该部分将确切地展示如何使用 SPA。
资源
Krzywinski, M. 2003. “端口敲门:跨封闭端口的网络身份验证”。SysAdmin Magazine 12: 12–17。
ElGamal 加密:en.wikipedia.org/wiki/ElGamal_encryption
据我所知,在撰写本文时,只有一个其他的 SPA 实现,网址为 www.unspecific.com/spa。
另一个名为 Tumbler (tumbler.sourceforge.net) 的实现也采用单数据包,但它使用哈希有效负载而不是加密有效负载,这导致了显着不同的架构。
fwknop 文档和手册页:www.cipherdyne.org/fwknop/docs
Michael Rash 拥有马里兰大学应用数学硕士学位,专注于计算机安全。Michael 是 cipherdyne.org 的创始人,这是一个致力于 Linux 系统的开源安全软件的网站,他担任 Enterasys Networks 的 Dragon 入侵检测系统的安全架构师。他是即将出版的书籍 Linux 防火墙:攻击检测与响应 的作者,该书由 No Starch Press 出版。