PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证
PKI - 借助Nginx 实现Https_使用CA签发证书
客户端使用自签名证书供服务端验证的作用和意义主要体现在以下几个方面:
总的来说,客户端使用自签名证书供服务端验证可以加强通信的安全性和可靠性,确保通信双方的身份和数据的安全,建立起信任关系,从而提高整体系统的安全性。
要在 Nginx 中实现客户端使用自签名证书供服务器验证,需要执行以下步骤:
openssl genrsa -out client.key 2048
这个命令生成了一个 2048 位的 RSA 密钥对,其中私钥保存在 client.key
文件中。
openssl req -x509 -new -nodes -key client.key -subj "/CN=client" -days 10000 -out client.crt
这个命令生成了一个自签名的客户端证书。
-x509
参数表示生成的证书是自签名的 X.509 证书,
-new
参数表示生成一个新的证书请求,
-nodes
参数表示不加密生成的私钥,
-key
参数指定了用于生成证书的私钥,
-subj
参数用于指定证书的主题信息,其中 /CN=client
表示通用名称 (Common Name) 是 “client”,
-days
参数表示证书的有效期
-out
参数指定了输出的证书文件名。
通过这些命令,成功生成了一个自签名的客户端证书和私钥,可以用于客户端与服务器之间的安全通信。
请注意,这些证书和密钥是自签名的,因此在生产环境中可能需要进行更严格的安全性配置。
在 Nginx 的配置文件中,添加以下 SSL 配置,以指定客户端证书和 CA 证书,并启用客户端证书验证:
server {
listen 443 ssl;
ssl on;
ssl_certificate /cert/server.crt;
ssl_certificate_key /cert/server.key;
ssl_client_certificate /cert/client.crt;
ssl_verify_client on;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
...
}
以下是每一项的含义解释:
ssl on;
:
ssl_certificate /cert/server.crt;
:
server.crt
是服务器的公钥证书,用于向客户端证明服务器的身份。这个证书将由服务器发送给客户端,以供客户端验证服务器的身份。ssl_certificate_key /cert/server.key;
:
server.key
是服务器的私钥,用于解密客户端发送的加密数据。私钥必须与证书配对,并且只有持有私钥的服务器才能解密使用相应证书加密的数据。ssl_client_certificate /cert/client.crt;
:
client.crt
是用于验证客户端证书的 CA 证书。当 ssl_verify_client on;
时,服务器将使用指定的客户端 CA 证书对客户端发送的证书进行验证。ssl_verify_client on;
:
on
时,Nginx 将要求连接客户端提供有效的客户端证书,并使用 ssl_client_certificate
中指定的 CA 证书对其进行验证。ssl_session_cache shared:SSL:1m;
:
ssl_session_timeout 10m;
:
ssl_ciphers HIGH:!aNULL:!MD5;
:
ssl_prefer_server_ciphers on;
:
on
时,服务器将优先选择服务器端指定的密码套件,而不是客户端指定的密码套件。这有助于防止客户端通过协商使用较弱的密码套件。通过正确配置这些 SSL 选项,您可以提高您的 Nginx 服务器的安全性,并确保 SSL/TLS 连接的机密性和完整性。
通过这个配置,Nginx 将在客户端建立连接时要求客户端提供有效的证书,并使用指定的 CA 证书对其进行验证。只有当客户端提供的证书被成功验证后,Nginx 才会允许连接建立,并允许客户端访问受保护的资源。
改完 Nginx 配置后,重新加载或重启 Nginx 服务,使更改生效。
sudo systemctl reload nginx
现在,Nginx 已经配置为要求客户端使用自签名证书进行验证。当客户端发起连接时,Nginx 将验证客户端提供的证书是否由指定的 CA 签名,以及证书的有效性。如果验证通过,Nginx 将允许连接;否则,将拒绝连接。
请注意,客户端证书验证是双向的,即服务器会验证客户端提供的证书。因此,客户端在发起连接时需要提供有效的客户端证书和私钥。
执行
cur1 https://artisan.com --resolve artisan.com:443:192.68.3.103
返回
<html>
<head><title>400 No required ssL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SsL certificate was sent</center>
<hr><center>nginx/1.16.1</center>
</body>
</htm1>
服务器返回了一个 400 Bad Request 错误,指示客户端没有发送必需的 SSL 证书。这是因为服务器配置了要求客户端提供 SSL 证书,但客户端在连接时未提供有效的 SSL 证书。
如何解决呢?
可以通过以下几种方式来解决这个问题:
提供有效的客户端 SSL 证书: 确保客户端在连接时提供了有效的 SSL 证书。可以使用生成的客户端证书来进行连接。
检查 SSL 配置: 检查服务器端的 SSL 配置,确保已正确启用客户端证书验证,并且指定了正确的客户端 CA 证书路径。
调试连接: 可以使用 OpenSSL 工具来模拟客户端连接并进行调试,以查看服务器的 SSL 配置是否正确。例如,您可以使用以下命令进行连接:
openssl s_client -connect artisan.com:443 -CAfile /path/to/ca.crt -cert /path/to/client.crt -key /path/to/client.key
其中,/path/to/ca.crt
是客户端 CA 证书的路径,/path/to/client.crt
和 /path/to/client.key
是客户端证书和私钥的路径。通过这个命令,您可以模拟客户端连接并查看服务器的 SSL 配置是否正确。
检查服务器日志: 检查服务器的日志文件,查看是否有关于 SSL 握手失败的错误消息。这些日志可以提供更多的细节,帮助您确定问题所在。
我们 提供有效的客户端 SSL 证书继续试下
curl https://artisan.com --cacert /cert/ca.crt --cert /cert/client.crt --key /cert/client.key --resolve artisan.com:443:192.168.3.103
--cacert /cert/ca.crt
客户端验证服务端用--cert /cert/client.crt --key /cert/client.key
服务端验证客户端用 ,这个私钥不会发送给服务端,仅作为验证使用OK, 可以正常访问。
完成双向认证后,如果想在浏览器中安装客户端证书以便进行访问,可以将客户端证书和私钥导出为 PKCS#12 格式 (PFX 文件),然后在浏览器中导入该文件。
下面是执行的步骤:
将客户端证书和私钥导出为 PKCS#12 格式: 使用以下命令将客户端证书和私钥导出为 PKCS#12 格式的 PFX 文件:
openssl pkcs12 -export -inkey /cert/client.key -in /cert/client.crt -out client.pfx
这个命令将 client.crt
和 client.key
文件导出到一个名为 client.pfx
的 PKCS#12 文件中。
导入 PFX 文件到浏览器中: 根据使用的浏览器不同,导入 PFX 文件的步骤可能会有所不同。一般来说,可以按照以下步骤来导入证书:
client.pfx
文件,并输入密码(如果有的话)。通过执行这些步骤,浏览器就可以使用导入的客户端证书来进行与服务器的双向认证的安全通信。请注意,具体的操作步骤可能因浏览器版本和操作系统而有所不同,建议根据使用的浏览器和操作系统查阅相关文档以获取详细的指导。
[root@localhost cert]# openssl pkcs12 -export -inkey /root/cert/client.key -in /root/cert/client.crt -out client.pfx
Enter Export Password:
Verifying - Enter Export Password:
[root@localhost cert]#
[root@localhost cert]# ll
total 12
-rw-r--r--. 1 root root 1090 Feb 11 15:14 client.crt
-rw-r--r--. 1 root root 1675 Feb 11 15:13 client.key
-rw-r--r--. 1 root root 2365 Feb 11 16:21 client.pfx
[root@localhost cert]#
[root@localhost cert]#
[root@localhost cert]#
导入