Jump to content
View in the app

A better way to browse. Learn more.

PHP论坛人

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

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

Featured Replies

#!/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

Edited by Jack

Create an account or sign in to comment

Account

Navigation

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.