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 (修改版)

Featured Replies

#!/bin/sh
# -----------------------------------------------------------------------------
# 防火牆腳本 - 適用於 Debian 13 / iptables-nft (nf_tables backend)
# 存放路徑:/usr/local/bin/firewall.sh
# 權限設定:chmod 700 /usr/local/bin/firewall.sh
# 整合 systemd 開機啟動 (參考 firewall.service)
#
# 功能說明:
#   - 支援 start / stop 參數
#   - 無參數執行時進入測試模式,7 秒後自動清除規則(避免鎖死自己)
#   - 包含核心參數調校(抗攻擊、防 IP Spoofing)
#   - 支援來源 IP 限制、連續埠、反向排除
# -----------------------------------------------------------------------------

# ========================== 使用者設定區塊 ========================== #
# 警告:修改前請務必閱讀註解,並確認您的管理 IP 已正確設定!

# 1. 禁止連線的 IP 或網段(空白分隔)
# 範例:BADIPS="198.108.0.0/16 203.0.113.0/24"
BADIPS=""

# 2. 不可能出現的私有 IP(RFC 1918)
# 注意:若您的伺服器本身 IP 屬於以下網段,請務必刪除該行!
#   10.0.0.0/8    → 大型企業內網
#   172.16.0.0/12 → 中型企業內網
#   192.168.0.0/16→ 小型辦公室/家庭網路
IMPOSSIBLE_IPS="10.0.0.0/8 172.16.0.0/12 192.168.0.0/16"

# 3. 允許對內連線的 TCP 通訊埠
# 格式說明:
#   - 單一埠:22
#   - 連續埠:7000:7009(包含 7000~7009)
#   - 指定來源 IP:22,192.168.1.100
#   - 反向排除(!):22,!192.168.1.100(允許所有人,除了該 IP)
#   - 網段寫法:22,10.0.0.0/8
#
# 重要:請務必將「你的管理員IP」換成您當前連線的 IP,否則套用 DROP 後將無法連線!
IN_TCP_PORTALLOWED="22,你的管理員IP 888,你的管理員IP 80 443"



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



# 5. 允許對內連線的 ICMP 類型
# 常用類型:
#   0:Echo Reply(回應 PING)
#   3:Destination Unreachable
#   8:Echo Request(允許外部 PING 本機)
#   11:Time Exceeded(traceroute 需要)
IN_ICMP_ALLOWED="8"




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

# 停止功能:清除所有規則,完全開放防火牆(供 systemd ExecStop 或緊急使用)
if [ "$1" = "stop" ]; then
    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
    echo " OK"
    echo "警告:所有防火牆規則已清除,伺服器目前無任何防護!"
    exit 0
fi

# 清除現有規則,還原預設策略
echo -n "Initializing iptables..."
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
iptables -t filter -F
iptables -t filter -X
echo " OK"

# 若帶有 start 參數,則跳過測試模式
[ "$1" = "start" ] && skiptest="1"

# ========================== 核心參數調校 ========================== #
# 這些設定可提升伺服器對抗某些網路攻擊的能力

# 啟用 SYN Cookies(防止 SYN Flood 攻擊)
sysctl -w net.ipv4.tcp_syncookies=2 > /dev/null 2>&1

# 忽略廣播 PING(防止 Smurf 攻擊)
sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=2 > /dev/null 2>&1 || \
sysctl -w net.ipv4.icmp_echo_ignore_all_broadcasts=2 > /dev/null 2>&1

# 忽略格式錯誤的 ICMP 封包
sysctl -w net.ipv4.icmp_ignore_bogus_error_responses=2 > /dev/null 2>&1 || \
sysctl -w net.ipv4.icmp_echo_ignore_bogus_error_responses=2 > /dev/null 2>&1

# 關閉 ICMP 重新導向(防止路由表被惡意變更)
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

# 關閉來源路由(防止封包偽造)
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

# 啟用逆向路徑過濾(防止 IP Spoofing)
sysctl -w net.ipv4.conf.all.rp_filter=2 > /dev/null 2>&1
sysctl -w net.ipv4.conf.default.rp_filter=2 > /dev/null 2>&1

# TCP 逾時調校(加快斷線偵測)
sysctl -w net.ipv4.tcp_retries1=3 > /dev/null 2>&1
sysctl -w net.ipv4.tcp_fin_timeout=30 > /dev/null 2>&1
sysctl -w net.ipv4.tcp_keepalive_time=1400 > /dev/null 2>&1




# 注意:以下功能為現代 TCP 必要選項,請勿關閉:
#   - tcp_window_scaling(高延遲高頻寬連線效能)
#   - tcp_sack(封包遺失重傳效率)
#   - tcp_timestamps(RTT 計算與 PAWS 保護)

# ========================== 防火牆規則設定 ========================== #
echo -n "Applying firewall rules..."

# 設定預設策略:INPUT 與 FORWARD 預設丟棄,OUTPUT 預設允許
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 3/min -j LOG --log-prefix "BADPKT: "
iptables -A BADPKT -j DROP

# 阻擋連線狀態為 INVALID 的封包
iptables -A INPUT -m conntrack --ctstate INVALID -j BADPKT

# 阻擋非 SYN 的新連線(異常連線嘗試)
iptables -A INPUT -p tcp ! --syn -m conntrack --ctstate NEW -j BADPKT

# 阻擋各種異常 TCP Flags 組合(掃描或攻擊手法)
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j BADPKT
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j BADPKT
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j BADPKT
iptables -A INPUT -p tcp --tcp-flags FIN,RST FIN,RST -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ACK,FIN FIN -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ACK,URG URG -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ACK,PSH PSH -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ALL SYN,RST,ACK,FIN,URG -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ALL ALL -j BADPKT
iptables -A INPUT -p tcp --tcp-flags ALL FIN -j BADPKT

# -------------------------- 狀態允許規則 -------------------------- #
# 允許已建立連線與相關連線(回應封包不需重新驗證)
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

# -------------------------- 阻擋特定 IP -------------------------- #
iptables -N BADIP
iptables -A BADIP -j DROP

for ip in $BADIPS $IMPOSSIBLE_IPS; do
    # 忽略空白變數
    [ -n "$ip" ] && iptables -A INPUT -s $ip -j BADIP
done

# -------------------------- 允許特定連線 -------------------------- #
# 允許 TCP 連線
for entry in $IN_TCP_PORTALLOWED; do
    # 處理格式 "port,source" 或 "port"
    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/^!//')
                iptables -A INPUT -p tcp --dport $port --syn -m conntrack --ctstate NEW -s $src_ip -j DROP
                iptables -A INPUT -p tcp --dport $port --syn -m conntrack --ctstate NEW -j ACCEPT
            else
                iptables -A INPUT -p tcp --dport $port --syn -m conntrack --ctstate NEW -s $src -j ACCEPT
            fi
            ;;
        *)
            iptables -A INPUT -p tcp --dport $entry --syn -m conntrack --ctstate NEW -j ACCEPT
            ;;
    esac
done

# 允許 UDP 連線(無 SYN 標誌)
for entry in $IN_UDP_PORTALLOWED; do
    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/^!//')
                iptables -A INPUT -p udp --dport $port -m conntrack --ctstate NEW -s $src_ip -j DROP
                iptables -A INPUT -p udp --dport $port -m conntrack --ctstate NEW -j ACCEPT
            else
                iptables -A INPUT -p udp --dport $port -m conntrack --ctstate NEW -s $src -j ACCEPT
            fi
            ;;
        *)
            iptables -A INPUT -p udp --dport $entry -m conntrack --ctstate NEW -j ACCEPT
            ;;
    esac
done

# 允許 ICMP 類型
for entry in $IN_ICMP_ALLOWED; do
    case "$entry" in
        *,*)
            type=$(echo "$entry" | cut -d, -f1)
            src=$(echo "$entry" | cut -d, -f2-)
            if echo "$src" | grep -q '^!'; then
                src_ip=$(echo "$src" | sed 's/^!//')
                iptables -A INPUT -p icmp --icmp-type $type -m conntrack --ctstate NEW -s $src_ip -j DROP
                iptables -A INPUT -p icmp --icmp-type $type -m conntrack --ctstate NEW -j ACCEPT
            else
                iptables -A INPUT -p icmp --icmp-type $type -m conntrack --ctstate NEW -s $src -j ACCEPT
            fi
            ;;
        *)
            iptables -A INPUT -p icmp --icmp-type $entry -m conntrack --ctstate NEW -j ACCEPT
            ;;
    esac
done

# 對外連線不限制(預設 OUTPUT ACCEPT)
# 若需要限制對外連線,可在 OUTPUT 鏈設定規則,此處不贅述

echo " OK"

# ========================== 測試模式 ========================== #
if [ "$skiptest" = "1" ]; then
    exit 0
fi

echo ""
echo "!!! 測試模式 !!!"
echo "防火牆規則已套用,將在 7 秒後自動清除,以防止您意外鎖定自己。"
echo "若您仍能正常連線,請按 Ctrl + C 中斷,然後執行:"
echo "    /usr/local/bin/firewall.sh start"
echo ""

i=1
while [ "$i" -le 7 ]; do
    echo -n "."
    sleep 1
    i=$((i + 1))
done

echo ""
echo -n "正在清除規則..."
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -t filter -F
iptables -t filter -X
echo " OK"
echo "測試模式結束。若連線中斷,請使用 VNC/Serial Console 重新登入並修正規則。"

firewall.sh

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.