From 2f5b0e6b6464b87c18a680b2c729397395dce43e Mon Sep 17 00:00:00 2001 From: Albin Kerouanton Date: Fri, 15 Dec 2023 14:28:03 +0100 Subject: [PATCH 1/2] Switch over to xtables-legacy when nf_tables module isn't available PR #461 updated Alpine to 3.19 and made a change to load the nf_tables kernel module if needed. However, as demonstrated by #463 and #464 this might break when the host system doesn't have the nf_tables module available. In that case, we should still try to load the ip_tables module and symlink /sbin/iptables to xtables-legacy-multi. Signed-off-by: Albin Kerouanton --- 24/dind/Dockerfile | 3 +++ 24/dind/dockerd-entrypoint.sh | 12 +++++++++++- 25-rc/dind/Dockerfile | 3 +++ 25-rc/dind/dockerd-entrypoint.sh | 12 +++++++++++- Dockerfile-dind.template | 3 +++ dockerd-entrypoint.sh | 12 +++++++++++- 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/24/dind/Dockerfile b/24/dind/Dockerfile index 064a9a4bf..e6233694e 100644 --- a/24/dind/Dockerfile +++ b/24/dind/Dockerfile @@ -14,6 +14,9 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 + iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ diff --git a/24/dind/dockerd-entrypoint.sh b/24/dind/dockerd-entrypoint.sh index 056ee2ae0..f1768c6e5 100755 --- a/24/dind/dockerd-entrypoint.sh +++ b/24/dind/dockerd-entrypoint.sh @@ -143,12 +143,22 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" + use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - modprobe nf_tables || : + if ! modprobe nf_tables; then + modprobe ip_tables || : + use_xtables_legacy=true + fi + fi + if [ "$use_xtables_legacy" = "true" ]; then + ln -fs /sbin/iptables-legacy /sbin/iptables + # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. + ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore + ln -fs /sbin/iptables-legacy-save /sbin/iptables-save fi uid="$(id -u)" diff --git a/25-rc/dind/Dockerfile b/25-rc/dind/Dockerfile index 6e1182008..1304f5531 100644 --- a/25-rc/dind/Dockerfile +++ b/25-rc/dind/Dockerfile @@ -14,6 +14,9 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 + iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ diff --git a/25-rc/dind/dockerd-entrypoint.sh b/25-rc/dind/dockerd-entrypoint.sh index 056ee2ae0..f1768c6e5 100755 --- a/25-rc/dind/dockerd-entrypoint.sh +++ b/25-rc/dind/dockerd-entrypoint.sh @@ -143,12 +143,22 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" + use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - modprobe nf_tables || : + if ! modprobe nf_tables; then + modprobe ip_tables || : + use_xtables_legacy=true + fi + fi + if [ "$use_xtables_legacy" = "true" ]; then + ln -fs /sbin/iptables-legacy /sbin/iptables + # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. + ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore + ln -fs /sbin/iptables-legacy-save /sbin/iptables-save fi uid="$(id -u)" diff --git a/Dockerfile-dind.template b/Dockerfile-dind.template index f8b585328..564c30f71 100644 --- a/Dockerfile-dind.template +++ b/Dockerfile-dind.template @@ -9,6 +9,9 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 + iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ diff --git a/dockerd-entrypoint.sh b/dockerd-entrypoint.sh index 056ee2ae0..f1768c6e5 100755 --- a/dockerd-entrypoint.sh +++ b/dockerd-entrypoint.sh @@ -143,12 +143,22 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" + use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - modprobe nf_tables || : + if ! modprobe nf_tables; then + modprobe ip_tables || : + use_xtables_legacy=true + fi + fi + if [ "$use_xtables_legacy" = "true" ]; then + ln -fs /sbin/iptables-legacy /sbin/iptables + # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. + ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore + ln -fs /sbin/iptables-legacy-save /sbin/iptables-save fi uid="$(id -u)" From cadf44cf32d98c6022faa2e5f5f9e756908b2a08 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Fri, 15 Dec 2023 10:20:20 -0800 Subject: [PATCH 2/2] Adjust iptables-legacy fallback implementation to use an image-provided symlink farm instead of symlinking over package-provided files in /sbin/ at runtime --- 24/dind/Dockerfile | 28 +++++++++++++++++++++++++--- 24/dind/dockerd-entrypoint.sh | 12 +++--------- 25-rc/dind/Dockerfile | 28 +++++++++++++++++++++++++--- 25-rc/dind/dockerd-entrypoint.sh | 12 +++--------- Dockerfile-dind.template | 28 +++++++++++++++++++++++++--- dockerd-entrypoint.sh | 12 +++--------- 6 files changed, 84 insertions(+), 36 deletions(-) diff --git a/24/dind/Dockerfile b/24/dind/Dockerfile index e6233694e..1cb755153 100644 --- a/24/dind/Dockerfile +++ b/24/dind/Dockerfile @@ -14,9 +14,6 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ -# dind might be used on systems where the nf_tables kernel module isn't available. In that case, -# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 - iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ @@ -33,6 +30,31 @@ RUN set -eux; \ # TODO aufs-tools +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 +RUN set -eux; \ + apk add --no-cache iptables-legacy; \ +# set up a symlink farm we can use PATH to switch to legacy with + mkdir -p /usr/local/sbin/.iptables-legacy; \ +# https://git.alpinelinux.org/aports/tree/main/iptables/APKBUILD?id=b215d54de159eacafecb13c68dfadce6eefd9ec9#n73 + for f in \ + iptables \ + iptables-save \ + iptables-restore \ + ip6tables \ + ip6tables-save \ + ip6tables-restore \ + ; do \ +# "iptables-save" -> "iptables-legacy-save", "ip6tables" -> "ip6tables-legacy", etc. +# https://pkgs.alpinelinux.org/contents?branch=v3.19&name=iptables-legacy&arch=x86_64 + b="/sbin/${f/tables/tables-legacy}"; \ + "$b" --version; \ + ln -svT "$b" "/usr/local/sbin/.iptables-legacy/$f"; \ + done; \ +# verify it works (and gets us legacy) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH"; \ + iptables --version | grep legacy + # set up subuid/subgid so that "--userns-remap=default" works out-of-the-box RUN set -eux; \ addgroup -S dockremap; \ diff --git a/24/dind/dockerd-entrypoint.sh b/24/dind/dockerd-entrypoint.sh index f1768c6e5..c15a62417 100755 --- a/24/dind/dockerd-entrypoint.sh +++ b/24/dind/dockerd-entrypoint.sh @@ -143,23 +143,17 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then - # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) + # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 if ! modprobe nf_tables; then modprobe ip_tables || : - use_xtables_legacy=true + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi fi - if [ "$use_xtables_legacy" = "true" ]; then - ln -fs /sbin/iptables-legacy /sbin/iptables - # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. - ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore - ln -fs /sbin/iptables-legacy-save /sbin/iptables-save - fi uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/25-rc/dind/Dockerfile b/25-rc/dind/Dockerfile index 1304f5531..72f8279f5 100644 --- a/25-rc/dind/Dockerfile +++ b/25-rc/dind/Dockerfile @@ -14,9 +14,6 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ -# dind might be used on systems where the nf_tables kernel module isn't available. In that case, -# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 - iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ @@ -33,6 +30,31 @@ RUN set -eux; \ # TODO aufs-tools +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 +RUN set -eux; \ + apk add --no-cache iptables-legacy; \ +# set up a symlink farm we can use PATH to switch to legacy with + mkdir -p /usr/local/sbin/.iptables-legacy; \ +# https://git.alpinelinux.org/aports/tree/main/iptables/APKBUILD?id=b215d54de159eacafecb13c68dfadce6eefd9ec9#n73 + for f in \ + iptables \ + iptables-save \ + iptables-restore \ + ip6tables \ + ip6tables-save \ + ip6tables-restore \ + ; do \ +# "iptables-save" -> "iptables-legacy-save", "ip6tables" -> "ip6tables-legacy", etc. +# https://pkgs.alpinelinux.org/contents?branch=v3.19&name=iptables-legacy&arch=x86_64 + b="/sbin/${f/tables/tables-legacy}"; \ + "$b" --version; \ + ln -svT "$b" "/usr/local/sbin/.iptables-legacy/$f"; \ + done; \ +# verify it works (and gets us legacy) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH"; \ + iptables --version | grep legacy + # set up subuid/subgid so that "--userns-remap=default" works out-of-the-box RUN set -eux; \ addgroup -S dockremap; \ diff --git a/25-rc/dind/dockerd-entrypoint.sh b/25-rc/dind/dockerd-entrypoint.sh index f1768c6e5..c15a62417 100755 --- a/25-rc/dind/dockerd-entrypoint.sh +++ b/25-rc/dind/dockerd-entrypoint.sh @@ -143,23 +143,17 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then - # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) + # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 if ! modprobe nf_tables; then modprobe ip_tables || : - use_xtables_legacy=true + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi fi - if [ "$use_xtables_legacy" = "true" ]; then - ln -fs /sbin/iptables-legacy /sbin/iptables - # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. - ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore - ln -fs /sbin/iptables-legacy-save /sbin/iptables-save - fi uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/Dockerfile-dind.template b/Dockerfile-dind.template index 564c30f71..881ea6333 100644 --- a/Dockerfile-dind.template +++ b/Dockerfile-dind.template @@ -9,9 +9,6 @@ RUN set -eux; \ e2fsprogs-extra \ ip6tables \ iptables \ -# dind might be used on systems where the nf_tables kernel module isn't available. In that case, -# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 - iptables-legacy \ openssl \ shadow-uidmap \ xfsprogs \ @@ -28,6 +25,31 @@ RUN set -eux; \ # TODO aufs-tools +# dind might be used on systems where the nf_tables kernel module isn't available. In that case, +# we need to switch over to xtables-legacy. See https://github.com/docker-library/docker/issues/463 +RUN set -eux; \ + apk add --no-cache iptables-legacy; \ +# set up a symlink farm we can use PATH to switch to legacy with + mkdir -p /usr/local/sbin/.iptables-legacy; \ +# https://git.alpinelinux.org/aports/tree/main/iptables/APKBUILD?id=b215d54de159eacafecb13c68dfadce6eefd9ec9#n73 + for f in \ + iptables \ + iptables-save \ + iptables-restore \ + ip6tables \ + ip6tables-save \ + ip6tables-restore \ + ; do \ +# "iptables-save" -> "iptables-legacy-save", "ip6tables" -> "ip6tables-legacy", etc. +# https://pkgs.alpinelinux.org/contents?branch=v3.19&name=iptables-legacy&arch=x86_64 + b="/sbin/${f/tables/tables-legacy}"; \ + "$b" --version; \ + ln -svT "$b" "/usr/local/sbin/.iptables-legacy/$f"; \ + done; \ +# verify it works (and gets us legacy) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH"; \ + iptables --version | grep legacy + # set up subuid/subgid so that "--userns-remap=default" works out-of-the-box RUN set -eux; \ addgroup -S dockremap; \ diff --git a/dockerd-entrypoint.sh b/dockerd-entrypoint.sh index f1768c6e5..c15a62417 100755 --- a/dockerd-entrypoint.sh +++ b/dockerd-entrypoint.sh @@ -143,23 +143,17 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - use_xtables_legacy=false if ! iptables -nL > /dev/null 2>&1; then - # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using nftables with the translating "iptables" wrappers, for example) + # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 if ! modprobe nf_tables; then modprobe ip_tables || : - use_xtables_legacy=true + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi fi - if [ "$use_xtables_legacy" = "true" ]; then - ln -fs /sbin/iptables-legacy /sbin/iptables - # iptables-restore and iptables-save aren't used by dockerd currently, but let's not ship a half broken image. - ln -fs /sbin/iptables-legacy-restore /sbin/iptables-restore - ln -fs /sbin/iptables-legacy-save /sbin/iptables-save - fi uid="$(id -u)" if [ "$uid" != '0' ]; then