Files
fnos-iptables-forward/install.sh
T
2026-06-02 23:10:58 +08:00

149 lines
4.3 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -Eeuo pipefail
SERVICE_NAME="${SERVICE_NAME:-iptables-forward}"
SCRIPT_DIR="${SCRIPT_DIR:-/home/scripts}"
RULE_SCRIPT="${RULE_SCRIPT:-$SCRIPT_DIR/iptables-forward.sh}"
SERVICE_FILE="${SERVICE_FILE:-/etc/systemd/system/${SERVICE_NAME}.service}"
TIMER_FILE="${TIMER_FILE:-/etc/systemd/system/${SERVICE_NAME}.timer}"
DELAY="${DELAY:-20s}"
LAN_A="${LAN_A:-192.168.2.0/24}"
LAN_B="${LAN_B:-192.168.3.0/24}"
VIRTUAL_LAN="${VIRTUAL_LAN:-192.168.4.0/24}"
TUN_IF="${TUN_IF:-tun0}"
MODE="${1:-install}"
info() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33mWARN:\033[0m %s\n' "$*" >&2; }
fail() { printf '\033[1;31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }
need_root() { [ "$(id -u)" -eq 0 ] || fail "请用 root 运行:sudo bash install.sh ${MODE}"; }
need_cmd() { command -v "$1" >/dev/null 2>&1 || fail "缺少命令:$1"; }
write_rule_script() {
mkdir -p "$SCRIPT_DIR"
cat > "$RULE_SCRIPT" <<EOF
#!/usr/bin/env bash
set -Eeuo pipefail
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F FORWARD
iptables -P FORWARD ACCEPT
# 放行 ${LAN_B} <-> ${LAN_A}
iptables -A FORWARD -s ${LAN_A} -d ${LAN_B} -j ACCEPT
iptables -A FORWARD -s ${LAN_B} -d ${LAN_A} -j ACCEPT
# 放行 ${LAN_B}/${LAN_A} -> ${VIRTUAL_LAN}(虚拟组网)
iptables -A FORWARD -s ${LAN_B} -d ${VIRTUAL_LAN} -j ACCEPT
iptables -A FORWARD -s ${LAN_A} -d ${VIRTUAL_LAN} -j ACCEPT
# 放行 ${VIRTUAL_LAN} -> ${LAN_B}/${LAN_A} 的回包(必须)
iptables -A FORWARD -s ${VIRTUAL_LAN} -d ${LAN_B} -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s ${VIRTUAL_LAN} -d ${LAN_A} -m state --state RELATED,ESTABLISHED -j ACCEPT
# 禁止 ${VIRTUAL_LAN} 主动访问 ${LAN_B}/${LAN_A}(安全隔离)
iptables -A FORWARD -s ${VIRTUAL_LAN} -d ${LAN_B} -j DROP
iptables -A FORWARD -s ${VIRTUAL_LAN} -d ${LAN_A} -j DROP
# 放行 EasyTier 虚拟网卡 ${TUN_IF}
iptables -A FORWARD -i ${TUN_IF} -j ACCEPT
iptables -A FORWARD -o ${TUN_IF} -j ACCEPT
EOF
chmod 0755 "$RULE_SCRIPT"
}
write_systemd_units() {
cat > "$SERVICE_FILE" <<EOF
[Unit]
Description=EasyTier iptables forward rules loader
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=${RULE_SCRIPT}
User=root
EOF
cat > "$TIMER_FILE" <<EOF
[Unit]
Description=Delay load EasyTier iptables forward rules after boot
[Timer]
OnBootSec=${DELAY}
Unit=${SERVICE_NAME}.service
[Install]
WantedBy=timers.target
EOF
}
install_all() {
need_root
need_cmd systemctl
need_cmd iptables
info "写入转发规则脚本:$RULE_SCRIPT"
write_rule_script
info "写入 systemd service/timer"
write_systemd_units
info "加载并启用 timer(只启用 timer,不直接 enable service"
systemctl daemon-reload
systemctl enable --now "${SERVICE_NAME}.timer"
info "立即执行一次规则加载,避免等到下次开机才生效"
systemctl start "${SERVICE_NAME}.service"
info "安装完成"
status_all
}
uninstall_all() {
need_root
need_cmd systemctl
info "停止并禁用 timer/service"
systemctl disable --now "${SERVICE_NAME}.timer" 2>/dev/null || true
systemctl stop "${SERVICE_NAME}.service" 2>/dev/null || true
rm -f "$SERVICE_FILE" "$TIMER_FILE" "$RULE_SCRIPT"
systemctl daemon-reload
info "已移除 systemd 单元和规则脚本;现有 iptables 规则不会自动清空,如需清空请手动执行 iptables 管理命令。"
}
status_all() {
need_root
printf '\n# systemd timer\n'
systemctl --no-pager --full status "${SERVICE_NAME}.timer" || true
printf '\n# systemd service\n'
systemctl --no-pager --full status "${SERVICE_NAME}.service" || true
printf '\n# ip_forward\n'
cat /proc/sys/net/ipv4/ip_forward || true
printf '\n# iptables FORWARD\n'
iptables -S FORWARD || true
}
case "$MODE" in
install) install_all ;;
uninstall|remove) uninstall_all ;;
status) status_all ;;
*)
cat <<USAGE
Usage: sudo bash install.sh [install|status|uninstall]
Environment overrides:
LAN_A=$LAN_A
LAN_B=$LAN_B
VIRTUAL_LAN=$VIRTUAL_LAN
TUN_IF=$TUN_IF
DELAY=$DELAY
SERVICE_NAME=$SERVICE_NAME
SCRIPT_DIR=$SCRIPT_DIR
Examples:
sudo bash install.sh install
sudo LAN_A=192.168.2.0/24 LAN_B=192.168.3.0/24 VIRTUAL_LAN=192.168.4.0/24 TUN_IF=tun0 bash install.sh install
sudo DELAY=30s bash install.sh install
sudo bash install.sh status
sudo bash install.sh uninstall
USAGE
exit 2
;;
esac