3

I've built a Fastapi web app that relies on the library exchangelib. I'm working in an internal network, where a windows IIS signed a as root the certificate of the mail server. The certificate chain is made of only 2 levels: mail server certificate and root server certificate.

On an ubuntu 20.04 server I've added the two certificates under /usr/local/share/ca-certificates and updated the list via sudo update-ca-certificates. Until here it works with no problem.

When I use docker to build and run the container I get error message

exchangelib.errors.TransportError: HTTPSConnectionPool(host='**********', port=443): Max retries exceeded with url: /EWS/Exchange.asmx (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1124)')))

Here's the Dockerfile

FROM python:3.8.6-slim

WORKDIR .

COPY . .

RUN pip install -r requirements.txt

EXPOSE 8000

COPY ./ssl/CA.crt /usr/local/share/ca-certificates/CA.crt
RUN chmod 644 /usr/local/share/ca-certificates/CA.crt
RUN update-ca-certificates

COPY ./ssl/server.crt /usr/local/share/ca-certificates/server.crt
RUN chmod 644 /usr/local/share/ca-certificates/server.crt
RUN update-ca-certificates

CMD [ "uvicorn", "app:app", "--host", "0.0.0.0"]

I've changed the certificate permissions since I thought it would help, but with no result. Also, I run with every newly added certificate. But the certificates are added as 1 added is printed on the terminal when the RUN update-ca-certificates command is run.

I'm not sure if it's an issue with docker or with the library. The same certificates work on the bare-metal server, but not on docker.

Can anyone help? Thanks

I'm not understanding

lsabi
  • 3,641
  • 1
  • 14
  • 26
  • 1
    You probably need to tell requests to use the copied certificates. See suggestions at https://stackoverflow.com/questions/42982143/python-requests-how-to-use-system-ca-certificates-debian-ubuntu – Erik Cederstrand Dec 04 '20 at 09:48
  • It seems to be root of the problem. Although even trying to set the environment variable in the dockerfile seems to be not working (the path to the python's certificates does not change). – lsabi Dec 04 '20 at 14:17

1 Answers1

3

Ok, after more than a week spent on checking my certificates and what was going on with docker, @Erik Cederstrand enlightened me, suggesting to check the requests's certificate path.

It turned out that indeed it was set to a different location, not sure why. So, to be sure, I changed both REQUESTS_CA_BUNDLE and SSL_CERT_FILE environment variables to point to my ca certificates file (which is the system one on ubuntu/debian).

Anyway, my final Dockerfile looks as follows

FROM python:3.8-slim

WORKDIR .

COPY . .

ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
ENV REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt

COPY ./ssl/* /usr/local/share/ca-certificates/

RUN update-ca-certificates

RUN pip install -r requirements.txt

EXPOSE 8000

CMD [ "uvicorn", "app:app", "--host", "0.0.0.0"]

Many thanks to @Erik Cederstrand

lsabi
  • 3,641
  • 1
  • 14
  • 26