PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证
PKI - 数字签名与数字证书
使用 CA 签发证书的主要原因和作用如下:
建立信任关系: 使用 CA 签发的证书可以建立信任关系,客户端可以信任由公认的 CA 颁发的证书,从而确保与服务器之间的通信是安全可靠的。
保证身份验证: CA 对证书申请者进行身份验证,并在验证通过后签发证书。这样,服务器可以通过 CA 签发的证书来证明自己的身份,确保客户端与合法的服务器进行通信,防止中间人攻击。
保护通信数据: 证书中包含了公钥,可以用于加密通信数据。使用 CA 签发的证书可以保护通信数据的机密性,防止数据被窃取或篡改。
提供数据完整性: 证书中包含了数字签名,可以用于验证通信数据的完整性。使用 CA 签发的证书可以确保通信数据在传输过程中没有被篡改。
总之,使用 CA 签发证书可以确保通信的安全性、可靠性和完整性,为网络通信提供了重要的保护和信任基础。
如下OpenSSL 命令,用于生成自签名的 CA(Certificate Authority,证书颁发机构)证书以及服务器证书。
openssl genrsa -out ca.key 2048
这个命令生成了一个 2048 位的 RSA 密钥对,私钥保存在 ca.key
文件中。
openssl req -x509 -new -nodes -key ca.key -subj "/CN=artisan-ca.com" -days 5000 -out ca.crt
这个命令使用生成的 CA 密钥对生成了一个自签名的 CA 证书。
-x509
选项表示生成一个自签名的 X.509 证书,
-subj
选项用于指定证书的主题信息,
-days
选项用于指定证书的有效期,
-out
选项用于指定输出的证书文件名。
# 服务器的 RSA 密钥对
openssl genrsa -out server.key 2048
# 证书签名请求 (CSR)
openssl req -new -key server.key -subj "/CN=artisan.com" -out server.csr
这两个命令分别生成了服务器的 RSA 密钥对和证书签名请求 (CSR)。
首先使用 genrsa
命令生成了服务器的私钥 server.key
,然后使用 req
命令生成了 CSR 文件 server.csr
,其中 -subj
选项用于指定证书的主题信息。
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 5000
这个命令使用之前生成的 CA 密钥对和证书 (ca.crt
和 ca.key
) 对服务器的 CSR (server.csr
) 进行签名,生成了服务器的证书 server.crt
。
-CA
选项用于指定签署证书的 CA 证书,
-CAkey
选项用于指定 CA 的私钥
-CAcreateserial
选项用于生成一个序列号文件以跟踪已签署的证书,
-out
选项用于指定输出的证书文件名。
通过这些 OpenSSL 命令,就可以成功地生成了自签名的 CA 证书和服务器证书,并使用 CA 对服务器证书进行了签名,从而建立了一个简单的证书信任链。
创建和配置 Nginx 使用 HTTPS 自签名证书的步骤如下:
openssl genrsa -out server.key 2048
server.key
文件中。参数 2048
指定了密钥长度为 2048 位。
openssl req -x509 -new -nodes -key server.key -subj "/CN=artisan.com" -days 10000 -out server.crt
-x509
:表示生成自签名证书。-new
:创建一个新的证书请求。-nodes
:不加密生成的私钥。-key server.key
:指定使用之前生成的私钥文件 server.key
。-subj "/CN=yandun.com"
:指定证书的主题(Subject)。在这里,/CN=yandun.com
表示通用名称(Common Name)为 yandun.com
。-days 10000
:指定证书的有效期为 10000 天。-out server.crt
:将生成的证书保存到 server.crt
文件中。
openssl x509 -in server.crt -noout -text
-in server.crt
:指定要查看的证书文件。-noout
:不打印证书内容到标准输出。-text
:以文本形式显示证书内容。这些命令可以用来生成自签名的证书并查看证书的详细信息。
Issuer 和 Subject 是同一个机构, 说明是自签证书。
CA: TRUE 说明它是一个CA签发结构。
编辑 Nginx 的配置文件(通常位于 /etc/nginx/nginx.conf
或 /etc/nginx/sites-available/default
),并确保以下配置项已经添加或更新:
server {
.....
.....
ss1 on;
ss1_certificate /cert/server.crt;
ss1_certificate_key /cert/server.key;
# 暂不开启
#ss1_client_certificate /cert/client.crt;
#ssI_verify_client on;
ss1_session_cache shared:ssL:1m;
ss1_session_timeout 10m;
ss1_ciphers HIGH:!aNULL:!MD5;
ss1_prefer_server_ciphers on;
.....
.....
}
每个指令的含义如下:
ss1 on;
:
ss1_certificate /cert/server.crt;
:
/cert/server.crt
是服务器证书的路径。ss1_certificate_key /cert/server.key;
:
/cert/server.key
是服务器私钥的路径。#ss1_client_certificate /cert/client.crt;
:
#ss1_verify_client on;
:
on
可以启用客户端证书验证。ss1_session_cache shared:ssL:1m;
:
ssL
,大小为 1MB。ss1_session_timeout 10m;
:
ss1_ciphers HIGH:!aNULL:!MD5;
:
HIGH
表示使用高强度加密算法,同时禁用了一些不安全的加密套件,如 NULL
和 MD5
。ss1_prefer_server_ciphers on;
:
on
表示优先使用服务器端提供的加密套件。这些指令配置了 Nginx 流模块的 SSL/TLS 加密功能,包括了服务器证书、私钥、会话缓存等参数。
完成配置后,通过以下命令重启 Nginx 服务,以使更改生效:
sudo systemctl restart nginx
现在,Nginx 应该已经配置为使用自签名证书进行 HTTPS 加密通信。请确保防火墙已正确配置以允许流量通过 HTTPS 端口(默认为 443)。
我们可以看到 开启了Https以后,直接使用http的方式访问是行不通的
curl: (60) Peer's certificate issuer has been marked as not trusted by the user
More details here: http;//curl.haxx.se/docs/sslcerts.html
通过web访问 会弹出警告信息
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.
curl https://192.168.3.103 -k
可以通过在 curl
命令中添加 -k
或 --insecure
选项来关闭 curl
对证书的验证,从而允许直接访问未经验证的 HTTPS 网站。这样做会绕过证书验证过程,可能会存在安全风险,因此建议仅在测试或特殊情况下使用。
可以使用的命令:
curl https://192.168.3.103 -k
这个命令将直接访问 https://192.168.3.103
,而不会验证服务器证书的有效性。
请注意,使用 -k
选项会将连接置于不安全的状态,因为它不验证服务器证书的真实性,可能容易受到中间人攻击。因此,在生产环境中应避免使用此选项,以确保通信的安全性。
不能使用签发的server.crt 进行访问,错误信息如下
curl https:/artisan.com --resolve --cacert /cert/server.crt
artisan.com:443:192.168.3.103
cur1: (60) Peer's Certificate issuer is not recognized.
cur1: (60) Peer's Certificate issuer is not recognized.
错误信息表明 curl
无法验证服务器证书的签发者。这通常是由于未将 CA 证书正确指定给 curl
所致。我们使用 --cacert
选项指定了服务器证书,但似乎没有正确指定 CA 证书。
需要将 CA 证书正确指定给 curl
,以便 curl
可以使用它来验证服务器证书的签发者。以下是正确的命令:
curl https://artisan.com --resolve artisan.com:443:192.168.3.103 --cacert /cert/ca.crt
在这个命令中,--cacert
选项被用来指定 CA 证书的路径,这样 curl
就可以使用它来验证服务器证书的签发者。
curl https://artisan.com --resolve artisan.com:443:192.168.3.103 --cacert /cert/ca.crt
如上命令,OK
会报错如上信息, 因为我们签发的证书的csr中,使用的是域名 artisan.com
openssl req -new -key server.key -subj "/CN=artisan.com" -out server.csr
这个错误通常意味着服务器证书中指定的域名与请求的域名不匹配。这可能是因为正在使用的证书是针对另一个域名签发的,或者服务器配置不正确。
要解决这个问题,您可以采取以下步骤:
检查证书的域名: 确保服务器证书是针对正在访问的域名签发的。可以使用以下命令检查证书中的主题信息:
openssl x509 -in /cert/server.crt -noout -subject
如果主题信息中的域名与正在访问的域名不匹配,那么需要获取一个正确匹配的证书。
检查服务器配置: 确保服务器配置正确,将证书配置为与正在访问的域名匹配。检查服务器配置文件,确保域名和证书的匹配性。
重新签发证书: 如果服务器证书确实是针对错误的域名签发的,需要重新签发一个正确匹配的证书。使用正确的域名生成证书签名请求 (CSR),并使用 CA 对其进行签名。
更新 DNS 记录: 如果更改了服务器证书针对的域名,确保更新 DNS 记录,以便域名解析到正确的服务器 IP 地址。
检查证书链: 确保服务器证书的颁发机构是信任的,并且证书链是完整的。您可以使用以下命令检查证书链的完整性:
openssl s_client -connect artisan.com:443 -showcerts
如果证书链不完整或不信任,需要安装完整的证书链或信任颁发机构的根证书。
解决办法将证书信息追加到
/etc/pki/t1s/certs/ca-bunde.crt