信任用于安全服务间通信的自签名 SSL/TLS 证书
Trust Self-signed SSL/TLS Certificate for Secure Inter-service Communication
我们在服务器上编排了微服务 运行。 nginx 服务充当微服务之间的代理。我们希望使用我们的自签名证书在 SSL 上进行所有通信。
我们想将我们的私有 CA 添加到每个服务(运行 在 Debian Buster 上),以便它在该服务中的任何地方都被认为是有效的。我们生成我们的服务器证书和 CA 如下:
# Generate Root CA Certificate
openssl genrsa -des3 -out CA-key.pem 2048
openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem
# Generate a Signing a Server Certificate
openssl genrsa -des3 -out server-key.pem 2048
openssl req –new –config openssl.cnf –key server-key.pem –out signingReq.csr
openssl x509 -req -days 365 -in signingReq.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out server-cert.pem
但是,我们无法让微服务将证书视为有效并信任它。在微服务中使用Python的请求库发出get请求时,抛出如下异常:
requests.exceptions.SSLError: HTTPSConnectionPool(host='server.name', port=443): Max
retries exceeded with url: /url/to/microservice2/routed/via/nginx/ (Caused by
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate
verify failed: self signed certificate (_ssl.c:1076)')))
目前我们尝试过的:
- 正在将证书复制到 /usr/share/ca-certificate/ 和 运行
sudo dpkg-reconfigure ca-certificates
and/or update-ca-certificates
命令。
- 将
REQUESTS_CA_BUNDLE
环境变量设置为 /path/to/internal-CA-cert.pem
- 将
SSL_CERT_FILE
环境变量设置为 /path/to/internal-CA-cert.pem
唯一可行的解决方法是在 requests.get(url, params=params, verify=False, **kwargs)
中设置 valid=False
,以忽略 SSL 证书的有效性。但是,这不是我们想要为所有微服务和通信实施的工作流程。
解决方案是将自签名服务器证书(用我们自己的 CA 签名)复制到 /usr/local/share/ca-certificates
目录并使用 debian 发行版中提供的 update-ca-certificates
(类似的解决方案可用对于其他 linux 发行版)。
cp /path/to/certificate/mycert.crt /usr/local/share/ca-certificates/mycert.crt
update-ca-certificates
然而,棘手的部分是上述解决方案不足以让 python 请求库将证书视为有效。要解决这个问题,必须将自签名服务器证书附加到 cat-certificates.crt
,然后将环境变量 REQUESTS_CA_BUNDLE
设置到该附加文件。
cat /path/to/certificate/mycert.crt >>/etc/ssl/certs/ca-certificates.crt
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
我们在服务器上编排了微服务 运行。 nginx 服务充当微服务之间的代理。我们希望使用我们的自签名证书在 SSL 上进行所有通信。
我们想将我们的私有 CA 添加到每个服务(运行 在 Debian Buster 上),以便它在该服务中的任何地方都被认为是有效的。我们生成我们的服务器证书和 CA 如下:
# Generate Root CA Certificate
openssl genrsa -des3 -out CA-key.pem 2048
openssl req -new -key CA-key.pem -x509 -days 1000 -out CA-cert.pem
# Generate a Signing a Server Certificate
openssl genrsa -des3 -out server-key.pem 2048
openssl req –new –config openssl.cnf –key server-key.pem –out signingReq.csr
openssl x509 -req -days 365 -in signingReq.csr -CA CA-cert.pem -CAkey CA-key.pem -CAcreateserial -out server-cert.pem
但是,我们无法让微服务将证书视为有效并信任它。在微服务中使用Python的请求库发出get请求时,抛出如下异常:
requests.exceptions.SSLError: HTTPSConnectionPool(host='server.name', port=443): Max
retries exceeded with url: /url/to/microservice2/routed/via/nginx/ (Caused by
SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate
verify failed: self signed certificate (_ssl.c:1076)')))
目前我们尝试过的:
- 正在将证书复制到 /usr/share/ca-certificate/ 和 运行
sudo dpkg-reconfigure ca-certificates
and/orupdate-ca-certificates
命令。 - 将
REQUESTS_CA_BUNDLE
环境变量设置为/path/to/internal-CA-cert.pem
- 将
SSL_CERT_FILE
环境变量设置为/path/to/internal-CA-cert.pem
唯一可行的解决方法是在 requests.get(url, params=params, verify=False, **kwargs)
中设置 valid=False
,以忽略 SSL 证书的有效性。但是,这不是我们想要为所有微服务和通信实施的工作流程。
解决方案是将自签名服务器证书(用我们自己的 CA 签名)复制到 /usr/local/share/ca-certificates
目录并使用 debian 发行版中提供的 update-ca-certificates
(类似的解决方案可用对于其他 linux 发行版)。
cp /path/to/certificate/mycert.crt /usr/local/share/ca-certificates/mycert.crt
update-ca-certificates
然而,棘手的部分是上述解决方案不足以让 python 请求库将证书视为有效。要解决这个问题,必须将自签名服务器证书附加到 cat-certificates.crt
,然后将环境变量 REQUESTS_CA_BUNDLE
设置到该附加文件。
cat /path/to/certificate/mycert.crt >>/etc/ssl/certs/ca-certificates.crt
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt