diff --git a/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service b/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service new file mode 100644 index 0000000000..a59bc10531 --- /dev/null +++ b/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.service @@ -0,0 +1,18 @@ +[Unit] +Description=CoreOS Enable iptables-legacy +ConditionPathExists=/etc/initrd-release +DefaultDependencies=false +ConditionPathExists=/sysroot/etc/coreos/iptables-legacy.stamp + +# 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/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh b/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh new file mode 100755 index 0000000000..4f364510bf --- /dev/null +++ b/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/coreos-enable-iptables-legacy.sh @@ -0,0 +1,82 @@ +#!/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 +) + +STAMP=/sysroot/etc/coreos/iptables-legacy.stamp +IGNITION_RESULT=/sysroot/etc/.ignition-result.json + +# sanity-check the stamp file is present +if [ ! -e "${STAMP}" ]; then + echo "File ${STAMP} not found; exiting." + exit 0 +fi + +# We only want to run once. +rm "${STAMP}" + +# Ignore firstboot. We don't want the stamp file to be a long-term +# provisioning-time API for moving to iptables-legacy, so explicitly check for +# this and don't support it. We use the Ignition report file because it's less +# hacky than parsing the kernel commandline for `ignition.firstboot`. +if [ -e "${IGNITION_RESULT}" ]; then + ignition_boot=$(jq -r .provisioningBootID "${IGNITION_RESULT}") + if [ "$(cat /proc/sys/kernel/random/boot_id)" = "${ignition_boot}" ]; then + echo "First boot detected; exiting." + exit 0 + fi +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 symlinkpath=$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/$symlinkpath" ] || [ ! -L "/sysroot/usr/$symlinkpath" ]; then + return 1 + fi + # compare symlink targets between deployment and OSTree default + if [ "$(readlink "/sysroot/$symlinkpath")" != "$(readlink "/sysroot/usr/$symlinkpath")" ]; then + return 1 + fi + # it's the default + return 0 +} + +# 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 + symlinkpath=/etc/alternatives/$symlink + if ! symlink_is_default "$symlinkpath"; then + echo "Symlink $symlinkpath 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 + +echo "Updated /sysroot to use iptables-legacy." diff --git a/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh b/overlay.d/35coreos-iptables/usr/lib/dracut/modules.d/35coreos-iptables/module-setup.sh new file mode 100644 index 0000000000..677f3f6188 --- /dev/null +++ b/overlay.d/35coreos-iptables/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/overlay.d/README.md b/overlay.d/README.md index 4213f2c0b2..61a989718a 100644 --- a/overlay.d/README.md +++ b/overlay.d/README.md @@ -46,3 +46,16 @@ Add static chrony configuration for NTP servers provided on platforms such as `azure`, `aws`, `gcp`. The chrony config for these NTP servers should override other chrony configuration (e.g. DHCP-provided) configuration. + +35coreos-iptables +----------------- + +Contains systemd service and script for remaining on iptables-nft after +the migration to nft. + +Split out because (1) it will roll out to next first, and (2) it can +more easily be deleted after the barrier release. + +For more details, see: +https://github.com/coreos/fedora-coreos-tracker/issues/676 +https://github.com/coreos/fedora-coreos-config/pull/1324