This is a playbook for Alpine sys installation that provides some really basic hardening and configurations to run Docker without root. It's a collection of small scripts and playbooks that were half-heartedly merged together but it does the essentials for single purpose applications and saves me personally time, maybe someone elses too. Tested on x86_64 and aarch64.
Important side note: Docker Swarm does not work on rootless!
The setup utilizes sudo, granting your ssh user admin access without requiring a password prompt. This configuration can be modified after the deployment by adjusting or deleting /etc/sudoers.d/ansible-alpine-default
Docker runs with a dedicated user and group (dockerguard:dockerguard). dockerguard is a system user, does not have a password nor a login shell, the user itself is not allowed to escalate privileges (/bin/su or /usr/bin/sudo). By becoming the dockerguard service user via sudo, Docker can be managed like a regular installation.
Since Alpine's default shell is ash the switch to the service user dockerguard works either via 'sudo -u dockerguard ash -l' or the alias 'dockerguard'.
The are 2 reason for this approach:
- The docker.sock group permissions are always subgid+100 which makes it impossible to add the dockerguard group to a user in order to interact with the service.
- The dockerguard user lacks the necessary environment variables to interact with the rootless Docker setup. To fix this the environment variables are placed in /etc/profile.d and inherited to the user with the -l option when switching. Without it you'd have to export them by hand every time you log in.
For ease of use unprivileged ports are enabled via sysctl
If this playbook doesn't gather_facts: true, it will fail!
- Python3 is installed on the target system
- A user exists that can connect via ssh-key and can become root via su
- Ansible modules installed
- community.general.apk
- community.general.ufw
When the playbook is run to configure sshd, the remote user needs to have your public ssh-ed25519 key on the target host (no other type is accepted by the sshd default config afterwards!)
ansible-playbook -b --ask-become-pass --become-method su --become-user root -i hosts site.yml -l test --tags "docker"
Useful tags:
- docker (rootless docker with userns)
- sshd (optional but recommended)
- unbound (optional - not recommended - deployment is broken/unfinished)
- update (lazy remote update for whenever it is deemed necessary)
Not so useful tags:
- sudo (invoked through docker)
- tools (invoked through docker)
- ufw (invoked through sshd)
Thanks to https://virtualzone.de/posts/alpine-docker-rootless/ for the openrc config