#!/bin/bash # Copyright Broadcom, Inc. All Rights Reserved. # SPDX-License-Identifier: APACHE-2.0 # Copyright 2020 The Kubernetes Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # This is a variant of the original Kubernetes iptables-wrapper below: # https://github.com/kubernetes-sigs/iptables-wrappers/blob/v2/iptables-wrapper-installer.sh # Adapted to use bash interpreter and make it compatible with read-only # root filesystems. # shellcheck disable=SC2126 set -o errexit set -o nounset # In kubernetes 1.17 and later, kubelet will have created at least # one chain in the "mangle" table (either "KUBE-IPTABLES-HINT" or # "KUBE-KUBELET-CANARY"), so check that first, against # iptables-nft, because we can check that more efficiently and # it's more common these days. nft_kubelet_rules=$( (iptables-nft-save -t mangle || true; ip6tables-nft-save -t mangle || true) 2>/dev/null | grep -E '^:(KUBE-IPTABLES-HINT|KUBE-KUBELET-CANARY)' | wc -l) if [ "${nft_kubelet_rules}" -ne 0 ]; then mode=nft else # Check for kubernetes 1.17-or-later with iptables-legacy. We # can't pass "-t mangle" to iptables-legacy-save because it would # cause the kernel to create that table if it didn't already # exist, which we don't want. So we have to grab all the rules legacy_kubelet_rules=$( (iptables-legacy-save || true; ip6tables-legacy-save || true) 2>/dev/null | grep -E '^:(KUBE-IPTABLES-HINT|KUBE-KUBELET-CANARY)' | wc -l) if [ "${legacy_kubelet_rules}" -ne 0 ]; then mode=legacy else # With older kubernetes releases there may not be any _specific_ # rules we can look for, but we assume that some non-containerized process # (possibly kubelet) will have created _some_ iptables rules. num_legacy_lines=$( (iptables-legacy-save || true; ip6tables-legacy-save || true) 2>/dev/null | grep '^-' | wc -l) num_nft_lines=$( (iptables-nft-save || true; ip6tables-nft-save || true) 2>/dev/null | grep '^-' | wc -l) if [ "${num_legacy_lines}" -gt "${num_nft_lines}" ]; then mode=legacy else mode=nft fi fi fi original_command="$(basename "$0")" # Update links to point to the selected binaries if [ -x /usr/sbin/alternatives ]; then # Fedora/SUSE style alternatives alternatives --set iptables "/usr/sbin/iptables-${mode}" > /dev/null || failed=1 if [ "${failed:-0}" = 1 ]; then # Try the multi-binary if alternatives failed exec "/usr/sbin/xtables-${mode}-multi" "$original_command" "$@" fi elif [ -x /usr/sbin/update-alternatives ] || [ -x /usr/bin/update-alternatives ]; then # Debian style alternatives update-alternatives --set iptables "/usr/sbin/iptables-${mode}" > /dev/null || failed=1 update-alternatives --set ip6tables "/usr/sbin/ip6tables-${mode}" > /dev/null || failed=1 if [ "${failed:-0}" = 1 ]; then # Try the multi-binary if update-alternatives failed exec "/usr/sbin/xtables-${mode}-multi" "$original_command" "$@" fi else # Try the multi-binary exec "/usr/sbin/xtables-${mode}-multi" "$original_command" "$@" fi # Now re-exec the original command with the newly-selected alternative exec "$original_command" "$@"