Making Docker work behind NTLM proxy

Working in a corporate environment, it may come that web access is filtered through a proxy… and even an NTLM one which requiere MS-style authentication.

If you also are lucky enough to run Docker inside a Linux Virtual machine (not natively on Windows), your docker builds or package update operations may fail at first.

You may ease the building and running of docker containers by using an intermediate proxy (cntlm) that will authenticate your and forward your requests against the coprorate proxy, while acting as simpler (unanthenticated) proxy for your doacker daemon or containers.

Build images behind a proxy

My environment:

- Coporate NTLM proxy
- Windows 7 (running cntlm proxy properly configured, listenning to 127.0.0.1:9128, and NOT in gateway mode)
- Virtual Box 
- Centos 7 
- Docker 

Make docker daemon use the proxy of the Windows host

Not hard but a bit complex:

The first thing to take care of with all these virtualization layers is that 127.0.0.1 means something different for each layer !

The tricky part is to understand that Virtual box creates a specific NIC inside CentOS (address is 10.0.2.x with a default gateway of 10.0.2.2). The 10.0.2.2 IP address is redirected by Virtual Box to the 127.0.0.1 of Windows, on which cntlm proxy is listenning.

Last thing, the daemon needs to be aware of proxy at build time (download an image from web), while apt-get or yum may need to be aware of proxy at build time but also possibly at runtime.

In short, from docker daemon perspective, the proxy is 10.0.2.2:9128

Docker daemon setup

Create

/etc/systemd/system/docker.service.d/docker_http_proxy.conf

With content:

[Service]
Environment="HTTP_PROXY=http://10.0.2.2:9128/"
Environment="HTTPS_PROXY=https://10.0.2.2:9128/"

Then reload configuration and restart daemon

sudo systemctl daemon-reload
sudo systemctl restart docker

Build the image

Then you should run the build using buildtime-only proxy configuration:

docker build --build-arg http_proxy=http://10.0.2.2:9128 --build-arg https_proxy=https://10.0.2.2:9128 -t my_app .

TBC: is --build-args needed for yum update only ?

Run containers behind a proxy

Here the context is a bit different: we want a running container to access the web. Generraly speaking, it may not be the best idea in production environments, but it may still greatly help you to test or develop inside container.

Quick and dirty: rely on another container to provide the proxy

The simplest way is to use an already existing container, made specifically to provide transparent cntlm proxy service to others through Docker -link capability. It allows your application to address the proxy by name.

You should rather build this container from source (rather than blindly downloading it) as you will entrust it sufficiently with your logins and passwords.

Several cntml proxies are available, I choose to use jaschac/cntlm.

Download / build image with:

docker pull jaschac/cntlm

Start jashac/cntlm container:

docker run --name cntlm -e CNTLM_USERNAME=your_username -e CNTLM_DOMAIN=your_domain -e CNTLM_PROXY_URL=your_parent_ proxy -e CNTLM_PROXY_PORT=your_parent_proxy_port -e CNTLM_PASSNTLMv2=yourhash -d jaschac/cntlm

Then start your applciation container with:

docker run --link cntlm:cntlm -it my_app /bin/bash

Note the –link option that allow your application to resolve the cntlm host destite in another container.

Optional: set the proxy env in the dockerfile:

ENV http_proxy http://cntlm:3128
ENV https_proxy https://cntlm:3128

Make your container aware of the external proxy

Use the same address (corresponding to Windows 127.0.0.1 through Virtual box) to let your container access the Windows cntlm proxy at runtime.

TBD: remains to be tested

ENV http_proxy http://10.0.2.2:9128
ENV https_proxy https://10.0.2.2:9128

Leave a Reply

Your email address will not be published. Required fields are marked *