docker / docker-bench-security

The Docker Bench for Security is a script that checks for dozens of common best-practices around deploying Docker containers in production.
Apache License 2.0
9.15k stars 1.02k forks source link

Execute benchmark on rootless docker #556

Open osorito opened 2 months ago

osorito commented 2 months ago

Describe the bug A clear and concise description of what the bug is.

If you set up docker in rootless mode, you can not run the test

Setup docker rootless based on

https://docs.docker.com/engine/security/rootless/

node@Blaze:~$ cat rootless_docker.log
[INFO] starting systemd service docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/node/.config/systemd/user/docker.service; enabled; preset: enabled)
     Active: active (running) since Wed 2024-09-04 22:37:31 UTC; 3s ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 4516 (rootlesskit)
      Tasks: 34
     Memory: 42.1M (peak: 42.6M)
        CPU: 498ms
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─4516 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
             ├─4526 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
             ├─4546 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 4526 tap0
             ├─4553 dockerd
             └─4571 containerd --config /run/user/1001/docker/containerd/containerd.toml

Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112155106Z" level=warning msg="WARNING: No io.weight support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112169219Z" level=warning msg="WARNING: No io.weight (per device) support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112176655Z" level=warning msg="WARNING: No io.max (rbps) support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112182808Z" level=warning msg="WARNING: No io.max (wbps) support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112188511Z" level=warning msg="WARNING: No io.max (riops) support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112194018Z" level=warning msg="WARNING: No io.max (wiops) support"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112211982Z" level=info msg="Docker daemon" commit=3ab5c7d containerd-snapshotter=false storage-driver=overlay2 version=27.2.0
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.112798306Z" level=info msg="Daemon has completed initialization"
Sep 04 22:37:31 Blaze dockerd-rootless.sh[4553]: time="2024-09-04T22:37:31.150703407Z" level=info msg="API listen on /run/user/1001/docker.sock"
Sep 04 22:37:31 Blaze systemd[998]: Started docker.service - Docker Application Container Engine (Rootless).
Client: Docker Engine - Community
 Version:           27.2.0
API version:       1.47
 Go version:        go1.21.13
 Git commit:        3ab4256
 Built:             Tue Aug 27 14:15:15 2024
 OS/Arch:           linux/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          27.2.0
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.21.13
  Git commit:       3ab5c7d
  Built:            Tue Aug 27 14:15:15 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.21
  GitCommit:        472731909fa34bd7bc9c087e4c27943f9835f111
 runc:
  Version:          1.1.13
  GitCommit:        v1.1.13-0-g58aa920
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
 rootlesskit:
  Version:          2.0.2
  ApiVersion:       1.1.1
  NetworkDriver:    slirp4netns
  PortDriver:       builtin
  StateDir:         /run/user/1001/dockerd-rootless
 slirp4netns:
  Version:          1.2.1
  GitCommit:        09e31e92fa3d2a1d3ca261adaeb012c8d75a8194
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger node`

[INFO] Creating CLI context "rootless"
[INFO] Using CLI context "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1001/docker.sock
node@Blaze:~$ docker ps -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
node@Blaze:~$
Running docker bench security from host
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
sudo sh docker-bench-security.sh

Version

Distribution [Ubuntu 24.04]

node@Blaze:~/docker-bench-security$ cat /etc/os-release
PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=noble
LOGO=ubuntu-logo
node@Blaze:~/docker-bench-security$ 
~/docker-bench-security$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default      Current DOCKER_HOST based configuration   unix:///var/run/docker.sock         
rootless *   Rootless mode                             unix:///run/user/1001/docker.sock   
node@Blaze:~/docker-bench-security$ systemctl --user status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/node/.config/systemd/user/docker.service; enabled; preset: enabled)
     Active: active (running) since Wed 2024-09-04 23:28:57 UTC; 12min ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 43286 (rootlesskit)
      Tasks: 34
     Memory: 40.3M (peak: 42.6M)
        CPU: 1.242s
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─43286 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=bu>
             ├─43296 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver>
             ├─43317 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 43296 tap0
             ├─43324 dockerd
             └─43342 containerd --config /run/user/1001/docker/containerd/containerd.toml

Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983732896Z" level=warning msg="WARNING: No io.max (rbps) support"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983738950Z" level=warning msg="WARNING: No io.max (wbps) support"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983744729Z" level=warning msg="WARNING: No io.max (riops) support"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983750999Z" level=warning msg="WARNING: No io.max (wiops) support"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983756811Z" level=warning msg="WARNING: bridge-nf-call-iptables is disabled"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983771620Z" level=warning msg="WARNING: bridge-nf-call-ip6tables is disabled"
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983791427Z" level=info msg="Docker daemon" commit=3ab5c7d containerd-snapshotter=false storage-driver=overlay2 version=27.2.0
Sep 04 23:28:56 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:56.983839748Z" level=info msg="Daemon has completed initialization"
Sep 04 23:28:57 Blaze dockerd-rootless.sh[43324]: time="2024-09-04T23:28:57.030565679Z" level=info msg="API listen on /run/user/1001/docker.sock"
Sep 04 23:28:57 Blaze systemd[983]: Started docker.service - Docker Application Container Engine (Rootless).
lines 1-25/25 (END)

Expected behavior A clear and concise description of what you expected to happen.

The test should run with or without rootless enabled

Output If applicable, add output that you get from the tool or the related section of lynis.log

node@Blaze:~/docker-bench-security$ sudo sh docker-bench-security.sh
Error connecting to docker daemon (does docker ps work?)
node@Blaze:~/docker-bench-security$ 
konstruktoid commented 2 months ago

Note that rootless mode currently isn't officially supported, and some config tests will return that the file is missing.

I use https://github.com/konstruktoid/ansible-role-docker-rootless to install rootless Docker services.

$ lsb_release -d
No LSB modules are available.
Description:    Ubuntu 24.04 LTS
$ git clone https://github.com/docker/docker-bench-security.git
 $ cd docker-bench-security
$ alias docker
alias docker='sudo XDG_RUNTIME_DIR="/run/user/1001" DOCKER_HOST="unix:///run/user/1001/docker.sock" /home/dockeruser/bin/docker'
$ sudo PATH="/home/dockeruser/bin/:$PATH" XDG_RUNTIME_DIR="/run/user/1001" DOCKER_HOST="unix:///run/user/1001/docker.sock" /bin/bash docker-bench-security.sh -c check_2_1
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-05T07:33:54+00:00

Section A - Check results
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)

Section C - Score

[INFO] Checks: 1
[INFO] Score: 0
osorito commented 2 months ago

Took a look at your shell command.

If I run the following

node@Blaze:~/docker-bench-security$ sudo DOCKER_HOST="unix:///run/user/1001/docker.sock" sh docker-bench-security.sh 
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-05T16:29:49+00:00

Section A - Check results

[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Hosts Specific Configuration
WARNING: No cpuset support
WARNING: No io.weight support
WARNING: No io.weight (per device) support
WARNING: No io.max (rbps) support
WARNING: No io.max (wbps) support
WARNING: No io.max (riops) support
WARNING: No io.max (wiops) support
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)
[INFO] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon (Automated)
[INFO]       * Users: node
[PASS] 1.1.3 - Ensure auditing is configured for the Docker daemon (Automated)
[PASS] 1.1.4 - Ensure auditing is configured for Docker files and directories -/run/containerd (Automated)
[PASS] 1.1.5 - Ensure auditing is configured for Docker files and directories - /var/lib/docker (Automated)
[PASS] 1.1.6 - Ensure auditing is configured for Docker files and directories - /etc/docker (Automated)
[PASS] 1.1.7 - Ensure auditing is configured for Docker files and directories - docker.service (Automated)
[WARN] 1.1.8 - Ensure auditing is configured for Docker files and directories - containerd.sock (Automated)
[PASS] 1.1.9 - Ensure auditing is configured for Docker files and directories - docker.socket (Automated)
[PASS] 1.1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker (Automated)
[PASS] 1.1.11 - Ensure auditing is configured for Dockerfiles and directories - /etc/docker/daemon.json (Automated)
[PASS] 1.1.12 - 1.1.12 Ensure auditing is configured for Dockerfiles and directories - /etc/containerd/config.toml (Automated)
[INFO] 1.1.13 - Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker (Automated)
[INFO]        * File not found
[PASS] 1.1.14 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd (Automated)
[PASS] 1.1.15 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim (Automated)
[PASS] 1.1.16 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v1 (Automated)
[PASS] 1.1.17 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v2 (Automated)
[PASS] 1.1.18 - Ensure auditing is configured for Docker files and directories - /usr/bin/runc (Automated)
[INFO] 1.2 - General Configuration
[NOTE] 1.2.1 - Ensure the container host has been Hardened (Manual)
[PASS] 1.2.2 - Ensure that the version of Docker is up to date (Manual)
[INFO]        * Using 27.2.0 which is current
[INFO]        * Check with your operating system vendor for support and security maintenance for Docker

[INFO] 2 - Docker daemon configuration
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)
docker-bench-security.sh: 37: [[: not found
[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[PASS] 2.3 - Ensure the logging level is set to 'info' (Scored)
docker-bench-security.sh: 96: [[: not found
[PASS] 2.4 - Ensure Docker is allowed to make changes to iptables (Scored)
docker-bench-security.sh: 118: [[: not found
[PASS] 2.5 - Ensure insecure registries are not used (Scored)
[PASS] 2.6 - Ensure aufs storage driver is not used (Scored)
[INFO] 2.7 - Ensure TLS authentication for Docker daemon is configured (Scored)
[INFO]      * Docker daemon not listening on TCP
docker-bench-security.sh: 185: [[: not found
[INFO] 2.8 - Ensure the default ulimit is configured appropriately (Manual)
[INFO]      * Default ulimit doesn't appear to be set
docker-bench-security.sh: 208: [[: not found
[WARN] 2.9 - Enable user namespace support (Scored)
[PASS] 2.10 - Ensure the default cgroup usage has been confirmed (Scored)
[PASS] 2.11 - Ensure base device size is not changed until needed (Scored)
docker-bench-security.sh: 276: [[: not found
[WARN] 2.12 - Ensure that authorization for Docker client commands is enabled (Scored)
[WARN] 2.13 - Ensure centralized and remote logging is configured (Scored)
[PASS] 2.14 - Ensure containers are restricted from acquiring new privileges (Scored)
[WARN] 2.15 - Ensure live restore is enabled (Scored)
[PASS] 2.16 - Ensure Userland Proxy is Disabled (Scored)
[INFO] 2.17 - Ensure that a daemon-wide custom seccomp profile is applied if appropriate (Manual)
[INFO] Ensure that experimental features are not implemented in production (Scored) (Deprecated)

[INFO] 3 - Docker daemon configuration files
[PASS] 3.1 - Ensure that the docker.service file ownership is set to root:root (Automated)
[PASS] 3.2 - Ensure that docker.service file permissions are appropriately set (Automated)
[PASS] 3.3 - Ensure that docker.socket file ownership is set to root:root (Automated)
[PASS] 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive (Automated)
[PASS] 3.5 - Ensure that the /etc/docker directory ownership is set to root:root (Automated)
[PASS] 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictively (Automated)
[PASS] 3.7 - Ensure that registry certificate file ownership is set to root:root (Automated)
[PASS] 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictively (Automated)
[INFO] 3.9 - Ensure that TLS CA certificate file ownership is set to root:root (Automated)
[INFO]      * No TLS CA certificate found
[INFO] 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS CA certificate found
[INFO] 3.11 - Ensure that Docker server certificate file ownership is set to root:root (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.12 - Ensure that the Docker server certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.13 - Ensure that the Docker server certificate key file ownership is set to root:root (Automated)
[INFO]       * No TLS Key found
[INFO] 3.14 - Ensure that the Docker server certificate key file permissions are set to 400 (Automated)
[INFO]       * No TLS Key found
[INFO] 3.15 - Ensure that the Docker socket file ownership is set to root:docker (Automated)
[INFO]       * File not found
[INFO] 3.16 - Ensure that the Docker socket file permissions are set to 660 or more restrictively (Automated)
[INFO]       * File not found
[PASS] 3.17 - Ensure that the daemon.json file ownership is set to root:root (Automated)
[PASS] 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive (Automated)
[PASS] 3.19 - Ensure that the /etc/default/docker file ownership is set to root:root (Automated)
[PASS] 3.20 - Ensure that the /etc/default/docker file permissions are set to 644 or more restrictively (Automated)
[INFO] 3.21 - Ensure that the /etc/sysconfig/docker file permissions are set to 644 or more restrictively (Automated)
[INFO]       * File not found
[INFO] 3.22 - Ensure that the /etc/sysconfig/docker file ownership is set to root:root (Automated)
[INFO]       * File not found
[PASS] 3.23 - Ensure that the Containerd socket file ownership is set to root:root (Automated)
[PASS] 3.24 - Ensure that the Containerd socket file permissions are set to 660 or more restrictively (Automated)

[INFO] 4 - Container Images and Build File
[INFO] 4.1 - Ensure that a user for the container has been created (Automated)
[INFO]      * No containers running
[NOTE] 4.2 - Ensure that containers use only trusted base images (Manual)
[NOTE] 4.3 - Ensure that unnecessary packages are not installed in the container (Manual)
[NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches (Manual)
[PASS] 4.5 - Ensure Content trust for Docker is Enabled (Automated)
[PASS] 4.6 - Ensure that HEALTHCHECK instructions have been added to container images (Automated)
[PASS] 4.7 - Ensure update instructions are not used alone in the Dockerfile (Manual)
[NOTE] 4.8 - Ensure setuid and setgid permissions are removed (Manual)
[PASS] 4.9 - Ensure that COPY is used instead of ADD in Dockerfiles (Manual)
[NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles (Manual)
[NOTE] 4.11 - Ensure only verified packages are installed (Manual)
[NOTE] 4.12 - Ensure all signed artifacts are validated (Manual)

[INFO] 5 - Container Runtime
[INFO]   * No containers running, skipping Section 5
[PASS] 5.1 - Ensure swarm mode is not Enabled, if not needed (Automated)

[INFO] 6 - Docker Security Operations
[INFO] 6.1 - Ensure that image sprawl is avoided (Manual)
[INFO]      * There are currently: 0 images
[INFO] 6.2 - Ensure that container sprawl is avoided (Manual)
[INFO]      * There are currently a total of 0 containers, with 0 of them currently running

[INFO] 7 - Docker Swarm Configuration
[PASS] 7.1 - Ensure that the minimum number of manager nodes have been created in a swarm (Automated) (Swarm mode not enabled)
[PASS] 7.2 - Ensure that swarm services are bound to a specific host interface (Automated) (Swarm mode not enabled)
[PASS] 7.3 - Ensure that all Docker swarm overlay networks are encrypted (Automated)
[PASS] 7.4 - Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster (Manual) (Swarm mode not enabled)
[PASS] 7.5 - Ensure that swarm manager is run in auto-lock mode (Automated) (Swarm mode not enabled)
[PASS] 7.6 - Ensure that the swarm manager auto-lock key is rotated periodically (Manual) (Swarm mode not enabled)
[PASS] 7.7 - Ensure that node certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.8 - Ensure that CA certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.9 - Ensure that management plane traffic is separated from data plane traffic (Manual) (Swarm mode not enabled)

Section C - Score

[INFO] Checks: 86
[INFO] Score: 36

node@Blaze:~/docker-bench-security$
....

The benchmark works again.

For some reasons it is displaying some errors that should not be there example, place /var/lib/docker on a separate partition.

node@Blaze:~/docker-bench-security$ sudo lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINTS
sda       8:0    0    5G  0 disk 
├─sda1    8:1    0    4G  0 part /
├─sda14   8:14   0    4M  0 part 
├─sda15   8:15   0  106M  0 part /boot/efi
└─sda16 259:0    0  913M  0 part /boot
sdb       8:16   0   25G  0 disk 
├─sdb1    8:17   0  6.3G  0 part /home
├─sdb2    8:18   0    5G  0 part /var
├─sdb3    8:19   0  6.3G  0 part /tmp
└─sdb4    8:20   0  7.5G  0 part /var/lib/docker
sr0      11:0    1    4M  0 rom  
node@Blaze:~/docker-bench-security$ sudo df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           392M  1.3M  391M   1% /run
/dev/sda1       3.9G  2.6G  1.3G  67% /
tmpfs           2.0G  3.1M  2.0G   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/sdb2       4.9G  984M  3.7G  22% /var
/dev/sdb3       6.1G   92K  5.8G   1% /tmp
/dev/sda16      881M   62M  758M   8% /boot
/dev/sda15      105M  6.1M   99M   6% /boot/efi
/dev/sdb4       7.3G  556K  6.9G   1% /var/lib/docker
/dev/sdb1       6.1G  6.0M  5.8G   1% /home
tmpfs           392M   36K  392M   1% /run/user/1001
tmpfs           392M   12K  392M   1% /run/user/1000
node@Blaze:~/docker-bench-security$ 

Rootless appears to ignore /etc/docker/daemon.json based on the output.

[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[WARN] 2.9 - Enable user namespace support (Scored)
[WARN] 2.15 - Ensure live restore is enabled (Scored)
node@Blaze:~/docker-bench-security$ sudo cat /etc/docker/daemon.json

{
  "log-driver": "syslog",
  "log-level": "info",
  "iptables": true,
  "insecure-registries": [],
  "live-restore": true,
  "userland-proxy": false,
  "icc": false,
  "no-new-privileges": true,
  "userns-remap": "default"

}

But that is totally independent of the benchmark. Or is it a feature of the benchmark?

konstruktoid commented 2 months ago

sudo DOCKER_HOST="unix:///run/user/1001/docker.sock" docker info -f '{{ .DockerRootDir }}' should be a separate partition and ~/.config/docker/daemon.json is the location of the config file when running rootless.

osorito commented 2 months ago

Moved daemon.json to ~/.config/docker/daemon.json

node@Blaze:~/.config/docker$ pwd
/home/node/.config/docker
node@Blaze:~/docker-bench-security$ sudo cat ~/.config/docker/daemon.json

{
  "log-driver": "syslog",
  "log-level": "info",
  "iptables": true,
  "insecure-registries": [],
  "live-restore": true,
  "userland-proxy": false,
  "tls": true,
  "tlsverify": true,
  "tlscacert": "/home/node/.config/docker/certs.d/ca.pem",
  "tlscert": "/home/node/.config/docker/certs.d/server_cert.pem",
  "tlskey": "/home/node/.config/docker/certs.d/server_key.pem",
  "hosts": ["tcp://0.0.0.0:2376","unix:///run/user/1001/docker.sock"],
  "no-new-privileges": true,
  "icc": false
}

node@Blaze:~/docker-bench-security$ 
node@Blaze:~/docker-bench-security$ dockerd --validate --config-file=/home/node/.config/docker/daemon.json
configuration OK
node@Blaze:~/.config/docker/certs.d$ sudo DOCKER_HOST="unix:///run/user/1001/docker.sock" docker info -f '{{ .DockerRootDir }}'
/home/node/.local/share/docker

The .DockerRootDir is not /var/lib/docker since I'm using rootless docker

node@Blaze:~/docker-bench-security$ sudo df -h
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           392M  1.3M  391M   1% /run
/dev/sda1       3.9G  2.5G  1.4G  65% /
tmpfs           2.0G  3.1M  2.0G   1% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
/dev/sdb2       4.9G  1.1G  3.6G  23% /var
/dev/sda16      881M   62M  758M   8% /boot
/dev/sda15      105M  6.1M   99M   6% /boot/efi
/dev/sdb3       6.1G   92K  5.8G   1% /tmp
/dev/sdb1       6.1G  6.0M  5.8G   1% /home
/dev/sdb4       7.3G  540K  6.9G   1% /var/lib/docker
tmpfs           392M   36K  392M   1% /run/user/1001
tmpfs           392M   12K  392M   1% /run/user/1000
node@Blaze:~/docker-bench-security$

The tool is looking for /var/lib/docker based on output and that is the partition /dev/sdb4

node@Blaze:~/docker-bench-security$ sudo DOCKER_HOST="unix:///run/user/1001/docker.sock" sh docker-bench-security.sh  -c check_1_1_1 -p
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-06T17:34:51+00:00

Section A - Check results
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)

Section B - Remediation measures

[INFO] 1.1.1 - For new installations, you should create a separate partition for the /var/lib/docker mount point. For systems that have already been installed, you should use the Logical Volume Manager (LVM) within Linux to create a new partition. Remediation Impact: None.

Section C - Score

[INFO] Checks: 1
[INFO] Score: -1

node@Blaze:~/docker-bench-security$ 

The daemon.json is in right path , but it gives error that should not be.

node@Blaze:~/docker-bench-security$ sudo cat /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart= 
ExecStart=/usr/bin/dockerd --no-new-privileges --icc=false --userns-remap=default --containerd=/run/containerd/containerd.sock  

[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[WARN] 2.7 - Ensure TLS authentication for Docker daemon is configured (Scored)
[WARN]      * Docker daemon currently listening on TCP without TLS
[WARN] 2.9 - Enable user namespace support (Scored)
[WARN] 2.14 - Ensure containers are restricted from acquiring new privileges (Scored)

Verified docker .service status

node@Blaze:~$ systemctl --user status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/node/.config/systemd/user/docker.service; enabled; preset: enabled)
     Active: active (running) since Fri 2024-09-06 18:13:36 UTC; 39min ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 34145 (rootlesskit)
      Tasks: 35
     Memory: 45.9M (peak: 55.8M)
        CPU: 8.223s
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─34145 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin >
             ├─34155 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=built>
             ├─34176 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 34155 tap0
             ├─34183 dockerd
             └─34200 containerd --config /run/user/1001/docker/containerd/containerd.toml

Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.465278145Z" level=info msg="[graphdriver] using prior storage driver: overlay2"
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.465491095Z" level=info msg="Loading containers: start."
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.465694079Z" level=info msg="skipping firewalld management for rootless mode"
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.700644079Z" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be used >
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.768844197Z" level=info msg="Loading containers: done."
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.779012825Z" level=info msg="Docker daemon" commit=3ab5c7d containerd-snapshotter=false storage-driver=overlay2 version=27.2.0
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.779082630Z" level=info msg="Daemon has completed initialization"
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.811544846Z" level=info msg="API listen on /run/user/1001/docker.sock"
Sep 06 18:13:36 Blaze dockerd-rootless.sh[34183]: time="2024-09-06T18:13:36.811646755Z" level=info msg="API listen on [::]:2376"
Sep 06 18:13:36 Blaze systemd[958]: Started docker.service - Docker Application Container Engine (Rootless).
lines 1-25/25 (END)

node@Blaze:~$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default      Current DOCKER_HOST based configuration   tcp://localhost:2376                
rootless *   Rootless mode                             unix:///run/user/1001/docker.sock   
node@Blaze:~$ 
node@Blaze:~$ docker run hello-world
Unable to find image 'hello-world:latest' locally
docker.io/library/hello-world@sha256:53cc4d415d839c98be39331c948609b659ed725170ad2ca8eb36951288f81b75: Pulling from library/hello-world
c1ec31eb5944: Pull complete 
Digest: sha256:53cc4d415d839c98be39331c948609b659ed725170ad2ca8eb36951288f81b75
Status: Downloaded newer image for hello-world@sha256:53cc4d415d839c98be39331c948609b659ed725170ad2ca8eb36951288f81b75
Tagging hello-world@sha256:53cc4d415d839c98be39331c948609b659ed725170ad2ca8eb36951288f81b75 as hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
konstruktoid commented 2 months ago

So the two issues are:

  1. the remediation text for 1.1.1 is static
  2. https://github.com/docker/docker-bench-security/blob/5c42b8ad5f367e2988b9889171e9ec4f11f446e0/functions/helper_lib.sh#L105 doesn't check if a ~/.config/docker/daemon.json exists.

Could be tested as.

$ export HOME_DOCKER_USER="$(grep "$(ps -eo user | grep docker | sort -u)" /etc/passwd | awk -F':' '{print $6}')" $ file "${HOME_DOCKER_USER}/.config/docker/daemon.json"

konstruktoid commented 2 months ago

PRs will be written.

konstruktoid commented 2 months ago

https://github.com/docker/docker-bench-security/pull/557 and https://github.com/docker/docker-bench-security/pull/558 hopefully fixes this

osorito commented 2 months ago

Locally made changes to test

get_docker_configuration_file() {
  DOCKER_USER_HOME="$(grep -m1 "^$(ps -eo user,cmd | grep docker | grep -v grep |\
    awk '{ print $1 }')" /etc/passwd | awk -F':' '{ print $6 }')"
  FILE="$(get_docker_effective_command_line_args '--config-file' | \
    sed 's/.*=//g')"

  if [ -f "$FILE" ]; then
    CONFIG_FILE="$FILE"
    return
  fi
  if [ -f '/etc/docker/daemon.json' ]; then
    CONFIG_FILE='/etc/docker/daemon.json'
    return
  fi
  if [ -f "${DOCKER_USER_HOME}/.config/docker/daemon.json" ]; then
    CONFIG_FILE="${DOCKER_USER_HOME}/.config/docker/daemon.json"
    return
  fi
  CONFIG_FILE='/dev/null'
}

It still ignores the configuration file

sudo cat ~/.config/docker/daemon.json
          {
            "log-driver": "syslog",
            "log-level": "info",
            "iptables": true,
            "insecure-registries": [],
            "live-restore": true,
            "userland-proxy": false,
            "tls": true,
            "tlscacert": "/home/node/.config/docker/certs.d/ca.pem",
            "tlscert": "/home/node/.config/docker/certs.d/server_cert.pem",
            "tlskey": "/home/node/.config/docker/certs.d/server_key.pem",
            "hosts": ["tcp://0.0.0.0:2376","unix:///run/user/1001/docker.sock"],
        "no-new-privileges": true,
            "icc": false,
            "tlsverify": true
          }
node@Blaze:~/docker-bench-security$ sudo cat /etc/systemd/system/docker.service.d/override.conf
[Service]
ExecStart= 
ExecStart=/usr/bin/dockerd --no-new-privileges --icc=false --userns-remap=default --containerd=/run/containerd/containerd.sock 

[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored) [WARN] 2.9 - Enable user namespace support (Scored) WARN] 2.12 - Ensure that authorization for Docker client commands is enabled (Scored) [WARN] 2.14 - Ensure containers are restricted from acquiring new privileges (Scored)

konstruktoid commented 2 months ago

Could you run bash -x docker-bench-security.sh -c check_2_2 and paste it all here?

osorito commented 2 months ago

Two outputs , first without DOCKER_HOST

node@docker-host:~/docker-bench-security$ sudo bash -x docker-bench-security.sh -c check_2_2
+ version=1.6.0
+ . ./functions/functions_lib.sh
+ . ./functions/helper_lib.sh
++ auditrules=/etc/audit/audit.rules
++ abspath docker-bench-security.sh
++ case "$1" in
++ printf '%s\n' /home/node/docker-bench-security/docker-bench-security.sh
+ this_path=/home/node/docker-bench-security/docker-bench-security.sh
++ basename /home/node/docker-bench-security/docker-bench-security
+ myname=docker-bench-security
+ readonly version
+ readonly this_path
+ readonly myname
+ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/
+ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/
+ req_programs 'awk docker grep sed stat tail tee tr wc xargs'
+ for p in $1
+ command -v awk
+ for p in $1
+ command -v docker
+ for p in $1
+ command -v grep
+ for p in $1
+ command -v sed
+ for p in $1
+ command -v stat
+ for p in $1
+ command -v tail
+ for p in $1
+ command -v tee
+ for p in $1
+ command -v tr
+ for p in $1
+ command -v wc
+ for p in $1
+ command -v xargs
+ command -v jq
+ HAVE_JQ=true
+ command -v ss
+ netbin=ss
+ return
+ docker ps -q
+ printf 'Error connecting to docker daemon (does docker ps work?)\n'
Error connecting to docker daemon (does docker ps work?)
+ exit 1
node@docker-host:~/docker-bench-security$ 

Output with DOCKER_HOST

node@docker-host:~/docker-bench-security$ sudo DOCKER_HOST="unix:///run/user/1001/docker.sock"   bash -x docker-bench-security.sh -c check_2_2
+ version=1.6.0
+ . ./functions/functions_lib.sh
+ . ./functions/helper_lib.sh
++ auditrules=/etc/audit/audit.rules
++ abspath docker-bench-security.sh
++ case "$1" in
++ printf '%s\n' /home/node/docker-bench-security/docker-bench-security.sh
+ this_path=/home/node/docker-bench-security/docker-bench-security.sh
++ basename /home/node/docker-bench-security/docker-bench-security
+ myname=docker-bench-security
+ readonly version
+ readonly this_path
+ readonly myname
+ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/
+ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/
+ req_programs 'awk docker grep sed stat tail tee tr wc xargs'
+ for p in $1
+ command -v awk
+ for p in $1
+ command -v docker
+ for p in $1
+ command -v grep
+ for p in $1
+ command -v sed
+ for p in $1
+ command -v stat
+ for p in $1
+ command -v tail
+ for p in $1
+ command -v tee
+ for p in $1
+ command -v tr
+ for p in $1
+ command -v wc
+ for p in $1
+ command -v xargs
+ command -v jq
+ HAVE_JQ=true
+ command -v ss
+ netbin=ss
+ return
+ docker ps -q
+ '[' '!' -d log ']'
+ mkdir log
+ logger=log/docker-bench-security.log
+ limit=0
+ printremediation=0
+ globalRemediation=
+ getopts bhl:u:c:e:i:x:t:n:p args
+ case $args in
+ check=check_2_2
+ getopts bhl:u:c:e:i:x:t:n:p args
+ . ./functions/output_lib.sh
++ bldred='\033[1;31m'
++ bldgrn='\033[1;32m'
++ bldblu='\033[1;34m'
++ bldylw='\033[1;33m'
++ txtrst='\033[0m'
++ '[' -n '' ']'
++ SSEP=
++ SEP=
+ yell_info
++ date +%Y
+ yell '# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------'
+ printf '%b\n' '\033[1;33m# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------\033[0m\n'
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

++ id -u
+ '[' 0 '!=' 0 ']'
+ totalChecks=0
+ currentScore=0
++ date +%Y-%m-%dT%H:%M:%S%:z
+ logit 'Initializing 2024-09-11T22:25:49+00:00\n'
+ printf '%b\n' 'Initializing 2024-09-11T22:25:49+00:00\n'
+ tee -a log/docker-bench-security.log
Initializing 2024-09-11T22:25:49+00:00

++ date +%s
+ beginjson 1.6.0 1726093549
+ printf '{\n  "dockerbenchsecurity": "%s",\n  "start": %s,\n  "tests": [' 1.6.0 1726093549
+ tee log/docker-bench-security.log.json
+ main -c check_2_2
+ logit '\n\033[1;33mSection A - Check results\033[0m'
+ printf '%b\n' '\n\033[1;33mSection A - Check results\033[0m'
+ tee -a log/docker-bench-security.log

Section A - Check results
+ get_docker_configuration_file
++ awk -F: '{ print $6 }'
+++ grep docker
+++ grep -v grep
+++ awk '{ print $1 }'
+++ ps -eo user,cmd
++ grep -m1 '^node
node
node
node
root
root
root
root
root
root' /etc/passwd
+ DOCKER_USER_HOME=/root
++ sed 's/.*=//g'
++ get_docker_effective_command_line_args --config-file
++ OPTION=--config-file
++ get_docker_cumulative_command_line_args --config-file
++ OPTION=--config-file
++ line_arg=dockerd
++ get_command_line_args 'docker daemon'
++ tail -n1
++ get_command_line_args dockerd
++ PROC=dockerd
++ sed -e 's/\-\-debug/-D/g' -e 's/\-\-host/-H/g' -e 's/\-\-log-level/-l/g' -e 's/\-\-version/-v/g'
+++ pgrep -f -n dockerd
++ sed -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g'
++ tr ' ' '\n'
++ grep '^--config-file'
++ sed -e 's/"//g' -e 's/'\''//g'
++ for PID in $(pgrep -f -n "$PROC")
++ tr '\0' ' '
+ FILE=
+ '[' -f '' ']'
+ '[' -f /etc/docker/daemon.json ']'
+ CONFIG_FILE=/etc/docker/daemon.json
+ return
+ benchcont=nil
++ docker ps
++ sed 1d
++ awk '{print $NF}'
+ benchimagecont=nil
++ docker images
++ sed 1d
++ awk '{print $3}'
++ sed 's/,/ /g'
++ echo ''
+ '[' -n '' ']'
+ '[' -n '' ']'
++ docker ps
++ grep -v nil
++ awk '{print $NF}'
++ sed 1d
+ containers=
++ docker images -q
++ grep -v nil
+ images=
+ for test in tests/*.sh
+ . ./tests/1_host_configuration.sh
+ for test in tests/*.sh
+ . ./tests/2_docker_daemon_configuration.sh
+ for test in tests/*.sh
+ . ./tests/3_docker_daemon_configuration_files.sh
+ for test in tests/*.sh
+ . ./tests/4_container_images.sh
+ for test in tests/*.sh
+ . ./tests/5_container_runtime.sh
+ for test in tests/*.sh
+ . ./tests/6_docker_security_operations.sh
+ for test in tests/*.sh
+ . ./tests/7_docker_swarm_configuration.sh
+ for test in tests/*.sh
+ . ./tests/8_docker_enterprise_configuration.sh
+ for test in tests/*.sh
+ . ./tests/99_community_checks.sh
+ '[' -z check_2_2 ']'
+ '[' -z check_2_2 ']'
++ echo check_2_2
++ sed 's/,/ /g'
+ for c in $(echo "$check" | sed "s/,/ /g")
+ command -v check_2_2
+ '[' -z '' ']'
+ check_2_2
+ local id=2.2
+ local 'desc=Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ local 'remediation=Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false.'
+ local 'remediationImpact=Inter-container communication is disabled on the default network bridge. If any communication between containers on the same host is desired, it needs to be explicitly defined using container linking or custom networks.'
+ local 'check=2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ starttestjson 2.2 'Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ printf '%s\n        {\n          "id": "%s",\n          "desc": "%s",\n          ' '' 2.2 'Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ tee -a log/docker-bench-security.log.json
+ SEP=,
+ get_docker_effective_command_line_args --icc
+ OPTION=--icc
+ grep false
+ get_docker_cumulative_command_line_args --icc
+ OPTION=--icc
+ line_arg=dockerd
+ tail -n1
+ get_command_line_args 'docker daemon'
+ get_command_line_args dockerd
+ PROC=dockerd
+ sed -e 's/\-\-debug/-D/g' -e 's/\-\-host/-H/g' -e 's/\-\-log-level/-l/g' -e 's/\-\-version/-v/g'
++ pgrep -f -n dockerd
+ sed -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g'
+ tr ' ' '\n'
+ grep '^--icc'
+ sed -e 's/"//g' -e 's/'\''//g'
+ for PID in $(pgrep -f -n "$PROC")
+ tr '\0' ' '
++ get_docker_configuration_file_args icc
++ OPTION=icc
++ get_docker_configuration_file
++ grep false
+++ awk -F: '{ print $6 }'
++++ ps -eo user,cmd
++++ grep docker
++++ grep -v grep
++++ awk '{ print $1 }'
+++ grep -m1 '^node
node
node
node
root
root
root
root
root
root
root
root' /etc/passwd
++ DOCKER_USER_HOME=/root
+++ get_docker_effective_command_line_args --config-file
+++ OPTION=--config-file
+++ get_docker_cumulative_command_line_args --config-file
+++ OPTION=--config-file
+++ sed 's/.*=//g'
+++ tail -n1
+++ line_arg=dockerd
+++ get_command_line_args 'docker daemon'
+++ get_command_line_args dockerd
+++ PROC=dockerd
++++ pgrep -f -n dockerd
+++ tr ' ' '\n'
+++ sed -e 's/\-\-debug/-D/g' -e 's/\-\-host/-H/g' -e 's/\-\-log-level/-l/g' -e 's/\-\-version/-v/g'
+++ sed -e 's/\-\([DHlv]\)[= ]\([^- ][^ ]\)/-\1=\2/g'
+++ grep '^--config-file'
+++ sed -e 's/"//g' -e 's/'\''//g'
+++ for PID in $(pgrep -f -n "$PROC")
+++ tr '\0' ' '
++ FILE=
++ '[' -f '' ']'
++ '[' -f /etc/docker/daemon.json ']'
++ CONFIG_FILE=/etc/docker/daemon.json
++ return
++ true
++ jq --monochrome-output --raw-output 'if has("icc") then .["icc"] else "" end' /etc/docker/daemon.json
+ [[ -n '' ]]
+ warn -s '2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ local warnScored
+ local OPTIND s
+ getopts s args
+ case $args in
+ warnScored=true
+ getopts s args
+ '[' true = true ']'
+ printf '%b\n' '\033[1;31m[WARN]\033[0m 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)'
+ tee -a log/docker-bench-security.log
[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
+ totalChecks=1
+ currentScore=-1
+ return
+ logcheckresult WARN
+ log_to_json WARN
+ '[' 1 -eq 1 ']'
+ printf '"result": "%s"' WARN
+ tee -a log/docker-bench-security.log.json
+ return
+ '[' -n 'Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false.' ']'
+ '[' WARN '!=' PASS ']'
+ '[' 0 = 1 ']'
+ printf '\n        }'
+ tee -a log/docker-bench-security.log.json
+ '[' -n 'Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false.' ']'
+ '[' WARN '!=' PASS ']'
+ '[' -n '' ']'
+ globalRemediation='\n\033[1;34m[INFO]\033[0m 2.2 - Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false.'
+ '[' -n 'Inter-container communication is disabled on the default network bridge. If any communication between containers on the same host is desired, it needs to be explicitly defined using container linking or custom networks.' ']'
+ globalRemediation='\n\033[1;34m[INFO]\033[0m 2.2 - Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false. Remediation Impact: Inter-container communication is disabled on the default network bridge. If any communication between containers on the same host is desired, it needs to be explicitly defined using container linking or custom networks.'
+ '[' -n '\n\033[1;34m[INFO]\033[0m 2.2 - Edit the Docker daemon configuration file to ensure that inter-container communication is disabled: icc: false. Remediation Impact: Inter-container communication is disabled on the default network bridge. If any communication between containers on the same host is desired, it needs to be explicitly defined using container linking or custom networks.' ']'
+ '[' 0 = 1 ']'
+ logit '\n\n\033[1;33mSection C - Score\033[0m\n'
+ printf '%b\n' '\n\n\033[1;33mSection C - Score\033[0m\n'
+ tee -a log/docker-bench-security.log

Section C - Score

+ info 'Checks: 1'
+ local infoCountCheck
+ local OPTIND c
+ getopts c args
+ '[' '' = true ']'
+ printf '%b\n' '\033[1;34m[INFO]\033[0m Checks: 1'
+ tee -a log/docker-bench-security.log
[INFO] Checks: 1
+ info 'Score: -1\n'
+ local infoCountCheck
+ local OPTIND c
+ getopts c args
+ '[' '' = true ']'
+ printf '%b\n' '\033[1;34m[INFO]\033[0m Score: -1\n'
+ tee -a log/docker-bench-security.log
[INFO] Score: -1

++ date +%s
+ endjson 1 -1 1726093550
+ printf '\n  ],\n  "checks": %s,\n  "score": %s,\n  "end": %s\n}' 1 -1 1726093550
+ tee -a log/docker-bench-security.log.json
node@docker-host:~/docker-bench-security$ 
konstruktoid commented 2 months ago

Are you running both a Docker as root and a rootless?

++++ awk '{ print $1 }'
+++ grep -m1 '^node
node
node
node
root
root
root
root
root
root
root
root' /etc/passwd
++ DOCKER_USER_HOME=/root
++ '[' -f /etc/docker/daemon.json ']'
++ CONFIG_FILE=/etc/docker/daemon.json
osorito commented 2 months ago

When you install docker, first create a user that is not root in my case node. Then created a group docker and added node to the group. Installed docker, once docker is installed run the steps to install rootless. That is why you see /etc/docker/daemon.json. I can rename the file .

node@docker-host:~$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default      Current DOCKER_HOST based configuration   tcp://localhost:2376                
rootless *   Rootless mode                             unix:///run/user/1001/docker.sock   
node@docker-host:~$ groups node

node : node sudo docker
node@docker-host:~$

node@docker-host:~/docker-bench-security$ id node
uid=1001(node) gid=1002(node) groups=1002(node),27(sudo),1001(docker)
node@docker-host:~/docker-bench-security$ 

node@docker-host:~/docker-bench-security$ ls /etc/docker -la
total 24
drwxr-xr-x   3 root root    4096 Sep 12 15:18 .
drwxr-xr-x 118 root root   12288 Sep 11 22:16 ..
drwxr-x---   2 node docker  4096 Sep 11 22:16 certs.d
-rw-r-----   1 root root     381 Sep 11 22:16 daemon.json.old
node@docker-host:~/docker-bench-security$ sudo systemctl status docker
○ docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; preset: enabled)
    Drop-In: /etc/systemd/system/docker.service.d
             └─override.conf
     Active: inactive (dead)
TriggeredBy: ○ docker.socket
       Docs: https://docs.docker.com
node@docker-host:~/docker-bench-security$ systemctl --user status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/node/.config/systemd/user/docker.service; enabled; preset: enabled)
     Active: active (running) since Thu 2024-09-12 15:24:00 UTC; 36s ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 2399 (rootlesskit)
      Tasks: 33
     Memory: 41.1M (peak: 42.0M)
        CPU: 477ms
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─2399 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin ->
             ├─2409 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builti>
             ├─2428 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 2409 tap0
             ├─2435 dockerd
             └─2453 containerd --config /run/user/1001/docker/containerd/containerd.toml

Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.574999905Z" level=info msg="skipping firewalld management for rootless mode"
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.775403898Z" level=info msg="Default bridge (docker0) is assigned with an IP address 172.17.0.0/16. Daemon option --bip can be >
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.843825153Z" level=info msg="Loading containers: done."
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.854111853Z" level=warning msg="WARNING: bridge-nf-call-iptables is disabled"
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.854136174Z" level=warning msg="WARNING: bridge-nf-call-ip6tables is disabled"
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.854157369Z" level=info msg="Docker daemon" commit=8b539b8 containerd-snapshotter=false storage-driver=overlay2 version=27.2.1
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.854207965Z" level=info msg="Daemon has completed initialization"
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.884873396Z" level=info msg="API listen on [::]:2376"
Sep 12 15:24:00 docker-host dockerd-rootless.sh[2435]: time="2024-09-12T15:24:00.884954622Z" level=info msg="API listen on /run/user/1001/docker.sock"
Sep 12 15:24:00 docker-host systemd[982]: Started docker.service - Docker Application Container Engine (Rootless).
lines 1-25/25 (END)

I just logged into root, eliminated the ~/.docker folder inside of root.

root@docker-host:~# ls -la
total 36
drwx------  4 root root 4096 Sep 12 15:27 .
drwxr-xr-x 23 root root 4096 Sep 12 15:06 ..
-rw-------  1 root root 1906 Sep 11 22:38 .bash_history
-rw-r--r--  1 root root 3106 Apr 22 13:04 .bashrc
-rw-------  1 root root   20 Sep 12 15:24 .lesshst
drwxr-x---  3 root root 4096 Sep  9 15:34 .local
-rw-r--r--  1 root root  161 Apr 22 13:04 .profile
drwx------  2 root root 4096 Sep  9 14:40 .ssh
-rw-r--r--  1 root root  225 Sep  9 14:41 .wget-hsts
root@docker-host:~# su node
node@docker-host:/root$ cd ~

The fact that node is a member of the sudo group generate this?

+++ grep -m1 '^node
node
node
node
root
root
root
root
root
root
root
root' /etc/passwd
++ DOCKER_USER_HOME=/root
konstruktoid commented 2 months ago

what does ps -ef | grep docker return?

osorito commented 2 months ago
node@docker-host:~$ ps -ef | grep docker
node        5265    1010  0 16:33 ?        00:00:00 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
node        5275    5265  0 16:33 ?        00:00:00 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
node        5301    5275  0 16:33 ?        00:00:00 dockerd
node        5318    5301  0 16:33 ?        00:00:05 containerd --config /run/user/1001/docker/containerd/containerd.toml
node        6410    6403  0 18:33 pts/0    00:00:00 grep --color=auto docker
node@docker-host:~$ 
konstruktoid commented 2 months ago

I wonder where the root user comes from in the above logs. What's the output of these two?

ps -eo user,cmd | grep docker

grep -m1 "^$(ps -eo user,cmd | grep docker | grep -v grep | awk '{ print $1 }')" /etc/passwd | awk -F':' '{ print $6 }'
osorito commented 2 months ago
node@docker-host:/home/omar$ ps -eo user,cmd | grep docker
node     rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
node     /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=builtin --copy-up=/etc --copy-up=/run --propagation=rslave /usr/bin/dockerd-rootless.sh
node     dockerd
node     containerd --config /run/user/1001/docker/containerd/containerd.toml
node     grep --color=auto docker

node@docker-host:~$ grep -m1 "^$(ps -eo user,cmd | grep docker | grep -v grep | awk '{ print $1 }')" /etc/passwd | awk -F':' '{ print $6 }'
/home/node
node@docker-host:~$ 
konstruktoid commented 2 months ago

I'm just wondering where this came from.

++++ awk '{ print $1 }'
+++ grep -m1 '^node
node
node
node
root
root
root
root
root
root
root
root' /etc/passwd
++ DOCKER_USER_HOME=/root

When the result is the above, does the script work?

node@docker-host:~$ grep -m1 "^$(ps -eo user,cmd | grep docker | grep -v grep | awk '{ print $1 }')" /etc/passwd | awk -F':' '{ print $6 }'
/home/node
node@docker-host:~$ 
osorito commented 2 months ago

If you run it by providing the host after sudo it does.

node@docker-host:~/docker-bench-security$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default      Current DOCKER_HOST based configuration   tcp://localhost:2376                
rootless *   Rootless mode                             unix:///run/user/1001/docker.sock   
node@docker-host:~/docker-bench-security$ 

node@docker-host:~/docker-bench-security$ mycontext="$(docker context ls | grep "*" | awk '{print $5}')"
echo "$mycontext"
sudo DOCKER_HOST=$mycontext sh docker-bench-security.sh
unix:///run/user/1001/docker.sock
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-13T15:26:08+00:00

Section A - Check results

[INFO] 1 - Host Configuration
[INFO] 1.1 - Linux Hosts Specific Configuration
[WARN] 1.1.1 - Ensure a separate partition for containers has been created (Automated)
[INFO] 1.1.2 - Ensure only trusted users are allowed to control Docker daemon (Automated)
[INFO]       * Users: node
[PASS] 1.1.3 - Ensure auditing is configured for the Docker daemon (Automated)
[PASS] 1.1.4 - Ensure auditing is configured for Docker files and directories -/run/containerd (Automated)
[PASS] 1.1.5 - Ensure auditing is configured for Docker files and directories - /var/lib/docker (Automated)
[PASS] 1.1.6 - Ensure auditing is configured for Docker files and directories - /etc/docker (Automated)
[PASS] 1.1.7 - Ensure auditing is configured for Docker files and directories - docker.service (Automated)
[WARN] 1.1.8 - Ensure auditing is configured for Docker files and directories - containerd.sock (Automated)
[PASS] 1.1.9 - Ensure auditing is configured for Docker files and directories - docker.socket (Automated)
[PASS] 1.1.10 - Ensure auditing is configured for Docker files and directories - /etc/default/docker (Automated)
[INFO] 1.1.11 - Ensure auditing is configured for Dockerfiles and directories - /etc/docker/daemon.json (Automated)
[INFO]        * File not found
[PASS] 1.1.12 - 1.1.12 Ensure auditing is configured for Dockerfiles and directories - /etc/containerd/config.toml (Automated)
[INFO] 1.1.13 - Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker (Automated)
[INFO]        * File not found
[PASS] 1.1.14 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd (Automated)
[PASS] 1.1.15 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim (Automated)
[PASS] 1.1.16 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v1 (Automated)
[PASS] 1.1.17 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v2 (Automated)
[PASS] 1.1.18 - Ensure auditing is configured for Docker files and directories - /usr/bin/runc (Automated)
[INFO] 1.2 - General Configuration
[NOTE] 1.2.1 - Ensure the container host has been Hardened (Manual)
[PASS] 1.2.2 - Ensure that the version of Docker is up to date (Manual)
[INFO]        * Using 27.2.1 which is current
[INFO]        * Check with your operating system vendor for support and security maintenance for Docker

[INFO] 2 - Docker daemon configuration
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)
docker-bench-security.sh: 37: [[: not found
[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[PASS] 2.3 - Ensure the logging level is set to 'info' (Scored)
docker-bench-security.sh: 96: [[: not found
[PASS] 2.4 - Ensure Docker is allowed to make changes to iptables (Scored)
docker-bench-security.sh: 118: [[: not found
[PASS] 2.5 - Ensure insecure registries are not used (Scored)
[PASS] 2.6 - Ensure aufs storage driver is not used (Scored)
[INFO] 2.7 - Ensure TLS authentication for Docker daemon is configured (Scored)
[INFO]      * Docker daemon not listening on TCP
docker-bench-security.sh: 185: [[: not found
[INFO] 2.8 - Ensure the default ulimit is configured appropriately (Manual)
[INFO]      * Default ulimit doesn't appear to be set
docker-bench-security.sh: 208: [[: not found
[WARN] 2.9 - Enable user namespace support (Scored)
[PASS] 2.10 - Ensure the default cgroup usage has been confirmed (Scored)
[PASS] 2.11 - Ensure base device size is not changed until needed (Scored)
docker-bench-security.sh: 276: [[: not found
[WARN] 2.12 - Ensure that authorization for Docker client commands is enabled (Scored)
[PASS] 2.13 - Ensure centralized and remote logging is configured (Scored)
[WARN] 2.14 - Ensure containers are restricted from acquiring new privileges (Scored)
[PASS] 2.15 - Ensure live restore is enabled (Scored)
[WARN] 2.16 - Ensure Userland Proxy is Disabled (Scored)
[INFO] 2.17 - Ensure that a daemon-wide custom seccomp profile is applied if appropriate (Manual)
[INFO] Ensure that experimental features are not implemented in production (Scored) (Deprecated)

[INFO] 3 - Docker daemon configuration files
[PASS] 3.1 - Ensure that the docker.service file ownership is set to root:root (Automated)
[PASS] 3.2 - Ensure that docker.service file permissions are appropriately set (Automated)
[PASS] 3.3 - Ensure that docker.socket file ownership is set to root:root (Automated)
[PASS] 3.4 - Ensure that docker.socket file permissions are set to 644 or more restrictive (Automated)
[PASS] 3.5 - Ensure that the /etc/docker directory ownership is set to root:root (Automated)
[PASS] 3.6 - Ensure that /etc/docker directory permissions are set to 755 or more restrictively (Automated)
[PASS] 3.7 - Ensure that registry certificate file ownership is set to root:root (Automated)
[PASS] 3.8 - Ensure that registry certificate file permissions are set to 444 or more restrictively (Automated)
[INFO] 3.9 - Ensure that TLS CA certificate file ownership is set to root:root (Automated)
[INFO]      * No TLS CA certificate found
[INFO] 3.10 - Ensure that TLS CA certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS CA certificate found
[INFO] 3.11 - Ensure that Docker server certificate file ownership is set to root:root (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.12 - Ensure that the Docker server certificate file permissions are set to 444 or more restrictively (Automated)
[INFO]       * No TLS Server certificate found
[INFO] 3.13 - Ensure that the Docker server certificate key file ownership is set to root:root (Automated)
[INFO]       * No TLS Key found
[INFO] 3.14 - Ensure that the Docker server certificate key file permissions are set to 400 (Automated)
[INFO]       * No TLS Key found
[INFO] 3.15 - Ensure that the Docker socket file ownership is set to root:docker (Automated)
[INFO]       * File not found
[INFO] 3.16 - Ensure that the Docker socket file permissions are set to 660 or more restrictively (Automated)
[INFO]       * File not found
[INFO] 3.17 - Ensure that the daemon.json file ownership is set to root:root (Automated)
[INFO]       * File not found
[INFO] 3.18 - Ensure that daemon.json file permissions are set to 644 or more restrictive (Automated)
[INFO]       * File not found
[PASS] 3.19 - Ensure that the /etc/default/docker file ownership is set to root:root (Automated)
[PASS] 3.20 - Ensure that the /etc/default/docker file permissions are set to 644 or more restrictively (Automated)
[INFO] 3.21 - Ensure that the /etc/sysconfig/docker file permissions are set to 644 or more restrictively (Automated)
[INFO]       * File not found
[INFO] 3.22 - Ensure that the /etc/sysconfig/docker file ownership is set to root:root (Automated)
[INFO]       * File not found
[PASS] 3.23 - Ensure that the Containerd socket file ownership is set to root:root (Automated)
[PASS] 3.24 - Ensure that the Containerd socket file permissions are set to 660 or more restrictively (Automated)

[INFO] 4 - Container Images and Build File
[INFO] 4.1 - Ensure that a user for the container has been created (Automated)
[INFO]      * No containers running
[NOTE] 4.2 - Ensure that containers use only trusted base images (Manual)
[NOTE] 4.3 - Ensure that unnecessary packages are not installed in the container (Manual)
[NOTE] 4.4 - Ensure images are scanned and rebuilt to include security patches (Manual)
[PASS] 4.5 - Ensure Content trust for Docker is Enabled (Automated)
[PASS] 4.6 - Ensure that HEALTHCHECK instructions have been added to container images (Automated)
[PASS] 4.7 - Ensure update instructions are not used alone in the Dockerfile (Manual)
[NOTE] 4.8 - Ensure setuid and setgid permissions are removed (Manual)
[PASS] 4.9 - Ensure that COPY is used instead of ADD in Dockerfiles (Manual)
[NOTE] 4.10 - Ensure secrets are not stored in Dockerfiles (Manual)
[NOTE] 4.11 - Ensure only verified packages are installed (Manual)
[NOTE] 4.12 - Ensure all signed artifacts are validated (Manual)

[INFO] 5 - Container Runtime
[INFO]   * No containers running, skipping Section 5
[PASS] 5.1 - Ensure swarm mode is not Enabled, if not needed (Automated)

[INFO] 6 - Docker Security Operations
[INFO] 6.1 - Ensure that image sprawl is avoided (Manual)
[INFO]      * There are currently: 0 images
[INFO] 6.2 - Ensure that container sprawl is avoided (Manual)
[INFO]      * There are currently a total of 0 containers, with 0 of them currently running

[INFO] 7 - Docker Swarm Configuration
[PASS] 7.1 - Ensure that the minimum number of manager nodes have been created in a swarm (Automated) (Swarm mode not enabled)
[PASS] 7.2 - Ensure that swarm services are bound to a specific host interface (Automated) (Swarm mode not enabled)
[PASS] 7.3 - Ensure that all Docker swarm overlay networks are encrypted (Automated)
[PASS] 7.4 - Ensure that Docker's secret management commands are used for managing secrets in a swarm cluster (Manual) (Swarm mode not enabled)
[PASS] 7.5 - Ensure that swarm manager is run in auto-lock mode (Automated) (Swarm mode not enabled)
[PASS] 7.6 - Ensure that the swarm manager auto-lock key is rotated periodically (Manual) (Swarm mode not enabled)
[PASS] 7.7 - Ensure that node certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.8 - Ensure that CA certificates are rotated as appropriate (Manual) (Swarm mode not enabled)
[PASS] 7.9 - Ensure that management plane traffic is separated from data plane traffic (Manual) (Swarm mode not enabled)

Section C - Score

[INFO] Checks: 86
[INFO] Score: 33

node@docker-host:~/docker-bench-security$ 

Problem I see is that it only considers the default context, the possibility of other context is not considered.

docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *                                             unix:///var/run/docker.sock 

Take into consideration the tool suggest you to use the daemon as a non-root.

[INFO] 2 - Docker daemon configuration
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)
konstruktoid commented 2 months ago

That's good at least. And 2.1 is a manual check in the benchmark so that's why it's not actually checking anything.

konstruktoid commented 2 months ago

A couple of scripting errors.

[INFO] 2 - Docker daemon configuration
[NOTE] 2.1 - Run the Docker daemon as a non-root user, if possible (Manual)
docker-bench-security.sh: 37: [[: not found
[WARN] 2.2 - Ensure network traffic is restricted between containers on the default bridge (Scored)
[PASS] 2.3 - Ensure the logging level is set to 'info' (Scored)
docker-bench-security.sh: 96: [[: not found
[PASS] 2.4 - Ensure Docker is allowed to make changes to iptables (Scored)
docker-bench-security.sh: 118: [[: not found
[PASS] 2.5 - Ensure insecure registries are not used (Scored)
[PASS] 2.6 - Ensure aufs storage driver is not used (Scored)
[INFO] 2.7 - Ensure TLS authentication for Docker daemon is configured (Scored)
[INFO]      * Docker daemon not listening on TCP
docker-bench-security.sh: 185: [[: not found
[INFO] 2.8 - Ensure the default ulimit is configured appropriately (Manual)
[INFO]      * Default ulimit doesn't appear to be set
docker-bench-security.sh: 208: [[: not found
osorito commented 2 months ago

Even if you set the options manually , script does not detect it.

example

node@docker-host:~/.config/systemd/user/docker.service.d$ sudo cat /home/node/.config/systemd/user/docker.service.d/override.conf

[Service]
Environment=DOCKERD_ROOTLESS_ROOTLESSKIT_FLAGS="-p 0.0.0.0:2376:2376/tcp" \
  dockerd-rootless.sh \
  -H tcp://docker-host:2376 \
  --no-new-privileges --icc=false --userns-remap=default
  --tlsverify --tlscacert=/home/node/.docker/ca.pem \
  --tlscert=/home/node/.docker/cert.pem \
  --tlskey=/home/node/.docker/key.pem

node@docker-host:~/.config/systemd/user/docker.service.d$ 
node@docker-host:~/.config/systemd/user/docker.service.d$ systemctl --user status docker.service
● docker.service - Docker Application Container Engine (Rootless)
     Loaded: loaded (/home/node/.config/systemd/user/docker.service; enabled; preset: enabled)
    Drop-In: /home/node/.config/systemd/user/docker.service.d
             └─override.conf
     Active: active (running) since Fri 2024-09-13 17:25:49 UTC; 3min 48s ago
       Docs: https://docs.docker.com/go/rootless/
   Main PID: 83885 (rootlesskit)
      Tasks: 34
     Memory: 43.1M (peak: 45.6M)
        CPU: 832ms
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─83885 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=aut>
             ├─83895 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=>
             ├─83914 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 83895 tap0
             ├─83921 dockerd
             └─83939 containerd --config /run/user/1001/docker/containerd/containerd.toml

Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.612847283Z" level=info msg="[graphdriver] using prior storage driver: overlay>
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.613331333Z" level=info msg="Loading containers: start."
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.613536136Z" level=info msg="skipping firewalld management for rootless mode"
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.837263437Z" level=info msg="Default bridge (docker0) is assigned with an IP a>
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.908430753Z" level=info msg="Loading containers: done."
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.918467195Z" level=info msg="Docker daemon" commit=8b539b8 containerd-snapshot>
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.918549281Z" level=info msg="Daemon has completed initialization"
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.949569888Z" level=info msg="API listen on [::]:2376"
Sep 13 17:25:49 docker-host dockerd-rootless.sh[83921]: time="2024-09-13T17:25:49.949666729Z" level=info msg="API listen on /run/user/1001/docker.sock"
Sep 13 17:25:49 docker-host systemd[1012]: Started docker.service - Docker Application Container Engine (Rootless).
lines 1-27/27 (END)

I know the override is working, testing securing the daemon with tls

Omars-MacBook-Pro:t7 omar$ docker version
Client:
 Version:           27.1.1
 API version:       1.46
 Go version:        go1.21.12
 Git commit:        6312585
 Built:             Tue Jul 23 19:54:12 2024
 OS/Arch:           darwin/amd64
 Context:           default

Server: Docker Engine - Community
 Engine:
  Version:          27.2.1
  API version:      1.47 (minimum version 1.24)
  Go version:       go1.22.7
  Git commit:       8b539b8
  Built:            Fri Sep  6 12:08:02 2024
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.7.22
  GitCommit:        7f7fdf5fed64eb6a7caf99b3e12efcf9d60e311c
 runc:
  Version:          1.1.14
  GitCommit:        v1.1.14-0-g2c9f560
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
 rootlesskit:
  Version:          2.0.2
  ApiVersion:       1.1.1
  NetworkDriver:    slirp4netns
  PortDriver:       builtin
  StateDir:         /run/user/1001/dockerd-rootless
 slirp4netns:
  Version:          1.2.1
  GitCommit:        09e31e92fa3d2a1d3ca261adaeb012c8d75a8194
Omars-MacBook-Pro:t7 omar$
node@docker-host:~/.config/systemd/user/docker.service.d$ sudo cat ~/.config/docker/daemon.json

{
  "log-driver": "syslog",
  "log-level": "info",
  "iptables": true,
  "insecure-registries": [],
  "live-restore": true,
  "userland-proxy": false,
  "tls": true,
  "tlscacert": "/home/node/.config/docker/certs.d/ca.pem",
  "tlscert": "/home/node/.config/docker/certs.d/server_cert.pem",
  "tlskey": "/home/node/.config/docker/certs.d/server_key.pem",
  "hosts": ["tcp://0.0.0.0:2376","unix:///run/user/1001/docker.sock"],
  "icc": false
}

node@docker-host:~/.config/systemd/user/docker.service.d$ 

The interesting part , is that if you use docker without rootless and set icc in the override.conf and the daemon.json it would complain since the line is on both sides. As you can see docker does not complain.

konstruktoid commented 1 month ago

Yeah, it def need some more testing.

osorito commented 1 month ago

I'm under the impression the function helper_lib.sh was improved?

root@docker-host:/home/node/docker-bench-security/functions# cat helper_lib.sh
#!/bin/bash

# Returns the absolute path of a given string
abspath () { case "$1" in /*)printf "%s\n" "$1";; *)printf "%s\n" "$PWD/$1";; esac; }

# Audit rules default path
auditrules="/etc/audit/audit.rules"

# Check for required program(s)
req_programs() {
  for p in $1; do
    command -v "$p" >/dev/null 2>&1 || { printf "Required program not found: %s\n" "$p"; exit 1; }
  done

It looks for required programs, docker . It claims its not found.

node@docker-host:~/docker-bench-security/functions$ cd ~/docker-bench-security
mycontext="$(docker context ls | grep "*" | awk '{print $5}')"
echo "$mycontext"
sudo DOCKER_HOST=$mycontext sh docker-bench-security.sh
unix:///run/user/1001/docker.sock
Required program not found: docker
node@docker-host:~/docker-bench-security$ command -v docker
/home/node/bin/docker
node@docker-host:~/docker-bench-security$ 
konstruktoid commented 1 month ago

What does you docker context actually return?

$ docker context ls | grep "*" | awk '{print $5}'
based
$ docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
osorito commented 1 month ago

node@docker-host:~/test$ docker context ls | grep "*" | awk '{print $5}' unix:///run/user/1001/docker.sock

osorito commented 1 month ago

Found problem on my side.

node@docker-host:/usr/local/lynis$ cd ~/docker-bench-security
mycontext="$(docker context ls | grep "*" | awk '{print $5}')"
echo "$mycontext"
sudo DOCKER_HOST=$mycontext sh docker-bench-security.sh
unix:///run/user/1001/docker.sock
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-23T19:26:16+00:00

Section A - Check results

Normally I install normal docker, then I follow steps on https://docs.docker.com/engine/security/rootless/ to set it as rootles.

Found alternative way to install rootless without installing docker first.

sudo apt-get update
sudo apt-get upgrade  -y
sudo apt-get install uidmap -y
sudo apt-get install curl -y
sudo apt-get install acl -y
sudo apt-get install dbus-user-session -y
sudo apt-get install systemd-container -y
sudo apt-get install ebtables -y
sudo addgroup docker
sudo useradd -m node  -s /bin/bash
sudo usermod -aG sudo,docker  node
sudo passwd node
## log in as node
su node
sudo mkdir -p ~/.ssh
sudo cp -p  /home/omar/.ssh/authorized_keys /home/node/.ssh/authorized_keys
sudo chown node:docker /home/node/.ssh/authorized_keys
sudo echo '0' > /proc/sys/kernel/apparmor_restrict_unprivileged_userns
cd ~
curl -fsSL https://get.docker.com/rootless | sh

With this second method, it does not find docker.

osorito commented 1 month ago

Modified docker-bench-security.sh

export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/:/home/node/bin"

export PATH="$PATH:/bin:/sbin:/usr/bin:/usr/local/bin:/usr/sbin/:/home/node/bin:/home/~$USER/bin"

cd ~/docker-bench-security
mycontext="$(docker context ls | grep "*" | awk '{print $5}')"
echo "$mycontext"
sudo DOCKER_HOST=$mycontext sh docker-bench-security.sh
unix:///run/user/1001/docker.sock
# --------------------------------------------------------------------------------------------
# Docker Bench for Security v1.6.0
#
# Docker, Inc. (c) 2015-2024
#
# Checks for dozens of common best-practices around deploying Docker containers in production.
# Based on the CIS Docker Benchmark 1.6.0.
# --------------------------------------------------------------------------------------------

Initializing 2024-09-23T21:44:00+00:00

Section A - Check results

modified helper_lib.sh

get_docker_configuration_file() {
  DOCKER_USER_HOME="$(grep "$(ps -eo user | grep docker | sort -u)" /etc/passwd | awk -F: '/\/home/ && ($3 > 1000) {printf "/home/%s\n",$1}' /etc/passwd)"
  FILE="$(get_docker_effective_command_line_args '--config-file' | \
    sed 's/.*=//g')"

  if [ -f "$FILE" ]; then
    CONFIG_FILE="$FILE"
    return
  fi
  if [ -f '/etc/docker/daemon.json' ]; then
    CONFIG_FILE='/etc/docker/daemon.json'
    return
  fi
  if [ -f "${DOCKER_USER_HOME}/.config/docker/daemon.json" ]; then
    CONFIG_FILE="${DOCKER_USER_HOME}/.config/docker/daemon.json"
    return
  fi
  CONFIG_FILE='/dev/null'
}

modified

get_service_file() {
  SERVICE="$1"
  DOCKER_USER_HOME="$(grep "$(ps -eo user | grep docker | sort -u)" /etc/passwd | awk -F: '/\/home/ && ($3 > 1000) {printf "/home/%s\n",$1}' /etc/passwd)"
  if [ -f "/etc/systemd/system/$SERVICE" ]; then
    echo "/etc/systemd/system/$SERVICE"
    return
  fi
  if [ -f "/lib/systemd/system/$SERVICE" ]; then
    echo "/lib/systemd/system/$SERVICE"
    return
  fi
  if  [ -f "${DOCKER_USER_HOME}/.config/systemd/user/$SERVICE" ]; then
     echo "${DOCKER_USER_HOME}/.config/systemd/user/$SERVICE"
  fi

  if find /run -name "$SERVICE" 2> /dev/null 1>&2; then
    find /run -name "$SERVICE" | head -n1
    return
  fi
  if [ "$(systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//')" != "" ]; then
    systemctl show -p FragmentPath "$SERVICE" | sed 's/.*=//'
    return
  fi
  echo "/usr/lib/systemd/system/$SERVICE"
}

Tool expect user and group to be root, if you set it as the tool expects. Docker stops working.

node@docker-host:~/.config/systemd/user$ ls -la
total 20
drwxrwx--- 4 node node   4096 Sep 23 20:18 .
drwxrwx--- 3 node node   4096 Sep 23 20:18 ..
drwxr-xr-x 2 node node   4096 Sep 23 20:18 default.target.wants
-rw-rw---- 1 node node    646 Sep 23 20:18 docker.service
drwxr-x--- 2 node docker 4096 Sep 23 20:18 docker.service.d
node@docker-host:~/.config/systemd/user$ sudo chown root:root docker.service
node@docker-host:~/.config/systemd/user$ systemctl --user daemon-reload
node@docker-host:~/.config/systemd/user$ systemctl --user restart docker.service
Failed to restart docker.service: Unit docker.service not found.
node@docker-host:~/.config/systemd/user$ systemctl --user status docker.service
● docker.service
     Loaded: not-found (Reason: Unit docker.service not found.)
     Active: active (running) since Mon 2024-09-23 22:18:26 UTC; 20min ago
   Main PID: 201519 (rootlesskit)
        CPU: 3.220s
     CGroup: /user.slice/user-1001.slice/user@1001.service/app.slice/docker.service
             ├─201519 rootlesskit --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=bui>
             ├─201530 /proc/self/exe --state-dir=/run/user/1001/dockerd-rootless --net=slirp4netns --mtu=65520 --slirp4netns-sandbox=auto --slirp4netns-seccomp=auto --disable-host-loopback --port-driver=>
             ├─201546 slirp4netns --mtu 65520 -r 3 --disable-host-loopback --enable-sandbox --enable-seccomp 201530 tap0
             ├─201554 dockerd
             ├─201573 containerd --config /run/user/1001/docker/containerd/containerd.toml
             └─201832 /home/node/bin/containerd-shim-runc-v2 -namespace moby -id 7c06988750740d0c18c172ccdbee6d5cb73900a9b440ea7f53b386930903cc10 -address /run/user/1001/docker/containerd/containerd.sock

The tests are looking at the wrong path for rootless.

node@docker-host:~/bin$ pwd
/home/node/bin
node@docker-host:~/bin$ ls -la
total 313348
drwxrwx---  2 node node       4096 Sep 23 20:18 .
drwxr-x--- 10 node node       4096 Sep 23 22:42 ..
-rwxr-x---  1 node node   39796888 Sep 20 11:43 containerd
-rwxr-x---  1 node node   12832920 Sep 20 11:43 containerd-shim-runc-v2
-rwxr-x---  1 node node   19804312 Sep 20 11:43 ctr
-rwxr-x---  1 node node   39536632 Sep 20 11:43 docker
-rwxr-x---  1 node docker 63789632 Sep 23 20:18 docker-compose
-rwxr-x---  1 node node     708448 Sep 20 11:43 docker-init
-rwxr-x---  1 node node    2074741 Sep 20 11:43 docker-proxy
-rwxr-x---  1 node node   72343624 Sep 20 11:43 dockerd
-rwxrwx---  1 node node      14967 Sep 20 11:43 dockerd-rootless-setuptool.sh
-rwxrwx---  1 node node       7249 Sep 20 11:43 dockerd-rootless.sh
-rwxr-x---  1 node node   12391273 Sep 20 11:43 rootlesskit
-rwxr-x---  1 node node    7797930 Sep 20 11:43 rootlesskit-docker-proxy
-rwxr-x---  1 node node   15705168 Sep 20 11:43 runc
-rwxr-x---  1 node node   34019520 Sep 20 11:43 vpnkit
node@docker-host:~/bin$ 
[INFO] 1.1.13 - Ensure auditing is configured for Docker files and directories - /etc/sysconfig/docker (Automated)
[INFO]        * File not found
[INFO] 1.1.14 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd (Automated)
[INFO]         * File not found
[INFO] 1.1.15 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim (Automated)
[INFO]         * File not found
[INFO] 1.1.16 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v1 (Automated)
[INFO]         * File not found
[INFO] 1.1.17 - Ensure auditing is configured for Docker files and directories - /usr/bin/containerd-shim-runc-v2 (Automated)
[INFO]         * File not found
[INFO] 1.1.18 - Ensure auditing is configured for Docker files and directories - /usr/bin/runc (Automated)
[INFO]         * File not found
konstruktoid commented 1 month ago

yeah, since the tool hasn't been designed for rootless docker (that didn't exist back then) it will miss alot of things. all audit tests are based on the benchmark which only has rootless as a recommendation, so the paths are all "wrong". i'll add an suggestion to CIS.

how would we test a host that is running multiple rootless Docker services? if we're not running the script using sudo or being root, assume rootless and check rootless Docker as the current user?

osorito commented 1 month ago

Don't assume, lets look after the context.

Example

docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT               ERROR
default *                                             unix:///var/run/docker.sock

If the context is "default *" unix:///var/run/docker.sock it would be the standard docker configuration and that is what is hard coded on the tool.

node@docker-host:~$ docker context ls
NAME         DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default      Current DOCKER_HOST based configuration   unix:///var/run/docker.sock         
rootless *   Rootless mode                             unix:///run/user/1001/docker.sock   

If the context is "rootless *" unix:///run/user/1001/docker.sock the tool should check based on that option. When you run the tool, there are many options example -p provides output and informs you how to deal with the warnings. There could be an option for rootless, if the tool sees the option it should check based on it. There could be a dictionary or json file with parameters based on the context. That way the tools would be more open, to different context options.

konstruktoid commented 1 month ago

it works until you set DOCKER_HOST

$ docker context ls
NAME        DESCRIPTION                               DOCKER ENDPOINT                     ERROR
default *   Current DOCKER_HOST based configuration   unix:///run/user/1001/docker.sock
Warning: DOCKER_HOST environment variable overrides the active context. To use a context, either set the global --context flag, or unset DOCKER_HOST environment variable.
osorito commented 1 month ago

in ~/.bashrc add

export PATH=/home/node/bin:$PATH
export DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1001/bus"
#[INFO] Some applications may require the following environment variable too:
#export DOCKER_HOST="unix:///run/user/1001/docker.sock"

run

unset DOCKER_HOST
source ~/.bashrc

After installing rootless

          systemctl --user daemon-reload
          systemctl --user restart docker.service
          sudo loginctl  enable-linger node

At reboot to prevent problems, create a script file.

node@docker-host:~$ sudo cat boot_job.sh

#!/bin/bash
sudo echo '0' > /proc/sys/kernel/apparmor_restrict_unprivileged_userns
sudo modprobe br_netfilter
sudo lsmod | grep br_netfilter > /home/node/netfilter.log

node@docker-host:~$ ls boot_job.sh -la
-rwxr-x--- 1 node docker 170 Sep 24 17:38 boot_job.sh
node@docker-host:~$ 

add cron job at @reboot @reboot /home/node/boot_job.sh

konstruktoid commented 1 month ago

yeah i do all such things using ansible, but docker-bench-security needs to support many of these configurations which is a hassle.