lighty 的生活

lighty 开发者博客

使用 GnuTLS 缓解 TLS 上的 BEAST 攻击

在我们的 lighttpd 2 开发分支中,我们使用模块来实现 SSL 支持;这使我们能够支持不同的 SSL 库,今天我想谈谈 mod_gnutls。

SSL/TLS 遇到了一些问题。一方面是 BEAST 攻击 1,它建议对 SSL3.0 和 TLS1.0 连接使用 RC4;另一方面,TLS 中的 RC4 已被攻破 2

因此,虽然有些客户端可能支持 TLS1.1 甚至 TLS1.2,但你仍然需要为不支持的客户端支持 RC4,同时你也不希望允许支持 TLS1.1 或 TLS1.2 的客户端使用 RC4。大多数服务器配置无法处理这种情况——但 mod_gnutls 可以,它利用了 GnuTLS 中的一个巧妙的钩子函数3(PolarSSL 也直接支持此功能,Hiawatha 正在使用它)。

基本上,如果连接使用 TLS1.0 或 SSL3.0,它将把 ":-CIPHER-ALL:+ARCFOUR-128" 添加到你的 优先级字符串 4(类似于 OpenSSL 中的密码套件)。

我建议在 lighttpd2 中将 "NORMAL:-VERS-SSL3.0:-CIPHER-ALL:-SHA1:-MD5:+SHA1:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC:%SERVER_PRECEDENCE" 作为 GnuTLS 的优先级字符串,mod_gnutls 将为你修复 BEAST 攻击。

  • SSL3.0 已被禁用 – 所有客户端现在至少应该支持 TLS1.0。
  • -SHA1:-MD5:+SHA1 重新排序了密码套件,使得 SHA1 靠后,并移除了 MD5 密码套件(只有一个支持的 MD5 密码套件:TLS_RSA_ARCFOUR_MD5)。
  • -CIPHER-ALL:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC 选择了我们希望支持的 3 种密码套件。如果你愿意,你也可以添加 128 位密码套件::+AES-128-GCM:+AES-128-CBC:+CAMELLIA-128-CBC
  • %SERVER_PRECEDENCE 告诉 GnuTLS 服务器根据其自身偏好重新排序密码套件。
  • 你可以添加 “:-RSA” 来强制进行 DHE/ECDHE 密钥交换,这应该能提供完美前向保密(Perfect Forward Secrecy)。

推荐的优先级字符串应产生以下密码列表

TLS_ECDHE_ECDSA_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_AES_256_CBC_SHA1
TLS_ECDHE_RSA_AES_256_GCM_SHA384
TLS_ECDHE_RSA_AES_256_CBC_SHA1
TLS_DHE_RSA_AES_256_CBC_SHA256
TLS_DHE_RSA_AES_256_CBC_SHA1
TLS_DHE_RSA_CAMELLIA_256_CBC_SHA1
TLS_DHE_DSS_AES_256_CBC_SHA256
TLS_DHE_DSS_AES_256_CBC_SHA1
TLS_DHE_DSS_CAMELLIA_256_CBC_SHA1
TLS_RSA_AES_256_CBC_SHA256
TLS_RSA_AES_256_CBC_SHA1
TLS_RSA_CAMELLIA_256_CBC_SHA1

对于 TLS1.0,它将改为使用此功能(SSL3.0 已禁用)

TLS_DHE_DSS_ARCFOUR_SHA1
TLS_RSA_ARCFOUR_SHA1

使用标准 RSA 密钥,它将使用以下密码套件(更新:我们现在支持 DHE

TLS_ECDHE_RSA_AES_256_GCM_SHA384
TLS_ECDHE_RSA_AES_256_CBC_SHA1
TLS_DHE_RSA_AES_256_CBC_SHA256
TLS_DHE_RSA_AES_256_CBC_SHA1
TLS_DHE_RSA_CAMELLIA_256_CBC_SHA1
TLS_RSA_AES_256_CBC_SHA256
TLS_RSA_AES_256_CBC_SHA1
TLS_RSA_CAMELLIA_256_CBC_SHA1

以及对于 TLS1.0

TLS_RSA_ARCFOUR_SHA1

lighttpd 2 配置示例

setup {
    module_load "mod_gnutls";
    gnutls [
        "priority" => "NORMAL:-VERS-SSL3.0:-CIPHER-ALL:-SHA1:-MD5:+SHA1:+AES-256-GCM:+AES-256-CBC:+CAMELLIA-256-CBC:%SERVER_PRECEDENCE",
        "listen" => "0.0.0.0:443",
        "pemfile" => "/ssl/certs/lighttpd_server.pem"
    ];
}

现在你可以测试你的服务器了(需要足够新的 GnuTLS 版本,至少包含对 TLS1.1 的支持,已使用 gnutls 3.0.22 测试)。

gnutls-cli --priority="NORMAL:-CIPHER-ALL:+ARCFOUR-128" example.com
gnutls-cli --priority="NORMAL:-CIPHER-ALL:+ARCFOUR-128:-VERS-TLS-ALL:+VERS-TLS1.0" example.com
gnutls-cli --priority="NORMAL:-ARCFOUR-128:-VERS-TLS-ALL:+VERS-TLS1.0" example.com

第一个应该失败;GnuTLS 应该使用 TLS1.2 进行连接,并且 RC4 将不可用。第二个命令应该成功——它应该使用 TLS1.0 进行连接,并且只有 RC4 可用,这就是为什么第三个命令应该再次失败的原因。

Qualys SSL Labs 服务器测试 5 应该会检测到此设置,它将在“仅用于 BEAST 缓解的套件(TLS 1.0 及更早版本)”下显示 "SSL_RSA_WITH_RC4_128_MD5"

1 缓解 TLS 上的 BEAST 攻击

2 TLS 中的 RC4 已被攻破:现在怎么办?

3 gnutls_handshake_set_post_client_hello_function

4 GnuTLS 优先级字符串

Qualys SSL Labs 服务器测试

请注意,我们不接受发布超过 3 个月的文章的评论! 另请使用我们的 bug 追踪器报告 bug,并使用我们的 IRC 频道 #lighttpd@libera 进行聊天。

« lighttpd 1.4.32 发布 预发布:lighttpd 1.4.33rc1-r2901 »