#!/usr/bin/env bash set -euo pipefail TRUSTED_ZONE="trusted" IFACES=("flannel.1" "cni0") WAIT_SECONDS_DEFAULT=30 WAIT_SECONDS="${WAIT_SECONDS_DEFAULT}" NON_INTERACTIVE="0" usage() { cat <<'EOF' 用法: setup-k3s-firewalld-interfaces.sh [选项] 选项: --wait-seconds 等待接口出现的秒数(默认 30) --non-interactive 非交互模式 -h, --help 显示帮助 EOF } while [[ $# -gt 0 ]]; do case "$1" in --wait-seconds) WAIT_SECONDS="${2:-30}"; shift 2 ;; --non-interactive) NON_INTERACTIVE="1"; shift ;; -h|--help) usage; exit 0 ;; *) echo "[ERR] 未知参数: $1"; usage; exit 1 ;; esac done require_cmd() { local c="$1" if ! command -v "$c" >/dev/null 2>&1; then echo "[ERR] 缺少命令: $c" exit 1 fi } require_cmd firewall-cmd require_cmd ip if [[ $EUID -ne 0 ]]; then SUDO="sudo" else SUDO="" fi echo "=== K3s firewalld 接口基线配置 ===" echo "目标 zone: ${TRUSTED_ZONE}" echo "目标接口: ${IFACES[*]}" echo "等待接口出现: ${WAIT_SECONDS}s" if [[ "${NON_INTERACTIVE}" == "0" ]]; then read -r -p "继续执行?[Y/n]: " ans ans="${ans:-Y}" if [[ ! "${ans}" =~ ^[Yy]$ ]]; then echo "已取消。" exit 0 fi fi deadline=$((SECONDS + WAIT_SECONDS)) for iface in "${IFACES[@]}"; do while ! ip link show "${iface}" >/dev/null 2>&1; do if (( SECONDS >= deadline )); then echo "[ERR] 接口未出现: ${iface}(等待 ${WAIT_SECONDS}s 仍未出现)" echo "请确认 k3s 已启动并生成 CNI 接口后重试。" exit 1 fi sleep 1 done done for iface in "${IFACES[@]}"; do echo "[RUN ] runtime add-interface ${iface} -> ${TRUSTED_ZONE}" ${SUDO} firewall-cmd --zone="${TRUSTED_ZONE}" --add-interface="${iface}" >/dev/null echo "[RUN ] permanent add-interface ${iface} -> ${TRUSTED_ZONE}" ${SUDO} firewall-cmd --permanent --zone="${TRUSTED_ZONE}" --add-interface="${iface}" >/dev/null done echo "[RUN ] firewall-cmd --reload" ${SUDO} firewall-cmd --reload >/dev/null echo echo "=== 验证输出 ===" ${SUDO} firewall-cmd --zone="${TRUSTED_ZONE}" --list-interfaces ${SUDO} firewall-cmd --get-active-zones echo echo "[OK] 已完成 firewalld 接口基线配置。"