Skip to content
/ vlad Public

PoC implementing TLS Certificate `OU=` access to swarm resources via an authz plugin

License

Notifications You must be signed in to change notification settings

stevommmm/vlad

Repository files navigation

Vlad the validator 🧛

⚠️ Super early days, we live in master. Vlad is still young and subject to change.

Vlad forces client interactions to be limited to the resources prefixed with the same OU= as the user TLS certificate. With OU=tst I could interact with service tst_thing and tstthing but not different_service. The same principle holds for networks, volumes and every other resource type. A public OU is automatically added for all clients.

Because we can't mutate the response to the client, global indexing is allowed, but deletion, inspection, update, etc is restricted to the client OU prefix.

Installation | Development | Docker Hub

Certificate requirements

Following along with https://docs.docker.com/engine/security/https/ we need to make a slight modification to the client certificate signing request.

The line

openssl req -subj '/CN=client' -new -key key.pem -out client.csr

Becomes the following (where groupname is set)

openssl req -subj '/CN=client/OU=groupname' -new -key key.pem -out client.csr

Installation

docker plugin install c45y/vlad --alias vlad

To complete, add vlad to your authorization-plugins configuration in daemon.json.

A small number of plugin configuration options can be toggled:

  • VLAD_BIND_MOUNT sets the ability to perform host bind mounts, default false
  • VLAD_BIND_PORTS toggles port binding outside the 30000-61000 range, default false

Current configuration can be seen using:

docker plugin inspect -f {{.Settings.Env}} vlad

Development Installation

From your command line:

docker build -t rootfsimage .
docker create --name vlad_container rootfsimage true
mkdir -p rootfs
docker export vlad_container | tar -x -C rootfs
docker plugin create vlad .
docker plugin enable vlad:latest  # Enable our dev plugin
sudo ./scripts/deploy.sh  # Generate docker CA/Node/Client certificates and deploy daemon.json
sudo ./scripts/docker.sh info  # Uses the client certificate via TLS + vlad authz
sudo docker info  # Uses existing unix socket (which is blanket allowed by vlad)

Tests

A small test harness based on the docker-bench-security setup to run through known valid/invalid operations. Runs a docker daemon with vlad under a mktemp directory which is destroyed at the end of testing.

systemctl stop docker  # Can't have another one running
cd test && sudo ./test

Output looks something like

Calling check_tls_volume_bad_bind
> docker volume create --opt=type=bind --opt=device=/tmp testgroup_4711accf0672
Error response from daemon: authorization denied by plugin c45y/vlad:latest: You cannot bind mount.
[PASS][check_tls_volume_bad_bind]

Calling check_tls_volume_bad_ou
> docker volume create badgroup_29d63f46fa7f
Error response from daemon: authorization denied by plugin c45y/vlad:latest: That volume is outside your OU prefix. ('public', 'testgroup')
[PASS][check_tls_volume_bad_ou]

Calling check_tls_volume_ou
> docker volume create testgroup_3c2739947c82
testgroup_3c2739947c82
[PASS][check_tls_volume_ou]


===================
Completed tests: 11
Passed tests:    11

Todo