跳转到帖子
在手机APP中查看

一个更好的浏览方法。了解更多

PHP论坛人

主屏幕上的全屏APP,带有推送通知、徽章等。

在iOS和iPadOS上安装此APP
  1. 在Safari中轻敲分享图标
  2. 滚动菜单并轻敲添加到主屏幕
  3. 轻敲右上角的添加按钮。
在安卓上安装此APP
  1. 轻敲浏览器右上角的三个点菜单 (⋮) 。
  2. 轻敲添加到主屏幕安装APP
  3. 轻敲安装进行确认。

這裡提供一個iptables防火牆規則 firewall.sh (IPv4 + IPv6 規則)

精选回复

#!/bin/bash
# =============================================================================
# 防火牆腳本 - Debian 13 / iptables-nft + ip6tables-nft
# 存放路徑:/usr/local/bin/firewall.sh
# 權限設定:chmod 700 /usr/local/bin/firewall.sh
# 整合 systemd 開機啟動
#
# 版本: 3.2 (正式版)
# 功能說明:
# - 支援 start (永久生效) / stop (清除規則) / test (測試模式) 參數
# - 同時設定 IPv4 (iptables) 與 IPv6 (ip6tables) 規則
# - 測試模式 30 秒後自動清除規則(避免鎖死)
# - 包含核心參數調校(抗攻擊、防 IP Spoofing)
# - 支援來源 IP 限制、連續埠、反向排除
# - 包含 Rate Limiting、Fragment 阻擋、ICMP/ICMPv6 防護
# - 優化日誌記錄避免過多訊息
# =============================================================================

# ========================== 使用者設定區塊 ========================== #
# 警告:修改前請務必閱讀註解,確認管理 IP 已正確設定(含 IPv6)

# 1. 禁止連線的 IP 或網段(支援 IPv4 與 IPv6)
# 範例:BADIPS="198.108.0.0/16 203.0.113.0/24 2001:db8::/32"
BADIPS=""


# 2. 不可能出現的私有 IP(RFC 1918 / 私有 IPv6)
# ⚠️ 注意:若您的伺服器本身 IP 屬於以下網段,請務必移除對應項目!
# 10.0.0.0/8 → 大型企業內網(AWS、Hetzner 等雲端內網請注意)
# 172.16.0.0/12 → 中型企業內網(Docker 預設網段也在這範圍)
# 192.168.0.0/16→ 小型辦公室/家庭網路
# fc00::/7 → IPv6 唯一本地位址(等同 IPv4 私有網段)
IMPOSSIBLE_IPS="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 fc00::/7"


# 3. 允許對內連線的 TCP 通訊埠(支援來源 IP 限制與反向排除)
# 格式說明:
# - 單一埠:22
# - 連續埠:7000:7009
# - 指定來源 IPv4:22,192.168.1.100
# - 指定來源 IPv6:22,2001:db8::1
# - 反向排除(禁止特定 IP):22,!192.168.1.100
#
# 重要:請將以下 IP 換成您當前連線的管理 IP!
IN_TCP_PORTALLOWED="22,你的管理員IPv4 22,你的管理員IPv6 80 443"



# 4. 允許對內連線的 UDP 通訊埠(格式同上)
IN_UDP_PORTALLOWED=""



# 5. 允許對內連線的 ICMP 類型(IPv4)
# 常用類型:0 (echo reply)、3 (destination unreachable)、
# 8 (echo request/ping)、11 (time exceeded/traceroute)
IN_ICMP_ALLOWED="0 3 8 11"



# 6. 允許對內連線的 ICMPv6 類型(IPv6 必要,請勿隨意刪減)
# ICMPv6 是 IPv6 正常運作的基礎,封鎖會導致連線異常
# 1: Destination Unreachable
# 2: Packet Too Big(Path MTU Discovery 必要)
# 3: Time Exceeded(traceroute6 使用)
# 4: Parameter Problem
# 128: Echo Request(ping6)
# 129: Echo Reply
# 133: Router Solicitation(NDP:取得路由器資訊)
# 134: Router Advertisement(NDP:路由器廣播)
# 135: Neighbor Solicitation(NDP:等同 ARP Request)
# 136: Neighbor Advertisement(NDP:等同 ARP Reply)
# 137: Redirect
# 141: Inverse Neighbor Discovery Solicitation
# 142: Inverse Neighbor Discovery Advertisement
IN_ICMPV6_ALLOWED="1 2 3 4 128 129 133 134 135 136 137 141 142"



# 7. Rate Limiting 設定
ENABLE_RATE_LIMIT="yes" # 是否啟用 rate limiting
SSH_RATE="10/60" # SSH: 60秒內10次
WEB_RATE="100/60" # Web: 60秒內100次
ICMP_RATE="5" # ICMP ping 每秒次數



# 8. 備份目錄設定
# 腳本備份目錄
BACKUP_DIR="/root/firewall-backups"



# ========================== 系統函式區塊 ========================== #
# 以下為程式邏輯,若不熟悉 shell script,請勿任意修改

set -e
trap 'echo "錯誤: 指令失敗於行號: $LINENO"; exit 1' ERR

IPTABLES="/usr/sbin/iptables"
IP6TABLES="/usr/sbin/ip6tables"
SYSCTL="/usr/sbin/sysctl"

# 建立備份目錄
mkdir -p "$BACKUP_DIR"
cp "$0" "$BACKUP_DIR/firewall.sh.$(date +%Y%m%d_%H%M%S)" 2>/dev/null || true

# 檢查必要指令
for cmd in $IPTABLES $IP6TABLES $SYSCTL; do
if ! command -v $cmd >/dev/null 2>&1; then
echo "錯誤: 找不到 $cmd 指令"
exit 1
fi
done

# 檢查 conntrack 模組
if ! $IPTABLES -m conntrack --help >/dev/null 2>&1; then
echo "錯誤: conntrack 模組不可用"
echo "請執行: modprobe nf_conntrack"
exit 1
fi

# -----------------------------------------------------------------------------
# 輔助函式:判斷 IP 版本
# -----------------------------------------------------------------------------
is_ipv6() { echo "$1" | grep -q ':'; }
is_ipv4() { echo "$1" | grep -q '\.' && ! echo "$1" | grep -q ':'; }

# -----------------------------------------------------------------------------
# 停止功能:清除所有規則
# -----------------------------------------------------------------------------
do_stop() {
echo -n "Stopping firewall (flushing all rules)..."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -t filter -F
$IPTABLES -t filter -X

$IP6TABLES -P INPUT ACCEPT
$IP6TABLES -P OUTPUT ACCEPT
$IP6TABLES -P FORWARD ACCEPT
$IP6TABLES -t filter -F
$IP6TABLES -t filter -X
echo " OK"
echo " 警告:所有防火牆規則已清除,伺服器目前無任何防護!"
}

if [ "$1" = "stop" ]; then
do_stop
exit 0
fi

# -----------------------------------------------------------------------------
# 初始化
# -----------------------------------------------------------------------------
echo -n "Initializing iptables/ip6tables..."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -t filter -F
$IPTABLES -t filter -X

$IP6TABLES -P INPUT ACCEPT
$IP6TABLES -P FORWARD ACCEPT
$IP6TABLES -P OUTPUT ACCEPT
$IP6TABLES -t filter -F
$IP6TABLES -t filter -X
echo " OK"

# 判斷模式
MODE="test"
[ "$1" = "start" ] && MODE="start"

# -----------------------------------------------------------------------------
# 核心參數調校
# -----------------------------------------------------------------------------
echo -n "Tuning kernel parameters..."

# SYN Flood 防護
$SYSCTL -w net.ipv4.tcp_syncookies=1 > /dev/null 2>&1

# ICMP 攻擊防護
$SYSCTL -w net.ipv4.icmp_echo_ignore_broadcasts=1 > /dev/null 2>&1
$SYSCTL -w net.ipv4.icmp_ignore_bogus_error_responses=1 > /dev/null 2>&1

# 關閉 ICMP Redirect(防中間人攻擊)
$SYSCTL -w net.ipv4.conf.all.accept_redirects=0 > /dev/null 2>&1
$SYSCTL -w net.ipv4.conf.default.accept_redirects=0 > /dev/null 2>&1
$SYSCTL -w net.ipv4.conf.all.send_redirects=0 > /dev/null 2>&1
$SYSCTL -w net.ipv4.conf.default.send_redirects=0 > /dev/null 2>&1

# 關閉 Source Routing
$SYSCTL -w net.ipv4.conf.all.accept_source_route=0 > /dev/null 2>&1
$SYSCTL -w net.ipv4.conf.default.accept_source_route=0 > /dev/null 2>&1

# 反向路徑過濾(單網卡設1,多網卡或VPN請改2)
$SYSCTL -w net.ipv4.conf.all.rp_filter=1 > /dev/null 2>&1
$SYSCTL -w net.ipv4.conf.default.rp_filter=1 > /dev/null 2>&1

# 記錄可疑封包(IP Spoofing)
$SYSCTL -w net.ipv4.conf.all.log_martians=1 > /dev/null 2>&1

# IPv6 防護
$SYSCTL -w net.ipv6.conf.all.accept_redirects=0 > /dev/null 2>&1
$SYSCTL -w net.ipv6.conf.default.accept_redirects=0 > /dev/null 2>&1
$SYSCTL -w net.ipv6.conf.all.accept_source_route=0 > /dev/null 2>&1
$SYSCTL -w net.ipv6.conf.default.accept_source_route=0 > /dev/null 2>&1

echo " OK"

# -----------------------------------------------------------------------------
# 通用解析函式(支援 IP 限制、反向排除)
# -----------------------------------------------------------------------------
parse_entry() {
local entry="$1"
local proto="$2"
local family="$3"
local cmd src_ip port src

[ "$family" = "ipv4" ] && cmd="$IPTABLES" || cmd="$IP6TABLES"

case "$entry" in
*,*)
port=$(echo "$entry" | cut -d, -f1)
src=$(echo "$entry" | cut -d, -f2-)

if echo "$src" | grep -q '^!'; then
src_ip=$(echo "$src" | sed 's/^!//')
# 版本過濾
if { [ "$family" = "ipv4" ] && is_ipv6 "$src_ip"; } || \
{ [ "$family" = "ipv6" ] && is_ipv4 "$src_ip"; }; then
return
fi

# 反向排除:先 DROP 該來源
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW -s "$src_ip" -j DROP
# 再 ACCEPT 其他
if [ "$proto" = "tcp" ] && [ "$port" = "22" ] && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
if [ "$family" = "ipv6" ]; then
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW ! -s "$src_ip" -j SSH_ACCEPT6
else
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW ! -s "$src_ip" -j SSH_ACCEPT
fi
elif [ "$proto" = "tcp" ] && { [ "$port" = "80" ] || [ "$port" = "443" ]; } && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
if [ "$family" = "ipv6" ]; then
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW ! -s "$src_ip" -j WEB_ACCEPT6
else
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW ! -s "$src_ip" -j WEB_ACCEPT
fi
else
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW ! -s "$src_ip" -j ACCEPT
fi
else
# 版本過濾
if { [ "$family" = "ipv4" ] && is_ipv6 "$src"; } || \
{ [ "$family" = "ipv6" ] && is_ipv4 "$src"; }; then
return
fi
# 指定來源
if [ "$proto" = "tcp" ] && [ "$port" = "22" ] && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW -s "$src" -j SSH_ACCEPT
elif [ "$proto" = "tcp" ] && { [ "$port" = "80" ] || [ "$port" = "443" ]; } && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW -s "$src" -j WEB_ACCEPT
else
$cmd -A INPUT -p "$proto" --dport "$port" -m conntrack --ctstate NEW -s "$src" -j ACCEPT
fi
fi
;;
*)
# 純埠
if [ "$proto" = "tcp" ] && [ "$entry" = "22" ] && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
if [ "$family" = "ipv6" ]; then
$cmd -A INPUT -p "$proto" --dport "$entry" -m conntrack --ctstate NEW -j SSH_ACCEPT6
else
$cmd -A INPUT -p "$proto" --dport "$entry" -m conntrack --ctstate NEW -j SSH_ACCEPT
fi
elif [ "$proto" = "tcp" ] && { [ "$entry" = "80" ] || [ "$entry" = "443" ]; } && [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
if [ "$family" = "ipv6" ]; then
$cmd -A INPUT -p "$proto" --dport "$entry" -m conntrack --ctstate NEW -j WEB_ACCEPT6
else
$cmd -A INPUT -p "$proto" --dport "$entry" -m conntrack --ctstate NEW -j WEB_ACCEPT
fi
else
$cmd -A INPUT -p "$proto" --dport "$entry" -m conntrack --ctstate NEW -j ACCEPT
fi
;;
esac
}

# ========================== IPv4 規則 ========================== #
echo -n "Applying IPv4 firewall rules..."

$IPTABLES -P INPUT DROP
$IPTABLES -P FORWARD DROP
$IPTABLES -P OUTPUT ACCEPT

# Loopback
$IPTABLES -A INPUT -i lo -j ACCEPT

# 建立 BADPKT 鏈
$IPTABLES -N BADPKT
$IPTABLES -A BADPKT -m limit --limit 1/min --limit-burst 3 -j LOG --log-prefix "IPv4_BADPKT: " --log-level 4
$IPTABLES -A BADPKT -j DROP

# Rate limiting 鏈
if [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
$IPTABLES -N SSH_ACCEPT
$IPTABLES -N WEB_ACCEPT

SSH_HITCOUNT=$(echo $SSH_RATE | cut -d/ -f1)
SSH_SECONDS=$(echo $SSH_RATE | cut -d/ -f2)
$IPTABLES -A SSH_ACCEPT -m recent --name SSH4 --set
$IPTABLES -A SSH_ACCEPT -m recent --name SSH4 --update --seconds $SSH_SECONDS --hitcount $SSH_HITCOUNT -j LOG --log-prefix "SSH4_RATE_DROP: " --log-level 4
$IPTABLES -A SSH_ACCEPT -m recent --name SSH4 --update --seconds $SSH_SECONDS --hitcount $SSH_HITCOUNT -j DROP
$IPTABLES -A SSH_ACCEPT -j ACCEPT

WEB_HITCOUNT=$(echo $WEB_RATE | cut -d/ -f1)
WEB_SECONDS=$(echo $WEB_RATE | cut -d/ -f2)
$IPTABLES -A WEB_ACCEPT -m recent --name WEB4 --set
$IPTABLES -A WEB_ACCEPT -m recent --name WEB4 --update --seconds $WEB_SECONDS --hitcount $WEB_HITCOUNT -j LOG --log-prefix "WEB4_RATE_DROP: " --log-level 4
$IPTABLES -A WEB_ACCEPT -m recent --name WEB4 --update --seconds $WEB_SECONDS --hitcount $WEB_HITCOUNT -j DROP
$IPTABLES -A WEB_ACCEPT -j ACCEPT
fi

# 允許已建立連線(插到第一條)
$IPTABLES -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 阻擋 INVALID
$IPTABLES -A INPUT -m conntrack --ctstate INVALID -j BADPKT

# 阻擋非 SYN 的新連線
$IPTABLES -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j BADPKT

# 阻擋異常 TCP Flag
for flags in \
"ALL NONE" \
"SYN,FIN SYN,FIN" \
"SYN,RST SYN,RST" \
"FIN,RST FIN,RST" \
"ACK,FIN FIN" \
"ACK,URG URG" \
"ACK,PSH PSH" \
"ALL FIN,URG,PSH" \
"ALL SYN,RST,ACK,FIN,URG" \
"ALL ALL" \
"ALL FIN"
do
$IPTABLES -A INPUT -p tcp --tcp-flags $flags -j BADPKT
done

# 阻擋黑名單與私有 IP
for ip in $BADIPS $IMPOSSIBLE_IPS; do
if is_ipv4 "$ip"; then
$IPTABLES -A INPUT -s "$ip" -j DROP
fi
done

# 允許 TCP 埠
for entry in $IN_TCP_PORTALLOWED; do
parse_entry "$entry" tcp ipv4
done

# 允許 UDP 埠
for entry in $IN_UDP_PORTALLOWED; do
parse_entry "$entry" udp ipv4
done

# 允許 ICMP(含 rate limiting)
if [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
$IPTABLES -A INPUT -p icmp --icmp-type 8 -m limit --limit $ICMP_RATE/sec --limit-burst 5 -j ACCEPT
$IPTABLES -A INPUT -p icmp --icmp-type 8 -j LOG --log-prefix "ICMP_RATE_DROP: " --log-level 4
$IPTABLES -A INPUT -p icmp --icmp-type 8 -j DROP
fi

for type in $IN_ICMP_ALLOWED; do
if [ "$ENABLE_RATE_LIMIT" = "yes" ] && [ "$type" = "8" ]; then
continue
fi
$IPTABLES -A INPUT -p icmp --icmp-type "$type" -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
done

echo " OK"

# ========================== IPv6 規則 ========================== #
echo -n "Applying IPv6 firewall rules..."

$IP6TABLES -P INPUT DROP
$IP6TABLES -P FORWARD DROP
$IP6TABLES -P OUTPUT ACCEPT

$IP6TABLES -A INPUT -i lo -j ACCEPT

# 建立 BADPKT6 鏈
$IP6TABLES -N BADPKT6
$IP6TABLES -A BADPKT6 -m limit --limit 1/min --limit-burst 3 -j LOG --log-prefix "IPv6_BADPKT: " --log-level 4
$IP6TABLES -A BADPKT6 -j DROP

# Rate limiting 鏈 (IPv6)
if [ "$ENABLE_RATE_LIMIT" = "yes" ]; then
$IP6TABLES -N SSH_ACCEPT6
$IP6TABLES -N WEB_ACCEPT6

SSH_HITCOUNT=$(echo $SSH_RATE | cut -d/ -f1)
SSH_SECONDS=$(echo $SSH_RATE | cut -d/ -f2)
$IP6TABLES -A SSH_ACCEPT6 -m recent --name SSH6 --set
$IP6TABLES -A SSH_ACCEPT6 -m recent --name SSH6 --update --seconds $SSH_SECONDS --hitcount $SSH_HITCOUNT -j LOG --log-prefix "SSH6_RATE_DROP: " --log-level 4
$IP6TABLES -A SSH_ACCEPT6 -m recent --name SSH6 --update --seconds $SSH_SECONDS --hitcount $SSH_HITCOUNT -j DROP
$IP6TABLES -A SSH_ACCEPT6 -j ACCEPT

WEB_HITCOUNT=$(echo $WEB_RATE | cut -d/ -f1)
WEB_SECONDS=$(echo $WEB_RATE | cut -d/ -f2)
$IP6TABLES -A WEB_ACCEPT6 -m recent --name WEB6 --set
$IP6TABLES -A WEB_ACCEPT6 -m recent --name WEB6 --update --seconds $WEB_SECONDS --hitcount $WEB_HITCOUNT -j LOG --log-prefix "WEB6_RATE_DROP: " --log-level 4
$IP6TABLES -A WEB_ACCEPT6 -m recent --name WEB6 --update --seconds $WEB_SECONDS --hitcount $WEB_HITCOUNT -j DROP
$IP6TABLES -A WEB_ACCEPT6 -j ACCEPT
fi

# 允許已建立連線
$IP6TABLES -I INPUT 1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# 阻擋 INVALID
$IP6TABLES -A INPUT -m conntrack --ctstate INVALID -j BADPKT6

# 阻擋非 SYN 的新連線
$IP6TABLES -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j BADPKT6

# 阻擋異常 TCP Flag
for flags in \
"ALL NONE" \
"SYN,FIN SYN,FIN" \
"SYN,RST SYN,RST" \
"FIN,RST FIN,RST" \
"ACK,FIN FIN" \
"ACK,URG URG" \
"ACK,PSH PSH" \
"ALL FIN,URG,PSH" \
"ALL SYN,RST,ACK,FIN,URG" \
"ALL ALL" \
"ALL FIN"
do
$IP6TABLES -A INPUT -p tcp --tcp-flags $flags -j BADPKT6
done

# 阻擋 IPv6 fragment 攻擊
$IP6TABLES -A INPUT -m ipv6header --header frag --soft -j LOG --log-prefix "IPv6_FRAG_DROP: " --log-level 4
$IP6TABLES -A INPUT -m ipv6header --header frag --soft -j DROP

# 允許必要 IPv6 通訊
$IP6TABLES -A INPUT -s fe80::/10 -j ACCEPT # Link-local
$IP6TABLES -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT # DHCPv6

# MLD (Multicast Listener Discovery)
$IP6TABLES -A INPUT -p ipv6-icmp --icmpv6-type 130 -j ACCEPT
$IP6TABLES -A INPUT -p ipv6-icmp --icmpv6-type 131 -j ACCEPT
$IP6TABLES -A INPUT -p ipv6-icmp --icmpv6-type 132 -j ACCEPT

# 阻擋黑名單與私有 IPv6
for ip in $BADIPS $IMPOSSIBLE_IPS; do
if is_ipv6 "$ip"; then
$IP6TABLES -A INPUT -s "$ip" -j DROP
fi
done

# 允許 TCP 埠(IPv6)
for entry in $IN_TCP_PORTALLOWED; do
parse_entry "$entry" tcp ipv6
done

# 允許 UDP 埠(IPv6)
for entry in $IN_UDP_PORTALLOWED; do
parse_entry "$entry" udp ipv6
done

# 允許 ICMPv6
for type in $IN_ICMPV6_ALLOWED; do
$IP6TABLES -A INPUT -p ipv6-icmp --icmpv6-type "$type" -m conntrack --ctstate NEW,ESTABLISHED,RELATED -j ACCEPT
done

echo " OK"

# ========================== 顯示統計 ========================== #
echo ""
echo "防火牆規則統計:"
echo "----------------"
echo "IPv4 規則數:$($IPTABLES -L -v -n | wc -l)"
echo "IPv6 規則數:$($IP6TABLES -L -v -n | wc -l)"
echo ""

# ========================== 測試模式 ========================== #
if [ "$MODE" = "start" ]; then
echo ""
echo "防火牆已啟動(start 模式),規則持續生效。"
echo "若要停用請執行:/usr/local/bin/firewall.sh stop"
exit 0
fi

# 測試模式
WAIT=30

cleanup() {
echo ""
echo -n "正在清除規則(測試結束)..."
$IPTABLES -P INPUT ACCEPT
$IPTABLES -P OUTPUT ACCEPT
$IPTABLES -P FORWARD ACCEPT
$IPTABLES -t filter -F
$IPTABLES -t filter -X

$IP6TABLES -P INPUT ACCEPT
$IP6TABLES -P OUTPUT ACCEPT
$IP6TABLES -P FORWARD ACCEPT
$IP6TABLES -t filter -F
$IP6TABLES -t filter -X
echo " OK"
echo "測試模式結束。若有問題請修正規則後重新測試。"
exit 0
}

trap cleanup INT TERM

echo ""
echo "========================================================"
echo "!!! 測試模式 !!!"
echo "防火牆規則已套用(IPv4 + IPv6)"
echo "將在 ${WAIT} 秒後自動清除規則,以防止鎖死。"
echo ""
echo "請在另一終端機確認連線是否正常:"
echo " SSH 連線測試:ssh localhost"
echo " Ping 測試:ping -c 3 8.8.8.8"
echo " Web 測試:curl -I http://localhost"
echo " IPv6 測試:ping6 -c 3 google.com"
echo ""
echo "若連線正常,請按 Ctrl+C 中斷倒數,然後執行:"
echo " /usr/local/bin/firewall.sh start"
echo "========================================================"
echo ""

i=1
while [ "$i" -le "$WAIT" ]; do
printf "\r等待中... %d 秒後自動清除規則 (按 Ctrl+C 保留規則) " "$((WAIT - i + 1))"
sleep 1
i=$((i + 1))
done

echo ""
cleanup

firewall.sh

本帖最后于,由Jack编辑

创建帐户或登录后发表意见

帐户

导航

搜索

配置浏览器推送通知

Chrome (安卓)
  1. 轻敲地址栏旁的锁形图标。
  2. 轻敲权限 → 通知。
  3. 调整你的偏好。
Chrome (台式电脑)
  1. 点击地址栏中的挂锁图标。
  2. 选择网站设置。
  3. 找到通知选项并调整你的偏好。