Exchangelib on Docker with custom SSL Certificates

1.9k views Asked by At

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

1

There are 1 answers

0
lsabi On BEST ANSWER

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