VPS Proof of Concept for Docker and Traefik - Page 2

CSF Docker Configuration

Disable Docker daemon automatic iptable rules with an override at the ExecStart section of the main docker.service. This prevents the Docker daemon from configuring iptables.

sudo nano /etc/systemd/system/multi-user.target.wants/docker.service

Append --iptables=false to ExecStart=/usr/bin/dockerd -H fd://. For example,

ExecStart=/usr/bin/dockerd -H fd:// --iptables=false

If Docker gets an upgrade during apt-get dist-upgrade, this docker.service file may get overwritten and you will need update it to override ExecStart again.

For Docker iptables, create a csfpost.sh script that will be triggered after the ConfigServer firewall has been started or reloaded.

sudo nano /etc/csf/csfpost.sh
csfpost.sh
#!/bin/sh

echo "[DOCKER] Setting up FW rules."

iptables -N DOCKER

# Masquerade outbound connections from containers
iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE

# Accept established connections to the docker containers
iptables -t filter -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

# Allow docker containers to communicate with themselves & outside world
iptables -t filter -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
iptables -t filter -A FORWARD -i docker0 -o docker0 -j ACCEPT

echo "[DOCKER] Done."

Make the script executable.

sudo chmod +x /etc/csf/csfpost.sh

Add an exception to allow container traffic through the firewall.

sudo nano /etc/csf/csf.allow
csf.allow
# The following IP addresses will be allowed through iptables

172.17.0.0/16 # Docker

Reload the systemd daemon to pickup these changes, restart the docker daemon and reload the ConfigServer firewall.

sudo systemctl daemon-reload

sudo systemctl restart docker

sudo csf -r

Basic Auth

This will be used to password protect applications as needed.

Use the htpasswd utility included in the apache2-utils package to create an encrypted password.

sudo apt-get install apache2-utils

Generate the password with htpasswd. For example, user admin and password secret.

htpasswd -nb admin secret

Copy the output, it will be added to the traefik.toml file created in the next step. For example, copy:

admin:$apr1$m7bjJGAs$yoFBU4EmPy0wAQuKccomQ/

Traefik

Use Docker Compose to setup Traefik reverse proxy and load balancer as a docker container. Within the home directory, create a new directory named docker for the configuration files. Create another directory for docker/traefik files.

cd ~/
mkdir docker
mkdir docker/traefik

Create a traefik/traefik.toml to configure entry points and the web provider for access to the dashboard interface.

nano docker/traefik/traefik.toml
traefik.toml
defaultEntryPoints = ["http", "https"]

[web]
address = ":8080"
  [web.auth.basic]
  users = ["admin:$apr1$m7bjJGAs$yoFBU4EmPy0wAQuKccomQ/"]

[entryPoints]

[entryPoints.http]
address = ":80"
[entryPoints.https.redirect]
entryPoint = "http"

# [entryPoints.https]
# address = ":443"

# [entryPoints.https.tls]

# [acme]
# email = "myemail@example.com"
# storage = "acme.json"
# entryPoint = "https"
# onDemand = false
# OnHostRule = true
# [acme.httpChallenge]
# entryPoint = "http"
# provider = ""
# delayBeforeCheck = 0

Traefik has built in support for the free Let’s Encrypt SSL certificate retrieval service. A server with a public domain is needed for the service to validate. The traefik.toml file example above contains a commented stub for reference.

Let’s Encrypt has permanently disabled TLS-SNI-0x challenge due to a vulnerability and Traefik prior to 1.5 was using TLS-SNI-01 challenge by default. Refer to the [acme] configuration docs for the new [acme.httpChallenge] section as needed.

Dockerfile

Create a traefik/dockerfile to add the traefik.toml to the image.

nano docker/traefik/dockerfile
dockerfile
FROM traefik
ADD traefik.toml .
EXPOSE 80
EXPOSE 8080
# EXPOSE 443

Create a traefik/docker-compose.yml file to configure Traefik services and networks.

docker-compose.yml
version: '2'

services:
  proxy:
    build: .
    restart: always
    command: --docker --logLevel=DEBUG
    networks:
      - webgateway
    ports:
      - "80:80"
#      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

networks:
  webgateway:
    driver: bridge

Update CSF firewall configuration to allow traffic on the password protected port 8080.

sudo nano /etc/csf/csf.conf

Append 8080 to the list of TCP ports. For example,

# Allow incoming TCP ports
TCP_IN = "20,21,22,25,53,80,110,143,443,465,587,993,995,8080"

# Allow outgoing TCP ports
TCP_OUT = "20,21,22,25,53,80,110,113,443,587,993,995,8080"

Use docker-compose to create the Docker container and run the traefik application.

docker-compose -f ~/docker/traefik/docker-compose.yml up -d

Testing

Navigate to the VM in a browser using the IP address over port 8080 to login to the Traefik dashboard. For example, http://172.30.0.10:8080 which redirects to http://172.30.0.10:8080/dashboard/#/

Create a whoami/docker-compose.yml file to configure another container application labeled whoami. The image for this container uses a tiny Go webserver that prints system information and HTTP request to output.

mkdir ~/docker/whoami

nano ~/docker/whoami/docker-compose.yml
docker-compose.yml
version: '2'

services:
  app:
    image: emilevauge/whoami
    networks:
      - web
    labels:
      - "traefik.backend=whoami"
      - "traefik.frontend.rule=PathPrefixStrip: /whoami" # IP/whoami/
      # - "traefik.frontend.rule=Host:vm.ubuntuserver.whoami.com"

networks:
  web:
    external:
      name: traefik_webgateway

Access the application in a browser using the VM IP address. For example, http://172.30.0.10. To use a domain name, add 172.30.0.10 vm.ubuntuserver.whoami.com to your computers hosts file. Then remove the comment for the Host frontend rule in the whoami/docker-compose.yml.

When you’re done testing everything and ready to enable the firewall, disable the testing flag.

sudo nano /etc/csf/csf.conf

Set TESTING = "0" and reload.

sudo csf -r

Resources

comments powered by Disqus