0

We have an orchestration of microservices running on a server. An nginx service is acting as a proxy between microservices. We would like to have all the communications on SSL with our self-signed certificates.

We want to add our private CA to every service (running on Debian Buster), so that it is considered valid everywhere within that service. We generate our server certificate and CA as follows:

# 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

However, we can't make the microservices to consider the certificate as valid and trust it. When a get request is issued using the request library of Python in the micro-service, the following exception is thrown:

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)')))

What we have tried so far:

  • Copying the certificate to /usr/share/ca-certificate/ and running the sudo dpkg-reconfigure ca-certificates and/or update-ca-certificates commands.
  • Set the REQUESTS_CA_BUNDLE env variable to /path/to/internal-CA-cert.pem
  • Set the SSL_CERT_FILE env variable to /path/to/internal-CA-cert.pem

The only workaround that works is setting the valid=False in requests.get(url, params=params, verify=False, **kwargs), to ignore the validity of the SSL certificate is ignored. But, this is not the worfklow we would want to implement for all the microservices and communications.

Amir
  • 2,259
  • 1
  • 19
  • 29
  • My guess is that a self-signed server certificate is not a self-signed CA. You probably need a self-signed CA and use that to sign your server certificates. – Richard Smith Apr 18 '20 at 07:03
  • I can generate a CA (certificate authority) and server certificate following this: https://www.simba.com/products/SEN/doc/Client-Server_user_guide/content/clientserver/configuringssl/signingca.htm . But which one shall I include in Nginx SSL configs, and which one in the service (which is actually a client of nginx) to be trusted? – Amir Apr 18 '20 at 09:44
  • I don't understand your setup, but if Python is raising the exception, then it probably wants the CA so that it can validate the other end's server certificate. – Richard Smith Apr 18 '20 at 09:58
  • @richard-smith The CA certificate associated witht the server certificate is already included in `/etc/ssl/certs/` of the service, but the service still considers the ssl connection still fails with `SSL: CERTIFICATE_VERIFY_FAILED]`. – Amir Apr 26 '20 at 18:11
  • @RichardSmith I edited the question to provide more details and clarify. – Amir Apr 26 '20 at 18:37

1 Answers1

-1

The solution was to copy the self-signed server certificate (signed with our own CA) to the /usr/local/share/ca-certificates directory and use the update-ca-certificates which is shipped in debian distributions (similar solution is available for other linux distributions).

cp /path/to/certificate/mycert.crt /usr/local/share/ca-certificates/mycert.crt
update-ca-certificates

However, the tricky part is that the above solution is not sufficient for the python request library to consider the certificate as valid. To resolve that, one has to append the self-signed server certificate to the cat-certificates.crt and then set the environment variable REQUESTS_CA_BUNDLE to that appended file.

cat /path/to/certificate/mycert.crt >>/etc/ssl/certs/ca-certificates.crt
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt
Amir
  • 2,259
  • 1
  • 19
  • 29