| #!/bin/bash | |
| set -e | |
| # Set the container env-var, so that AppArmor is enabled in the daemon and | |
| # containerd when running docker-in-docker. | |
| # | |
| # see: https://github.com/containerd/containerd/blob/787943dc1027a67f3b52631e084db0d4a6be2ccc/pkg/apparmor/apparmor_linux.go#L29-L45 | |
| # see: https://github.com/moby/moby/commit/de191e86321f7d3136ff42ff75826b8107399497 | |
| container=docker | |
| export container | |
| if [ $# -eq 0 ]; then | |
| echo >&2 'ERROR: No command specified. You probably want to run `journalctl -f`, or maybe `bash`?' | |
| exit 1 | |
| fi | |
| if [ ! -t 0 ]; then | |
| echo >&2 'ERROR: TTY needs to be enabled (`docker run -t ...`).' | |
| exit 1 | |
| fi | |
| # Mount /tmp (conditionally) | |
| # /tmp must be 'exec,rw', and 'dev' (defaults) to allow mknod to work for the | |
| # pkg/archive/archive_linux_test.go tests. | |
| if ! mountpoint -q /tmp; then | |
| mount -t tmpfs none /tmp | |
| fi | |
| # Change mount propagation to shared, which SystemD PID 1 would normally do | |
| # itself when started by the kernel. SystemD skips that when it detects it is | |
| # running in a container. | |
| mount --make-rshared / | |
| # Allow AppArmor to work inside the container; | |
| # | |
| # aa-status | |
| # apparmor filesystem is not mounted. | |
| # apparmor module is loaded. | |
| # | |
| # mount -t securityfs none /sys/kernel/security | |
| # | |
| # aa-status | |
| # apparmor module is loaded. | |
| # 30 profiles are loaded. | |
| # 30 profiles are in enforce mode. | |
| # /snap/snapd/18357/usr/lib/snapd/snap-confine | |
| # ... | |
| # | |
| # Note: https://0xn3va.gitbook.io/cheat-sheets/container/escaping/sensitive-mounts#sys-kernel-security | |
| # | |
| # ## /sys/kernel/security | |
| # | |
| # In /sys/kernel/security mounted the securityfs interface, which allows | |
| # configuration of Linux Security Modules. This allows configuration of | |
| # AppArmor policies, and so access to this may allow a container to disable | |
| # its MAC system. | |
| # | |
| # Given that we're running privileged already, this should not be an issue. | |
| if [ -d /sys/kernel/security ] && ! mountpoint -q /sys/kernel/security; then | |
| mount -t securityfs none /sys/kernel/security || { | |
| echo >&2 'Could not mount /sys/kernel/security.' | |
| echo >&2 'AppArmor detection and --privileged mode might break.' | |
| } | |
| fi | |
| if [ "${FIREWALLD:-}" = "true" ]; then | |
| # Allow connections coming from the host (through eth0). This is needed to | |
| # access the daemon port (independently of which port is used), or run a | |
| # 'remote' Delve session, etc... | |
| cat > /etc/firewalld/zones/trusted.xml << EOF | |
| <?xml version="1.0" encoding="utf-8"?> | |
| <zone target="ACCEPT"> | |
| <short>Trusted</short> | |
| <description>All network connections are accepted.</description> | |
| <interface name="eth0"/> | |
| <forward/> | |
| </zone> | |
| EOF | |
| # Increase firewalld log verbosity to help debug issues | |
| cat > /etc/systemd/system/firewalld.service << EOF | |
| [Service] | |
| ExecStart= | |
| ExecStart=/usr/sbin/firewalld --nofork --nopid --debug=4 | |
| EOF | |
| # Copy firewalld logs into the bundles/ folder on shutdown to let the CI | |
| # include it in jobs reports. | |
| cat > /etc/systemd/system/collect-firewalld-logs.service << EOF | |
| [Unit] | |
| Description=Collect firewalld logs on shutdown | |
| After=firewalld.service | |
| [Service] | |
| Type=oneshot | |
| ExecStart=/bin/true | |
| RemainAfterExit=true | |
| ExecStop=cp /var/log/firewalld /go/src/github.com/docker/docker/bundles/firewalld.log | |
| [Install] | |
| WantedBy=firewalld.service | |
| EOF | |
| systemctl enable collect-firewalld-logs.service | |
| fi | |
| env > /etc/docker-entrypoint-env | |
| cat > /etc/systemd/system/docker-entrypoint.target << EOF | |
| [Unit] | |
| Description=the target for docker-entrypoint.service | |
| Requires=docker-entrypoint.service systemd-logind.service systemd-user-sessions.service $([ "${FIREWALLD:-}" = "true" ] && echo firewalld.service) | |
| EOF | |
| quoted_args="$(printf " %q" "${@}")" | |
| echo "${quoted_args}" > /etc/docker-entrypoint-cmd | |
| cat > /etc/systemd/system/docker-entrypoint.service << EOF | |
| [Unit] | |
| Description=docker-entrypoint.service | |
| [Service] | |
| ExecStart=/bin/bash -exc "source /etc/docker-entrypoint-cmd" | |
| # EXIT_STATUS is either an exit code integer or a signal name string, see systemd.exec(5) | |
| ExecStopPost=/bin/bash -ec "if echo \${EXIT_STATUS} | grep [A-Z] > /dev/null; then echo >&2 \"got signal \${EXIT_STATUS}\"; systemctl exit \$(( 128 + \$( kill -l \${EXIT_STATUS} ) )); else systemctl exit \${EXIT_STATUS}; fi" | |
| StandardInput=tty-force | |
| StandardOutput=inherit | |
| StandardError=inherit | |
| WorkingDirectory=$(pwd) | |
| EnvironmentFile=/etc/docker-entrypoint-env | |
| [Install] | |
| WantedBy=multi-user.target | |
| EOF | |
| systemctl mask systemd-firstboot.service systemd-udevd.service | |
| systemctl unmask systemd-logind | |
| systemctl enable docker-entrypoint.service | |
| systemd= | |
| if [ -x /lib/systemd/systemd ]; then | |
| systemd=/lib/systemd/systemd | |
| elif [ -x /usr/lib/systemd/systemd ]; then | |
| systemd=/usr/lib/systemd/systemd | |
| elif [ -x /sbin/init ]; then | |
| systemd=/sbin/init | |
| else | |
| echo >&2 'ERROR: systemd is not installed' | |
| exit 1 | |
| fi | |
| systemd_args="--show-status=false --unit=docker-entrypoint.target" | |
| echo "$0: starting $systemd $systemd_args" | |
| exec $systemd $systemd_args |