Raymond Raymond

Docker with WSL 2, SSL Proxy and SSL Certificate Problem

event 2022-06-20 visibility 14,497 comment 0 insights toc
more_vert
insights Stats
Docker with WSL 2, SSL Proxy and SSL Certificate Problem

In many companies, proxy including MITM (man-in-the-middle) SSL forward proxy are added to enhance network security. This can cause problems when you use Docker Desktop with WSL 2 base engine. For example, when you need to connect to internet to download packages for your applications, the https may not work due to error - SSL certificate problem: unable to get local issuer certificate

This article provides some learnings I had in the past few days and the resolutions to fix these problems. 

Environment

  • Host OS: Windows 10
  • WSL 2 distro: Ubuntu 20.04
  • Docker version: 4.2.0. WSL 2 is used as base engine.
  • Proxy is enforced in the network (i.e. SSL forward proxy occurs).

These issues can apply to Docker in Ubuntu or other WSL Linux distros, Linux distros, or Docker in Hyper-V virtual machines, etc.

Prerequisites

The high-level approach to fix this problem is to add the proxy certificate for example, Zscaler's root certificate to your docker images as part of docker build. If you don't know the specific certificate, check with your IT network security team.

If you know it, you can export the certificate directly by following these steps:

warning The following step is for demo purpose only and the actual certificate name and path in your company can be different. 
  • Type certmgr.msc using Windows search button.
  • In the window, find out the certificate of the proxy:
    2022062090015-image.png
  • Double click the certificate row and go to Details tab:
    2022062090124-image.png
  • Click button Copy to File.
  • Click Next button:
    2022062090201-image.png
  • Select Base-64 encoded X.509 (.CER)
  • Choose the path and finish the export. For this article, we will call this certificate as myproxy.cer.
  • Copy this certification file into your WSL distro.
  • Install openssl package if not installed:
    sudo apt-get install openssl
  • Use the following command line to convert
    openssl x509 -inform PEM -in <filepath>/myproxy.cer -out myproxy.crt
  • We will use myproxy.crt in the following sections. 

Double-confirm the issue

Before we dive into the solutions, let's double confirm you have this issue. 

Scenario 1 - openssl connection

Logon to your Ubuntu WSL 2 distro and use openssl to verify.

openssl s_client -connect https://the-domain-you-are-connecting-to.com -showcerts

If your company's proxy cert is not trusted in the distro, the following error can show:

Verify return code: 20 (unable to get local issuer certificate)

Scenario 2 - node:gallium-alpine

Create a Dockerfile file in a project folder. Add the following content:

FROM node:gallium-alpine

WORKDIR /app

RUN apk update && apk add bash netcat-openbsd

RUN ["echo", "Hello, Kontext!"]

Run docker command under the project folder context:

docker build .

The following error will show up:

fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
140124873489224:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913:
ERROR: https://dl-cdn.alpinelinux.org/alpine/v3.13/main: Permission denied
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/main: No such file or directory
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
140124873489224:error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed:ssl/statem/statem_clnt.c:1913:
ERROR: https://dl-cdn.alpinelinux.org/alpine/v3.13/community: Permission denied
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.13/community: No such file or directory

Scenario 3 - amazon/aws-cli:2.1.35

Create another project folder with docker file Dockerfile:

FROM amazon/aws-cli:2.1.35

WORKDIR /app

RUN yes y | yum install jq

RUN ["echo", "Hello, Kontext!"]

Run docker command under the project folder context:

docker build .

The following error will show up:

failure: repodata/repomd.xml from amzn2-core: [Errno 256] Mo more mirrors to try.
https://cdn.amazonlinux.com/2/core/2.0/x86_64/****** [Errno 14] curl#60 - "SSL certificate problem: unable to get local issuer certificate"

So all the three scenarios complain about local issuer certificate issue. Thus the resolution is simple - adding the proxy certificate myproxy.crt to the trusted store in the distro or container.

Solutions to fix SSL local issuer certificate issue

Now let's add the solutions for each of the three scenarios listed above.

Scenario 1 - openssl connection

To fix this issue, we just need to trust the certificate using the following command:

$ sudo apt-get install -y ca-certificates
$ sudo cp myproxy.crt /usr/local/share/ca-certificates
$ sudo update-ca-certificates

Then run the OpenSSL connection command again, it should work like a charm.

Scenario 2 - node:gallium-alpine

AS the image name suggests, it is based on Alpine Linux. To update the certificates in Alpine, we need to connect to internet thus we cannot add it directly (Correct me if I am wrong as I am not a Linux expert). One workaround is to replace Alpine repositories file (/etc/apk/repositories) to change https to http.

This can be done by adding a line into docker file:

FROM node:gallium-alpine

WORKDIR /app

RUN sed -i 's/https/http/' /etc/apk/repositories

RUN apk update && apk add bash netcat-openbsd

RUN ["echo", "Hello, Kontext!"]

Now it should also work.

warning By changing from https to http, it can add security concerns. Thus please use it cautiously. Another approach is to change your base image to use other Linux/UNIX distros. 

Scenario 3 - amazon/aws-cli:2.1.35

Similar as scenario 2, we just need to either avoid SSL or trust the proxy cert myproxy.crt.

Add myproxy.crt to your project folder and copy it to Docker image and then trust it there:

FROM amazon/aws-cli:2.1.35

WORKDIR /app

COPY myproxy.crt /etc/pki/ca-trust/source/anchors/
RUN update-ca-trust extract

RUN yes y | yum install jq

RUN ["echo", "Hello, Kontext!"]

This now also works. The highlighted part can be different from one Linux distro to another, please change them accordingly to apply to your own environments. The AWS CLI docker image is based on Amazon Linux 2, thus I am using the above two command lines. 

I hope this article helps you to get your container application build or other build work under company proxy environment. Let me if you find other issues and I will try my best to help.

References

Installing a root CA certificate in the trust store | Ubuntu

More from Kontext
comment Comments
No comments yet.

Please log in or register to comment.

account_circle Log in person_add Register

Log in with external accounts