Implement iptables forward manager core

This commit is contained in:
2026-04-17 09:36:40 +08:00
parent d1a5392476
commit 28960eee03
20 changed files with 2047 additions and 0 deletions

129
tests/test_env_check.sh Normal file
View File

@@ -0,0 +1,129 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
# shellcheck source=tests/lib/assert.sh
source "${ROOT_DIR}/tests/lib/assert.sh"
status_of() {
set +e
"$@" >/dev/null 2>&1
local rc=$?
set -e
printf '%s\n' "${rc}"
}
TMP_DIR=$(mktemp -d)
trap 'rm -rf "${TMP_DIR}"' EXIT
BIN_DIR="${TMP_DIR}/bin"
mkdir -p "${BIN_DIR}"
IPTABLES_PATH="${BIN_DIR}/iptables"
IP6TABLES_PATH="${BIN_DIR}/ip6tables"
PERSIST_PATH="${BIN_DIR}/netfilter-persistent"
DPKG_PATH="${BIN_DIR}/dpkg"
SYSCTL_PATH="${BIN_DIR}/sysctl"
SYSTEMCTL_PATH="${BIN_DIR}/systemctl"
DEBCONF_PATH="${BIN_DIR}/debconf-set-selections"
APT_PATH="${BIN_DIR}/apt-get"
cat >"${DPKG_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 1
MOCK
cat >"${SYSCTL_PATH}" <<MOCK
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "\$*" >>"${TMP_DIR}/sysctl.log"
printf '1\n' >"${TMP_DIR}/ipv4_forward"
printf '1\n' >"${TMP_DIR}/ipv6_forward"
MOCK
cat >"${SYSTEMCTL_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 1
MOCK
cat >"${DEBCONF_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
cat >/dev/null
MOCK
cat >"${APT_PATH}" <<MOCK
#!/usr/bin/env bash
set -euo pipefail
printf '%s\n' "\$*" >>"${TMP_DIR}/apt.log"
MOCK
chmod +x "${DPKG_PATH}" "${SYSCTL_PATH}" "${SYSTEMCTL_PATH}" "${DEBCONF_PATH}" "${APT_PATH}"
export IPF_STORAGE_DIR="${TMP_DIR}/storage"
export IPF_SYSCTL_FILE="${TMP_DIR}/99-iptables-forward.conf"
export IPF_IPV4_FORWARD_FILE="${TMP_DIR}/ipv4_forward"
export IPF_IPV6_FORWARD_FILE="${TMP_DIR}/ipv6_forward"
export IPF_CHECK_IPTABLES_CMD="${BIN_DIR}/missing-iptables"
export IPF_CHECK_IP6TABLES_CMD="${BIN_DIR}/missing-ip6tables"
export IPF_CHECK_PERSIST_CMD="${BIN_DIR}/missing-persist"
export DPKG_BIN="${DPKG_PATH}"
export SYSCTL_BIN="${SYSCTL_PATH}"
export SYSTEMCTL_BIN="${SYSTEMCTL_PATH}"
export DEBCONF_SET_SELECTIONS_BIN="${DEBCONF_PATH}"
export APT_GET_BIN="${APT_PATH}"
echo 0 >"${IPF_IPV4_FORWARD_FILE}"
echo 0 >"${IPF_IPV6_FORWARD_FILE}"
# shellcheck source=lib/common.sh
source "${ROOT_DIR}/lib/common.sh"
# shellcheck source=lib/env_check.sh
source "${ROOT_DIR}/lib/env_check.sh"
env_check_collect_issues
assert_eq '6' "${#ENV_CHECK_ISSUES[@]}" 'env_check_collect_issues should capture missing binaries, persistence, forwarding and storage'
cat >"${IPTABLES_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 0
MOCK
cat >"${IP6TABLES_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 0
MOCK
cat >"${PERSIST_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 0
MOCK
cat >"${DPKG_PATH}" <<'MOCK'
#!/usr/bin/env bash
set -euo pipefail
exit 0
MOCK
chmod +x "${IPTABLES_PATH}" "${IP6TABLES_PATH}" "${PERSIST_PATH}" "${DPKG_PATH}"
mkdir -p "${IPF_STORAGE_DIR}"
export IPF_CHECK_IPTABLES_CMD="${IPTABLES_PATH}"
export IPF_CHECK_IP6TABLES_CMD="${IP6TABLES_PATH}"
export IPF_CHECK_PERSIST_CMD="${PERSIST_PATH}"
export IPF_ASSUME_YES=1
env_check_all
assert_file_contains "${IPF_SYSCTL_FILE}" 'net.ipv4.ip_forward=1' 'env_check_all should write IPv4 forwarding setting'
assert_file_contains "${IPF_SYSCTL_FILE}" 'net.ipv6.conf.all.forwarding=1' 'env_check_all should write IPv6 forwarding setting'
assert_file_contains "${TMP_DIR}/sysctl.log" '--system' 'env_check_all should apply sysctl settings'
export IPF_CHECK_IPTABLES_CMD="${BIN_DIR}/missing-iptables-again"
export IPF_CHECK_IP6TABLES_CMD="${BIN_DIR}/missing-ip6tables-again"
export IPF_CHECK_PERSIST_CMD="${BIN_DIR}/missing-persist-again"
export IPF_ASSUME_YES=0
export IPF_TEST_INPUTS=$'n\n'
assert_eq '3' "$(status_of env_check_all)" 'env_check_all should return 3 when user rejects autofix'
pass 'test_env_check.sh'