From 116c83ce93baef7ccbb3d55d5d142fc844667459 Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 3 Nov 2021 12:23:32 -0400 Subject: [PATCH] 15fcos: add 35coreos-iptables dracut module This implements the proposal agreed upon in: https://github.com/coreos/fedora-coreos-tracker/issues/676 On first boot and subsequent boots, we look for `/etc/fedora-coreos/iptables-legacy.stamp`. If found, we move the system back to iptables-legacy. If any modifications already exist to the configuration, we do nothing. --- .../coreos-enable-iptables-legacy.service | 19 ++++++ .../coreos-enable-iptables-legacy.sh | 62 +++++++++++++++++++ .../35coreos-iptables/module-setup.sh | 17 +++++ tests/kola/firewall/iptables-legacy/config.bu | 28 +++++++++ .../test.sh} | 7 +-- tests/kola/firewall/iptables-nft/test.sh | 18 ++++++ 6 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service create mode 100755 overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh create mode 100644 overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh create mode 100644 tests/kola/firewall/iptables-legacy/config.bu rename tests/kola/firewall/{iptables-legacy => iptables-legacy/test.sh} (69%) create mode 100755 tests/kola/firewall/iptables-nft/test.sh diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service new file mode 100644 index 0000000000..1df5092224 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service @@ -0,0 +1,19 @@ +[Unit] +Description=CoreOS Enable iptables-legacy +ConditionPathExists=/etc/initrd-release +DefaultDependencies=false +ConditionPathExists=/sysroot/etc/coreos/iptables-legacy.stamp +ConditionKernelCommandLine=!ignition.firstboot + +# On first boot, allow Ignition config to install stamp file. +After=ignition-files.service + +# On subsequent boots, just make sure the deployment is accessible. +After=ostree-prepare-root.service + +Before=initrd.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/coreos-enable-iptables-legacy diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh new file mode 100755 index 0000000000..547a275473 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -euo pipefail + +declare -A SYMLINKS=( + [ip6tables]=ip6tables-legacy + [ip6tables-restore]=ip6tables-legacy-restore + [ip6tables-save]=ip6tables-legacy-save + [iptables]=iptables-legacy + [iptables-restore]=iptables-legacy-restore + [iptables-save]=iptables-legacy-save +) + +# sanity-check the stamp file is present +if [ ! -e /sysroot/etc/coreos/iptables-legacy.stamp ]; then + exit 0 +fi + +# if legacy doesn't exist on the host anymore, do nothing +for legacy in "${SYMLINKS[@]}"; do + path=/sysroot/usr/sbin/$legacy + if [ ! -e "$path" ]; then + echo "Executable $path no longer present; exiting." + exit 0 + fi +done + +symlink_is_default() { + local symlink=$1; shift + # check that the deployment is still using the symlink (i.e. the user didn't + # do something funky), and that the OSTree default is still symlink-based + # (i.e. that we didn't change strategy and forgot to update this script) + if [ ! -L "/sysroot/$symlink" ] || [ ! -L "/sysroot/usr/$symlink" ]; then + return 1 + fi + # compare symlink targets between deployment and OSTree default + if [ "$(readlink "/sysroot/$symlink")" != "$(readlink "/sysroot/usr/$symlink")" ]; then + return 1 + fi +} + +# If there are any modifications to the symlinks, do nothing. This is basically +# like `ostree admin config-diff` but more focused and lighter/safer than doing +# a bwrap call and grepping output. +for symlink in "${!SYMLINKS[@]}"; do + symlink=/etc/alternatives/$symlink + if ! symlink_is_default "$symlink"; then + echo "Symlink $symlink is not default; exiting without modifying." + exit 0 + fi +done + +# Update symlinks for legacy backend! +for symlink in "${!SYMLINKS[@]}"; do + target=${SYMLINKS[$symlink]} + symlink=/etc/alternatives/$symlink + ln -vsf "/usr/sbin/$target" "/sysroot/$symlink" + # symlink labels don't matter, but relabel to appease unlabeled_t scanners + coreos-relabel "$symlink" +done + +rm /sysroot/etc/coreos/iptables-legacy.stamp +echo "Updated /sysroot to use iptables-legacy." diff --git a/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh new file mode 100644 index 0000000000..677f3f6188 --- /dev/null +++ b/overlay.d/15fcos/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh @@ -0,0 +1,17 @@ +install_and_enable_unit() { + unit="$1"; shift + target="$1"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "$target" "$unit" || exit 1 +} + +install() { + inst_simple readlink + + inst_simple "$moddir/coreos-enable-iptables-legacy.sh" \ + "/usr/sbin/coreos-enable-iptables-legacy" + install_and_enable_unit "coreos-enable-iptables-legacy.service" \ + "initrd.target" +} diff --git a/tests/kola/firewall/iptables-legacy/config.bu b/tests/kola/firewall/iptables-legacy/config.bu new file mode 100644 index 0000000000..c7092c4022 --- /dev/null +++ b/tests/kola/firewall/iptables-legacy/config.bu @@ -0,0 +1,28 @@ +variant: fcos +version: 1.4.0 +storage: + links: + - path: /etc/alternatives/iptables + target: /usr/sbin/iptables-legacy + overwrite: true + hard: false + - path: /etc/alternatives/iptables-restore + target: /usr/sbin/iptables-legacy-restore + overwrite: true + hard: false + - path: /etc/alternatives/iptables-save + target: /usr/sbin/iptables-legacy-save + overwrite: true + hard: false + - path: /etc/alternatives/ip6tables + target: /usr/sbin/ip6tables-legacy + overwrite: true + hard: false + - path: /etc/alternatives/ip6tables-restore + target: /usr/sbin/ip6tables-legacy-restore + overwrite: true + hard: false + - path: /etc/alternatives/ip6tables-save + target: /usr/sbin/ip6tables-legacy-save + overwrite: true + hard: false diff --git a/tests/kola/firewall/iptables-legacy b/tests/kola/firewall/iptables-legacy/test.sh similarity index 69% rename from tests/kola/firewall/iptables-legacy rename to tests/kola/firewall/iptables-legacy/test.sh index 9e45b15c89..e210116731 100755 --- a/tests/kola/firewall/iptables-legacy +++ b/tests/kola/firewall/iptables-legacy/test.sh @@ -3,7 +3,7 @@ # is using the `nf_tables` backend. # TODO: modify this test to check for `nf_tables` backend when FCOS switches. # See https://github.com/coreos/fedora-coreos-config/pull/1324 -# kola: { "distros": "fcos", "exclusive": false } +# kola: { "distros": "fcos", "exclusive": true } set -xeuo pipefail ok() { @@ -15,10 +15,9 @@ fatal() { exit 1 } -# Make sure we're still on legacy iptables for now -# https://github.com/coreos/fedora-coreos-tracker/issues/676#issuecomment-928028451 +# Make sure we're on legacy iptables if ! iptables --version | grep legacy; then iptables --version # output for logs fatal "iptables version is not legacy" fi -ok "iptables still in legacy mode" +ok "iptables in legacy mode" diff --git a/tests/kola/firewall/iptables-nft/test.sh b/tests/kola/firewall/iptables-nft/test.sh new file mode 100755 index 0000000000..89f75fcfb7 --- /dev/null +++ b/tests/kola/firewall/iptables-nft/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# kola: { "exclusive": false } +set -xeuo pipefail + +ok() { + echo "ok" "$@" +} + +fatal() { + echo "$@" >&2 + exit 1 +} + +if ! iptables --version | grep nf_tables; then + iptables --version # output for logs + fatal "iptables version is not nft" +fi +ok "iptables in nft mode"