使用 Apache 2.2 和 OpenSSL 1.0.1e-fips 进行双向 SSL 身份验证

使用 Apache 2.2 和 OpenSSL 1.0.1e-fips 进行双向 SSL 身份验证

我有一台 CentOS 6 服务器,运行 Apache 2.2.15 和 OpenSSL 1.0.1e-fips。我正在尝试为我的 Web 根目录中的特定位置设置双向 SSL 身份验证。第三方提供了公共(纯文本)和私有(二进制)证书。

我需要一些关于如何包含公共和私人证书以使握手正常工作的指导,因为我收到以下错误:

重新协商握手失败:客户端不接受!?

以下是我的 /etc/httpd/conf.d/ssl.conf 文件中与本节相关的内容:

<Location /api/path/>
SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
SSLCACertificateFile /etc/pki/tls/private/public.cer
SSLVerifyClient require
SSLVerifyDepth 10
SSLOptions +StdEnvVars +ExportCertData +OptRenegotiate
</Location>

诚然,我不是 SSL 专家。但我知道如何安装和运行证书。我已将 logginf 调至“调试”级别。我尝试遵循以下指南:

http://www.stefanocapitanio.com/configuring-two-way-authentication-ssl-with-apache/

http://www.cafesoft.com/products/cams/ps/docs32/admin/ConfiguringApache2ForSSLTLSMutualAuthentication.html

提前致谢!

完整的 ssl.conf 文件:

LoadModule ssl_module modules/mod_ssl.so
Listen 443

SSLPassPhraseDialog  builtin

SSLSessionCache         shmcb:/var/cache/mod_ssl/scache(512000)
SSLSessionCacheTimeout  300

SSLMutex default

SSLRandomSeed startup file:/dev/urandom  256
SSLRandomSeed connect builtin
#SSLRandomSeed startup file:/dev/random  512
#SSLRandomSeed connect file:/dev/random  512
#SSLRandomSeed connect file:/dev/urandom 512

SSLCryptoDevice builtin
#SSLCryptoDevice ubsec
<VirtualHost *:443>
DocumentRoot "/var/www/html/staging-site"
ServerName staging.site.com:443
ErrorLog logs/ssl_error_log
TransferLog logs/ssl_access_log
LogLevel debug

SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW

SSLCertificateFile /etc/pki/tls/certs/cert.crt
SSLCertificateKeyFile /etc/pki/tls/private/private.key
#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
SSLCACertificateFile /etc/pki/tls/certs/rapidssl.crt

#SSLVerifyClient require
#SSLVerifyDepth  10

#   Access Control:
#<Location />
#SSLRequire (    %{SSL_CIPHER} !~ m/^(EXP|NULL)/ \
#            and %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
#            and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"} \
#            and %{TIME_WDAY} >= 1 and %{TIME_WDAY} <= 5 \
#            and %{TIME_HOUR} >= 8 and %{TIME_HOUR} <= 20       ) \
#           or %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/
#</Location>

<Location /path/api/>
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCACertificateFile /etc/pki/tls/private/3rdpartyprivate.cer
    SSLVerifyClient require
    SSLVerifyDepth 10
    SSLOptions +StdEnvVars +ExportCertData +OptRenegotiate
</Location>

#   SSL Engine Options:
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
<Files ~ "\.(cgi|shtml|phtml|php3?)$">
    SSLOptions +StdEnvVars
</Files>
<Directory "/var/www/cgi-bin">
    SSLOptions +StdEnvVars
</Directory>

#   SSL Protocol Adjustments:
SetEnvIf User-Agent ".*MSIE.*" \
         nokeepalive ssl-unclean-shutdown \
         downgrade-1.0 force-response-1.0

#   Per-Server Logging:
CustomLog logs/ssl_request_log \
          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
</VirtualHost>

答案1

我认为您没有在正确的地方使用正确的证书。您应该在SSLCertificateFile(PEM 格式的证书)、SSLCertificateKeyFile(与证书匹配的 PEM 格式的密钥)和SSLCertificateChainFile(从主机证书的颁发者证书开始直到 PEM 格式的根证书的证书)中使用受信任 CA 颁发的服务器证书。

SSLCACertificateFile必须使用签署客户端证书的 CA 的证书(同样为 PEM 格式)。

这是一个完整的示例,请记住,我使用的服务器证书由签署客户端证书的同一 CA 签署。如果您的需求不同,请进行调整。

  • 生成证书 openssl genrsa -des3 -out ca.key 4096 openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=US/ST=Some State/L=FancyTown/O=SomeOrg/CN=Self-Signed CA" openssl genrsa -out client.key 4096 openssl req -new -key client.key -out client.csr -subj "/C=US/ST=Some State/L=FancyTown/O=SomeOrg/CN=client" openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt openssl genrsa -out server.key 4096 openssl req -new -key server.key -out server.csr -subj "/C=US/ST=Some State/L=FancyTown/O=SomeOrg/CN=server" openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 02 -out server.crt

  • 将它们移至更方便的位置 mkdir /etc/ssl_ ; mv * /etc/ssl_

  • 安装 webserver 和 mod_ssl yum install -y httpd mod_ssl

  • 清除默认 TLS 配置 truncate -s0 /etc/httpd/conf.d/ssl.conf

  • 所有 VHost 的通用 TLS 配置,/etc/httpd/conf.d/00-ssl.conf ``` LoadModule ssl_module modules/mod_ssl.so

监听 443 https SSLCACertificateFile /etc/pki/tls/certs/ca-bundle.crt SSLStaplingCache shmcb:/run/httpd/stapling_cache(128000) SSLUseStapling 关闭

SSLPassPhraseDialog exec:/usr/libexec/httpd-ssl-pass-dialog SSLSessionCache shmcb:/run/httpd/sslcache(512000) SSLSessionCacheTimeout 300 SSLRandomSeed 启动文件:/dev/urandom 256 SSLRandomSeed 连接内置 SSLCryptoDevice 内置

SSLStrictSNIVHost勾选 SSLProtocol +TLSv1.2 -TLSv1.1 -TLSv1 -SSLv3 SSLHonorCipherOrder

SSLCompression 关闭 SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:-ECDHE-RSA-RC4-SHA:ECDHE-RSA-AE S256-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:-RC4-SHA:AES256- GCM-SHA384:AES256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA ```

  • VHost 配置/etc/httpd/conf.d/50-ssl-vhost.conf

``` ServerAlias localhost.localdomain localhost ServerName server SSLEngine on SSLCertificateFile /etc/_ssl/server.crt SSLCertificateKeyFile /etc/_ssl/server.key SSLCertificateChainFile /etc/_ssl/ca.crt SSLCACertificateFile /etc/_ssl/ca.crt

    SSLVerifyClient require
    SSLVerifyDepth  10

    DocumentRoot /var/www/html

    <Directory /var/www/html>
            Require all granted
    </Directory>

    ErrorLog logs/ssl_error_log
    TransferLog logs/ssl_access_log

```

  • 创建index.html测试文件 echo 'It works\!' > /var/www/html/index.html

  • 启动 httpd

systemctl enable --now httpd

  • 添加主机名

echo '127.0.1.1 server' >> /etc/hosts

  • 测试

这有效(身份验证成功): ( echo -en 'GET / HTTP/1.1\r\nHost: server\r\n\r\n' ; sleep 2) | openssl s_client -CAfile /etc/_ssl/ca.crt -cert /etc/_ssl/client.crt -key /etc/_ssl/cli ent.key -connect server:443 -servername server

这不行,我们没有提供正确的证书:

( echo -en 'GET / HTTP/1.1\r\nHost: server\r\n\r\n' ; sleep 2) | openssl s_client -CAfile /etc/_ssl/ca.crt -connect server:443 -servername server

答案2

针对我们的情况,我们最终做出了三项改变:

  1. 取消注释 SSLCertificateChainFile 并将其设置为 RapidSSL 的证书链文件(谁颁发了我们的证书)。

  2. 将 SSLCACertificateFile 更改为第三方颁发者(颁发其证书的机构)的 CA 链文件。

  3. 从指令中删除了 SSLCACertificateFile。

一旦我们改变这些并重新启动,双向认证就会起作用,他们就可以访问 API。

感谢@fuero 的帮助。

相关内容