I recently needed to secure my Docker host instance simply with a basic username and password authentication as I mostly find the certificate creation steps tedious. Docker has no built-in username/password authentication support so I thought I could have a HTTP proxy server which asks for a password on top of Docker Remote API server. Below you will find how you can secure your Docker host using username and password, namely HTTP Basic Authentication.
By default, your Docker installation uses a Unix socket binded to localhost if you installed Docker by yourself and that is not open to access from outside world (read more about Docker Security). By exposing an endpoint to the outside world, you will increase the attack surface (something not good), if you are not extensively worried about it.
Caution: HTTP Basic Authentication uses username/password credentials transferred without any encryption. If you are serious about security, please secure your Docker host using TLS/SSL.
Hope you find it useful. Here we go:
Step 1: Install nginx
First, ssh
into the Docker host machine you have. Installing nginx on
Debian/Ubuntu is as simple as:
sudo apt-get install nginx
Step 2: Create passsword file
This file will contain your access to Docker instance.
sudo htpasswd -c /etc/nginx/.htpasswd YOUR_USERNAME
Running this will prompt you a password, pick a password and keep that in mind.
Step 3: Configure nginx
In order to access Docker API running on the Unix socket locally, nginx
process must have root privileges. Therefore edit /etc/nginx/nginx.conf
with user
configuration changed to root
user.
The following command do it for you:
sudo sed -i 's/user .*;/user root;/' /etc/nginx/nginx.conf
Step 4: Add Docker site
Now we need to expose the port 4243 as a proxy for the Unix socket running locally with HTTP Basic Authentication. The following command will create the nginx site for you:
sudo tee /etc/nginx/sites-enabled/docker <<EOF
upstream docker {
server unix:/var/run/docker.sock;
}
server {
listen 4242 default_server;
location / {
proxy_pass http://docker;
auth_basic_user_file /etc/nginx/.htpasswd;
auth_basic "Access restricted";
}
}
EOF
Step 5: Restart nginx
sudo service nginx restart
You must not see any errors at this step.
Step 6: Profit!
If all has gone well, you can now use your Docker instance with HTTP Basic Authentication with the username/password you defined earlier.
You should be able to access the Docker REST API running on your host
using the following while you’re still in ssh
:
curl -i http://username:password@localhost:4242/info
Alternatively, you can use:
curl -i http://username:[email protected]:4242/info
to verify if your basic auth works file. You can now even use your browser to verify if this works.
Known issues
Docker client currently does not accept URLs with basic authentication credentials (e.g. tcp://user:[email protected]:4243). I have an outstanding proposal for this.
Note: My Docker.DotNet library supports HTTP basic authentication thanks to Andreas Bieber!
Leave your thoughts