From ed6111153714fc023d8ef9dd65d90a81c3b6b41c Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Thu, 25 Apr 2024 09:22:42 +0200 Subject: [PATCH 1/9] Added support to expose docker-api via tcp --- README.md | 3 +++ defaults/main.yml | 1 + templates/docker_rootless.service.j2 | 17 +++++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 5b006c0..6884fad 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ docker_compose: false docker_compose_release: 2.26.0 docker_compose_release_shasum: 59c6b262bedc4a02f46c8400e830e660935684899c770c3f5e804a2b7079fc16 docker_daemon_json_template: daemon.json.j2 +docker_expose_docker_api_via_tcp: false docker_release: 26.1.0 docker_release_rootless_shasum: c40ce28994ae8c481eac796f25da587a4cdf1711c279abc9b9472ffca01d5d9e docker_release_shasum: ab46df00fbf4d218a8694da06f9c171760b6cad875924ed251a3a9d57a7180bf @@ -105,6 +106,8 @@ module. The `docker_release_shasum` is used for the Docker `.tgz` file and running in rootful mode, if unset the settings in `docker_rootful_service_template` will be used. +If `docker_expose_docker_api_via_tcp: true` then the docker daemon will expose its API via tcp. This is insecure, please check the [official docs](https://docs.docker.com/config/daemon/remote-access/) and ensure you understand the implications before activating this. + If `docker_add_alias: true`, then a `docker` alias will be added to either `.bashrc` or `.bash_aliases` of the Ansible user. If `false`, a shell script named `docker_rootless.sh` is created in the Ansible user home directory. This works as a substitute to the diff --git a/defaults/main.yml b/defaults/main.yml index 0947644..aed5768 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -8,6 +8,7 @@ docker_compose: false docker_compose_release: 2.26.0 docker_compose_release_shasum: 59c6b262bedc4a02f46c8400e830e660935684899c770c3f5e804a2b7079fc16 docker_daemon_json_template: daemon.json.j2 +docker_expose_docker_api_via_tcp: false docker_release: 26.1.0 docker_release_rootless_shasum: c40ce28994ae8c481eac796f25da587a4cdf1711c279abc9b9472ffca01d5d9e docker_release_shasum: ab46df00fbf4d218a8694da06f9c171760b6cad875924ed251a3a9d57a7180bf diff --git a/templates/docker_rootless.service.j2 b/templates/docker_rootless.service.j2 index a6276cf..5f7cfb4 100644 --- a/templates/docker_rootless.service.j2 +++ b/templates/docker_rootless.service.j2 @@ -1,6 +1,12 @@ # {{ ansible_managed }} # Generated by Ansible role {{ ansible_role_name }} +{# Set the external connection str if docker_expose_docker_api_via_tcp is wanted #} +{% set tcp_connection_str = '' %} +{% if docker_expose_docker_api_via_tcp %} +{% set tcp_connection_str = '-H tcp://0.0.0.0:2375 -H unix://${XDG_RUNTIME_DIR}/docker.sock' %} +{% endif %} + [Unit] Description=Docker Application Container Engine (Rootless) Documentation=https://docs.docker.com/engine/security/rootless/ @@ -9,18 +15,21 @@ Documentation=https://docs.docker.com/engine/security/rootless/ Environment="DOCKER_HOST=unix:///run/user/{{ docker_user_info.uid }}/docker.sock" Environment="PATH={{ docker_user_info.home }}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Environment="XDG_RUNTIME_DIR=/run/user/{{ docker_user_info.uid }}" +{% if docker_expose_docker_api_via_tcp %} +Environment="DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS=-p 0.0.0.0:2375:2375/tcp" +{% endif %} {% if not docker_rootful %} {% if ansible_distribution == "Debian" and ansible_kernel >= "4.18" and ansible_kernel <= "5.11" %} -ExecStart={{ docker_user_info.home }}/bin/dockerd-rootless.sh -s fuse-overlayfs +ExecStart={{ docker_user_info.home }}/bin/dockerd-rootless.sh {{ tcp_connection_str }} -s fuse-overlayfs {% else %} -ExecStart={{ docker_user_info.home }}/bin/dockerd-rootless.sh +ExecStart={{ docker_user_info.home }}/bin/dockerd-rootless.sh {{ tcp_connection_str }} {% endif %} {% endif %} {% if docker_rootful %} {% if ansible_distribution == "Debian" and ansible_kernel >= "4.18" and ansible_kernel <= "5.11" %} -ExecStart=/usr/bin/dockerd-rootless.sh -s fuse-overlayfs +ExecStart=/usr/bin/dockerd-rootless.sh {{ tcp_connection_str }} -s fuse-overlayfs {% else %} -ExecStart=/usr/bin/dockerd-rootless.sh +ExecStart=/usr/bin/dockerd-rootless.sh {{ tcp_connection_str }} {% endif %} {% endif %} ExecReload=/bin/kill -s HUP $MAINPID From 1d8ef1f3c0dfc522d370e05f6cac40c960174cae Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Thu, 25 Apr 2024 16:01:55 +0200 Subject: [PATCH 2/9] Added additional docs --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6884fad..26b9ce7 100644 --- a/README.md +++ b/README.md @@ -106,8 +106,6 @@ module. The `docker_release_shasum` is used for the Docker `.tgz` file and running in rootful mode, if unset the settings in `docker_rootful_service_template` will be used. -If `docker_expose_docker_api_via_tcp: true` then the docker daemon will expose its API via tcp. This is insecure, please check the [official docs](https://docs.docker.com/config/daemon/remote-access/) and ensure you understand the implications before activating this. - If `docker_add_alias: true`, then a `docker` alias will be added to either `.bashrc` or `.bash_aliases` of the Ansible user. If `false`, a shell script named `docker_rootless.sh` is created in the Ansible user home directory. This works as a substitute to the @@ -136,6 +134,10 @@ The most important template is most likely `docker_daemon_json_template: daemon.json.j2`, which is the location of the Docker `daemon.json` configuration file template. +If `docker_expose_docker_api_via_tcp: true` then the docker daemon will expose its API via tcp. This is insecure, please check the [official docs](https://docs.docker.com/config/daemon/remote-access/) and ensure you understand the implications before activating this. + +Exposing the Docker API securely by using TLS is currently not supported via Ansible variable. You will need to edit the [template/docker_rootless.service.j2](https://github.com/konstruktoid/ansible-role-docker-rootless/blob/main/templates/docker_rootless.service.j2) file yourself or provide your own template using the `docker_rootless_service_template` variable. In general you'll need to change the `DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS` and `tcp_connection_str` within the template to use port `:2376` and include the necessary `--tlsverify`, `--tlscacert`, `--tlscert` and `tlskey` parameters. Check the [official Docker docs](https://docs.docker.com/engine/security/rootless/#expose-docker-api-socket-through-tcp) for more info about that. + ## Container management ### Standalone container From f90478a71b7b693f287535df12d9ac1c0d2b8721 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Thu, 25 Apr 2024 16:04:26 +0200 Subject: [PATCH 3/9] Missing dashes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 26b9ce7..0840134 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ Docker `daemon.json` configuration file template. If `docker_expose_docker_api_via_tcp: true` then the docker daemon will expose its API via tcp. This is insecure, please check the [official docs](https://docs.docker.com/config/daemon/remote-access/) and ensure you understand the implications before activating this. -Exposing the Docker API securely by using TLS is currently not supported via Ansible variable. You will need to edit the [template/docker_rootless.service.j2](https://github.com/konstruktoid/ansible-role-docker-rootless/blob/main/templates/docker_rootless.service.j2) file yourself or provide your own template using the `docker_rootless_service_template` variable. In general you'll need to change the `DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS` and `tcp_connection_str` within the template to use port `:2376` and include the necessary `--tlsverify`, `--tlscacert`, `--tlscert` and `tlskey` parameters. Check the [official Docker docs](https://docs.docker.com/engine/security/rootless/#expose-docker-api-socket-through-tcp) for more info about that. +Exposing the Docker API securely by using TLS is currently not supported via Ansible variable. You will need to edit the [template/docker_rootless.service.j2](https://github.com/konstruktoid/ansible-role-docker-rootless/blob/main/templates/docker_rootless.service.j2) file yourself or provide your own template using the `docker_rootless_service_template` variable. In general you'll need to change the `DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS` and `tcp_connection_str` within the template to use port `:2376` and include the necessary `--tlsverify`, `--tlscacert`, `--tlscert` and `--tlskey` parameters. Check the [official Docker docs](https://docs.docker.com/engine/security/rootless/#expose-docker-api-socket-through-tcp) for more info about that. ## Container management From 9acf67a4183d7466319fbaa86d9eb578b9c947b5 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 07:45:48 +0200 Subject: [PATCH 4/9] Extended the molecule vars --- .vscode/settings.json | 3 +++ molecule/default/molecule.yml | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 .vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..a3041de --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "ansible.python.interpreterPath": "c:\\Users\\brinkmann_n\\AppData\\Local\\Programs\\Python\\Python310\\python.exe" +} \ No newline at end of file diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index af42f95..4ac191b 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -21,6 +21,7 @@ provisioner: docker_rootful: false docker_user: debiantestinguser docker_user_bashrc: false + docker_expose_docker_api_via_tcp: true bookworm: docker_add_alias: true docker_allow_ping: true @@ -29,6 +30,7 @@ provisioner: docker_user: bookwormuser docker_user_bashrc: false docker_compose: false + docker_expose_docker_api_via_tcp: true almalinux8: docker_add_alias: false docker_allow_ping: false @@ -38,6 +40,7 @@ provisioner: docker_user: dockeruser docker_user_bashrc: true docker_compose: false + docker_expose_docker_api_via_tcp: true almalinux9: docker_add_alias: false docker_allow_ping: false @@ -47,6 +50,7 @@ provisioner: docker_user: dockeruser docker_user_bashrc: false docker_compose: true + docker_expose_docker_api_via_tcp: true focal: docker_add_alias: true docker_allow_ping: false @@ -56,6 +60,7 @@ provisioner: docker_user: dockeruser docker_user_bashrc: false docker_compose: false + docker_expose_docker_api_via_tcp: true focalroot: docker_add_alias: false docker_allow_ping: true @@ -65,6 +70,7 @@ provisioner: docker_user: dockeruser docker_user_bashrc: false docker_compose: false + docker_expose_docker_api_via_tcp: true jammy: docker_add_alias: false docker_allow_ping: false @@ -74,6 +80,7 @@ provisioner: docker_user: jammyuser docker_user_bashrc: true docker_compose: true + docker_expose_docker_api_via_tcp: true platforms: - name: bookworm box: debian/bookworm64 From 40bf09a3746856d180478cc006e91d4be0cd8725 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 07:48:03 +0200 Subject: [PATCH 5/9] Extended the .gitignore to not include any .vscode user-specific files --- .gitignore | 1 + .vscode/settings.json | 3 --- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index f678ff8..4562321 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ .yamllint drafts/* hosts +.vscode/settings.json diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index a3041de..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ansible.python.interpreterPath": "c:\\Users\\brinkmann_n\\AppData\\Local\\Programs\\Python\\Python310\\python.exe" -} \ No newline at end of file From 52935a8877085db51d46960056007016df6b4d34 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 08:06:11 +0200 Subject: [PATCH 6/9] Removed some of the vars from molecule platforms --- molecule/default/molecule.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 4ac191b..42ff03e 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -21,7 +21,6 @@ provisioner: docker_rootful: false docker_user: debiantestinguser docker_user_bashrc: false - docker_expose_docker_api_via_tcp: true bookworm: docker_add_alias: true docker_allow_ping: true @@ -30,7 +29,6 @@ provisioner: docker_user: bookwormuser docker_user_bashrc: false docker_compose: false - docker_expose_docker_api_via_tcp: true almalinux8: docker_add_alias: false docker_allow_ping: false @@ -40,7 +38,6 @@ provisioner: docker_user: dockeruser docker_user_bashrc: true docker_compose: false - docker_expose_docker_api_via_tcp: true almalinux9: docker_add_alias: false docker_allow_ping: false @@ -60,7 +57,6 @@ provisioner: docker_user: dockeruser docker_user_bashrc: false docker_compose: false - docker_expose_docker_api_via_tcp: true focalroot: docker_add_alias: false docker_allow_ping: true @@ -80,7 +76,6 @@ provisioner: docker_user: jammyuser docker_user_bashrc: true docker_compose: true - docker_expose_docker_api_via_tcp: true platforms: - name: bookworm box: debian/bookworm64 From 59e184b337653f12789f2ccda097d0f5b4f7d8b3 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 14:26:30 +0200 Subject: [PATCH 7/9] Added tcp-parameter to rootful services as well --- templates/docker_rootful.service.j2 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/templates/docker_rootful.service.j2 b/templates/docker_rootful.service.j2 index 8bbebe2..71f32ca 100644 --- a/templates/docker_rootful.service.j2 +++ b/templates/docker_rootful.service.j2 @@ -1,6 +1,12 @@ # {{ ansible_managed }} # Generated by Ansible role {{ ansible_role_name }} +{# Set the external connection str if docker_expose_docker_api_via_tcp is wanted #} +{% set tcp_connection_str = '' %} +{% if docker_expose_docker_api_via_tcp %} +{% set tcp_connection_str = '-H tcp://0.0.0.0:2375' %} +{% endif %} + [Unit] Description=Docker Application Container Engine Documentation=https://docs.docker.com @@ -10,7 +16,7 @@ Requires=docker.socket [Service] Type=notify -ExecStart=/usr/bin/dockerd {{ docker_rootful_opts if docker_rootful_opts else '-H fd:// --containerd=/run/containerd/containerd.sock' }} +ExecStart=/usr/bin/dockerd {{ tcp_connection_str }} {{ docker_rootful_opts if docker_rootful_opts else '-H fd:// --containerd=/run/containerd/containerd.sock' }} ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 From 405f2b4cd49d60d0b2d4ad077bf8aeeee5c3738c Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 14:27:48 +0200 Subject: [PATCH 8/9] Changed parameters so we test rootful/rootless target platforms --- molecule/default/molecule.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 42ff03e..96ef157 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -29,6 +29,7 @@ provisioner: docker_user: bookwormuser docker_user_bashrc: false docker_compose: false + docker_expose_docker_api_via_tcp: true almalinux8: docker_add_alias: false docker_allow_ping: false @@ -47,7 +48,6 @@ provisioner: docker_user: dockeruser docker_user_bashrc: false docker_compose: true - docker_expose_docker_api_via_tcp: true focal: docker_add_alias: true docker_allow_ping: false From fe0273acc3f04d87598e9dbd5fe8c300979026f9 Mon Sep 17 00:00:00 2001 From: Nils Brinkmann Date: Fri, 26 Apr 2024 14:29:19 +0200 Subject: [PATCH 9/9] Added basic test --- molecule/default/verify.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/molecule/default/verify.yml b/molecule/default/verify.yml index d5241a1..7d10b7a 100644 --- a/molecule/default/verify.yml +++ b/molecule/default/verify.yml @@ -88,6 +88,8 @@ register: ps_dockerd changed_when: docker_user[:7] not in ps_dockerd.stdout failed_when: docker_user[:7] not in ps_dockerd.stdout + when: + - not docker_expose_docker_api_via_tcp - name: Verify docker_rootless.sh ansible.builtin.stat: @@ -178,6 +180,20 @@ delay: 10 timeout: 120 + - name: Verify tcp exposure + become: true + ansible.builtin.shell: + cmd: | + set -o pipefail + ss -ltnp | grep '\:2375.*rootlesskit' + args: + executable: /bin/bash + register: tcp_exposure + changed_when: false + failed_when: tcp_exposure.rc != 0 + when: + - docker_expose_docker_api_via_tcp + - name: Ensure no docker-compose.yml exists become: true become_user: "{{ docker_user }}"