<-
Apache > HTTP Server > 文档 > 版本 2.4 > SSL/TLS

SSL/TLS 强加密:操作指南

可用语言:  en  |  fr 

本文档旨在帮助您入门并使一些功能正常运行。强烈建议您阅读其余的 SSL 文档,并在深入了解相关内容后,再继续学习高级技术。

Support Apache!

另请参阅

top

基本配置示例

您的 SSL 配置至少需要包含以下指令。

LoadModule ssl_module modules/mod_ssl.so

Listen 443
<VirtualHost *:443>
    ServerName www.example.com
    SSLEngine on
    SSLCertificateFile "/path/to/www.example.com.cert"
    SSLCertificateKeyFile "/path/to/www.example.com.key"
</VirtualHost>
top

密码套件和强制执行强安全

如何创建仅接受强加密的 SSL 服务器?

以下配置仅启用最强的密码

SSLCipherSuite HIGH:!aNULL:!MD5

而使用以下配置,您可以指定对特定速度优化的密码的偏好(这些密码将由 mod_ssl 选择,前提是它们受客户端支持)

SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5
SSLHonorCipherOrder on

如何创建接受所有类型密码的 SSL 服务器,但要求访问特定 URL 时使用强密码?

显然,服务器范围内的 SSLCipherSuite 指令限制密码为强变体,这不是这里的答案。但是,mod_ssl 可以在 Location 块内重新配置,以提供每个目录的解决方案,并且可以自动强制重新协商 SSL 参数以满足新配置。这可以通过以下方式完成

# be liberal in general
SSLCipherSuite ALL:!aNULL:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP:+eNULL

<Location "/strong/area">
# but https://hostname/strong/area/ and below
# requires strong ciphers
SSLCipherSuite HIGH:!aNULL:!MD5
</Location>
top

OCSP 钉扎

在线证书状态协议 (OCSP) 是一种机制,用于确定服务器证书是否已被吊销,而 OCSP 钉扎是这种机制的一种特殊形式,其中服务器(如 httpd 和 mod_ssl)维护其证书的当前 OCSP 响应,并将这些响应发送给与其通信的客户端。大多数证书包含颁发证书机构维护的 OCSP 响应者的地址,mod_ssl 可以与该响应者通信以获取可以发送给与服务器通信的客户端的签名响应。

由于客户端可以从服务器获取证书吊销状态,而无需从客户端到证书机构进行额外的连接,因此 OCSP 钉扎是获取吊销状态的首选方式。消除客户端和证书机构之间通信的其他好处是,客户端浏览历史记录不会暴露给证书机构,并且通过不依赖于可能负载过重的证书机构服务器,获取状态更加可靠。

由于服务器获得的响应可以在响应有效期间内重复用于使用相同证书的所有客户端,因此服务器的开销很小。

在正确配置了常规 SSL 支持后,启用 OCSP 钉扎通常只需要对 httpd 配置进行非常小的修改 - 添加以下两个指令

SSLUseStapling On
SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"

这些指令放置在全局范围内(即,不在虚拟主机定义内),无论其他全局 SSL 配置指令放置在哪里,例如在 conf/extra/httpd-ssl.conf 中(对于 httpd 的正常开源构建),/etc/apache2/mods-enabled/ssl.conf 中(对于 Ubuntu 或 Debian 包含的 httpd)等等。

SSLStaplingCache 指令上的路径(例如,logs/)应与 SSLSessionCache 指令上的路径匹配。此路径相对于 ServerRoot

此特定 SSLStaplingCache 指令需要 mod_socache_shmcb(来自指令参数上的 shmcb 前缀)。此模块通常已为 SSLSessionCache 启用,或者代表除 mod_ssl 之外的某个模块启用。如果您使用除 mod_socache_shmcb 之外的机制启用了 SSL 会话缓存,请对 SSLStaplingCache 也使用该替代机制。例如

SSLSessionCache "dbm:logs/ssl_scache"
SSLStaplingCache "dbm:logs/ssl_stapling"

您可以使用 openssl 命令行程序来验证您的服务器是否发送了 OCSP 响应

$ openssl s_client -connect www.example.com:443 -status -servername www.example.com
...
OCSP response: 
======================================
OCSP Response Data:
    OCSP Response Status: successful (0x0)
    Response Type: Basic OCSP Response
...
    Cert Status: Good
...

以下部分重点介绍了需要对配置进行进一步修改的最常见情况。另请参阅 mod_ssl 参考手册。

如果服务器使用多个 SSL 证书

OCSP 响应存储在 SSL 钉扎缓存中。虽然响应通常只有几百到几千字节,但 mod_ssl 支持大小约为 10K 字节的 OCSP 响应。如果证书超过几个,则钉扎缓存大小(上面的示例中为 32768 字节)可能需要增加。如果存储响应时出错,将记录错误消息 AH01929。

如果证书没有指向 OCSP 响应者,或者必须使用不同的地址

请参阅 SSLStaplingForceURL 指令。

您可以使用 openssl 命令行程序确认服务器证书是否指向 OCSP 响应者,如下所示

$ openssl x509 -in ./www.example.com.crt -text | grep 'OCSP.*http'
OCSP - URI:http://ocsp.example.com

如果提供了 OCSP URI 并且 Web 服务器可以直接与之通信而无需使用代理,则无需任何配置。请注意,可能需要调整控制 Web 服务器出站连接的防火墙规则。

如果未提供 OCSP URI,请联系您的证书机构以确定是否提供了一个 URI;如果是,请使用使用该证书的虚拟主机中的 SSLStaplingForceURL 进行配置。

如果配置了多个启用 SSL 的虚拟主机,并且应为某些虚拟主机禁用 OCSP 钉扎

在应禁用 OCSP 钉扎的虚拟主机中添加 SSLUseStapling Off

如果 OCSP 响应者速度慢或不可靠

提供了一些指令来处理超时和错误。请参阅 SSLStaplingFakeTryLaterSSLStaplingResponderTimeoutSSLStaplingReturnResponderErrors 指令的文档。

如果 mod_ssl 记录错误 AH02217

AH02217: ssl_stapling_init_cert: Can't retrieve issuer certificate!

为了在使用特定服务器证书时支持 OCSP 钉扎,必须配置该证书的证书链。如果它没有在启用 SSL 的过程中配置,则在启用钉扎时将发出 AH02217 错误,并且不会为使用该证书的客户端提供 OCSP 响应。

请参阅 SSLCertificateChainFileSSLCertificateFile 以获取有关配置证书链的说明。

top

客户端身份验证和访问控制

如何强制客户端使用证书进行身份验证?

当您知道所有用户(例如,在公司 Intranet 上经常如此)时,您可以要求使用纯证书身份验证。您需要做的就是创建由您自己的 CA 证书 (ca.crt) 签名的客户端证书,然后根据此证书验证客户端。

# require a client certificate which has to be directly
# signed by our CA certificate in ca.crt
SSLVerifyClient require
SSLVerifyDepth 1
SSLCACertificateFile "conf/ssl.crt/ca.crt"

如何强制客户端使用证书访问特定 URL,但仍允许任意客户端访问服务器的其余部分?

要强制客户端使用证书访问特定 URL,您可以使用 mod_ssl 的每个目录重新配置功能

SSLVerifyClient none
SSLCACertificateFile "conf/ssl.crt/ca.crt"

<Location "/secure/area">
SSLVerifyClient require
SSLVerifyDepth 1
</Location>

如何仅允许拥有证书的客户端访问特定 URL,但允许所有客户端访问服务器的其余部分?

执行此操作的关键是检查客户端证书的一部分是否与您的预期相符。通常这意味着检查所有或部分可辨识名称 (DN),以查看它是否包含一些已知字符串。有两种方法可以做到这一点,使用 mod_auth_basicSSLRequire

当证书完全是任意的,或者它们的 DN 没有公共字段(通常是组织等)时,通常需要 mod_auth_basic 方法。在这种情况下,您应该建立一个包含所有允许的客户端的密码数据库,如下所示

SSLVerifyClient      none
SSLCACertificateFile "conf/ssl.crt/ca.crt"
SSLCACertificatePath "conf/ssl.crt"

<Directory "/usr/local/apache2/htdocs/secure/area">
    SSLVerifyClient      require
    SSLVerifyDepth       5
    SSLOptions           +FakeBasicAuth
    SSLRequireSSL
    AuthName             "Snake Oil Authentication"
    AuthType             Basic
    AuthBasicProvider    file
    AuthUserFile         "/usr/local/apache2/conf/httpd.passwd"
    Require              valid-user
</Directory>

此示例中使用的密码是 DES 加密的字符串“password”。有关更多信息,请参阅 SSLOptions 文档。

httpd.passwd

/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA
/C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA
/C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA

当您的所有客户端都属于一个共同的层次结构时,该层次结构被编码到 DN 中,您可以使用 SSLRequire 更轻松地匹配它们,如下所示

SSLVerifyClient      none
SSLCACertificateFile "conf/ssl.crt/ca.crt"
SSLCACertificatePath "conf/ssl.crt"

<Directory "/usr/local/apache2/htdocs/secure/area">
  SSLVerifyClient      require
  SSLVerifyDepth       5
  SSLOptions           +FakeBasicAuth
  SSLRequireSSL
  SSLRequire       %{SSL_CLIENT_S_DN_O}  eq "Snake Oil, Ltd." \
               and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
</Directory>

如何要求使用强密码的 HTTPS,以及基本身份验证或客户端证书,才能从互联网访问 Intranet 网站的一部分?我仍然希望允许 Intranet 上的客户端使用纯 HTTP 访问。

这些示例假设 Intranet 上的客户端的 IP 范围为 192.168.1.0/24,并且您要允许互联网访问的 Intranet 网站的一部分是 /usr/local/apache2/htdocs/subarea。此配置应保留在您的 HTTPS 虚拟主机之外,以便它适用于 HTTPS 和 HTTP。

SSLCACertificateFile "conf/ssl.crt/company-ca.crt"

<Directory "/usr/local/apache2/htdocs">
    #   Outside the subarea only Intranet access is granted
    Require              ip 192.168.1.0/24
</Directory>

<Directory "/usr/local/apache2/htdocs/subarea">
    #   Inside the subarea any Intranet access is allowed
    #   but from the Internet only HTTPS + Strong-Cipher + Password
    #   or the alternative HTTPS + Strong-Cipher + Client-Certificate
    
    #   If HTTPS is used, make sure a strong cipher is used.
    #   Additionally allow client certs as alternative to basic auth.
    SSLVerifyClient      optional
    SSLVerifyDepth       1
    SSLOptions           +FakeBasicAuth +StrictRequire
    SSLRequire           %{SSL_CIPHER_USEKEYSIZE} >= 128
    
    #   Force clients from the Internet to use HTTPS
    RewriteEngine        on
    RewriteCond          "%{REMOTE_ADDR}" "!^192\.168\.1\.[0-9]+$"
    RewriteCond          "%{HTTPS}" "!=on"
    RewriteRule          "." "-" [F]
    
    #   Allow Network Access and/or Basic Auth
    Satisfy              any
    
    #   Network Access Control
    Require              ip 192.168.1.0/24
    
    #   HTTP Basic Authentication
    AuthType             basic
    AuthName             "Protected Intranet Area"
    AuthBasicProvider    file
    AuthUserFile         "conf/protected.passwd"
    Require              valid-user
</Directory>
top

日志记录

mod_ssl 可以将非常详细的调试信息记录到错误日志中,当它的 LogLevel 设置为更高的跟踪级别时。另一方面,在非常繁忙的服务器上,级别 info 可能已经太多。请记住,您可以根据需要为每个模块配置 LogLevel

可用语言:  en  |  fr 

top

评论

注意
这不是问答部分。此处放置的评论应针对有关改进文档或服务器的建议,如果这些评论已被实施或被认为无效/主题无关,则可能被我们的版主删除。有关如何管理 Apache HTTP Server 的问题应发送到我们的 IRC 频道 #httpd(在 Libera.chat 上),或发送到我们的 邮件列表