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

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

PHP论坛人

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

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

Debian 13防火牆建置:iptables (nf_tables backend) IPv4+IPv6 雙棧防護、Fail2ban入侵防護、Systemd開機自動啟動

精选回复

Debian 13防火牆建置:iptables (nf_tables backend) IPv4+IPv6 雙棧防護、Fail2ban入侵防護、Systemd開機自動啟動

------
前言
------

在Debian 13中,iptables 預設使用 nf_tables 後端 (指令為 iptables-nft / ip6tables-nft),這代表:

指令名稱仍為 iptables 和 ip6tables (保持向下相容)

底層核心架構已切換為 nftables,效能與擴充性更佳

IPv4 與 IPv6 是兩套獨立的規則集,必須分別設定



常見安全漏洞:

許多管理員只設定 IPv4 防火牆,卻忽略 IPv6。如果伺服器有 IPv6 位址而 ip6tables 規則為空,IPv6 流量將完全不受保護



適用對象:

想繼續使用 iptables 指令語法的管理員

需要同時保護 IPv4 與 IPv6 的環境

希望透過 systemd 開機自動載入規則

需要整合 Fail2ban 防止暴力攻擊




安全提醒:

錯誤的規則可能導致SSH連線中斷,操作前建議先開啟 VNC / Serial Console / IPMI 等帶外管理備援

務必將你目前的管理IP加入允許清單 (包含IPv6位址)

修改前請先備份重要資料

測試模式非常重要:腳本提供 30 秒測試模式,可在規則鎖死連線時自動復原

雲端伺服器注意:AWS、GCP、Hetzner 等平台的內網 IP(10.x.x.x)可能需要保留,否則負載平衡或監控會失效



----------
事前準備
----------

查看目前 IPv4 連線IP
ss -tnp | grep :22 | grep ESTAB


查看目前 IPv6 連線IP
ss -tnp | grep :22 | grep ESTAB | grep '::'



請記下你的管理 IP (包含 IPv6 位址),稍後需填入防火牆腳本





---------------------------------
安裝iptables防火牆並確認後端
---------------------------------

在Debian 13中,ip6tables 是 iptables 套件的一部分,會一併安裝


更新套件清單
apt update


安裝 iptables (ip6tables會一併安裝)
apt install -y iptables


確認後端類型,應顯示 iptables v1.8.11 (nf_tables)
iptables --version


確認後端類型,應顯示 ip6tables v1.8.11 (nf_tables)
ip6tables --version


檢查 ip6tables 指令是否存在,預期輸出:/usr/sbin/ip6tables
which ip6tables



檢查IPv6是否啟用,預期輸出:net.ipv6.conf.all.disable_ipv6 = 0   (0表示啟用)
sysctl net.ipv6.conf.all.disable_ipv6


檢查這台VPS/雲主機的IPv6位址是否存在,應該會顯示你的IPv6位址 (如果有的話)
ip -6 addr show




檢查初始規則狀態

IPv4規則 (初始應為空或僅有基本規則)
iptables -L -v -n


IPv6規則 (應為空)
ip6tables -L -v -n



-------------------------
停用衝突的防火牆工具
-------------------------

注意:請勿移除 nftables 套件,它是核心 Netfilter 框架的一部分


若有安裝ufw,請將其停用以避免規則衝突
systemctl disable --now ufw


若有安裝firewalld,請將其停用以避免規則衝突
systemctl disable --now firewalld




-------------------------
防火牆腳本建立與設定
-------------------------

建立腳本目錄 (若目錄不存在)
mkdir -p /usr/local/bin


建立防火牆腳本
vi /usr/local/bin/firewall.sh


請將提供的防火牆腳本 firewall.sh 內容複製貼上

將腳本 你的管理員IPv4 替換為你的

將腳本 你的管理員IPv6 替換為你的 (若無 IPv6 可留空)


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



# 2. 不可能出現的私有 IP(RFC 1918 / 私有 IPv6)
# 注意:若您的伺服器本身 IP 屬於以下網段,請務必移除對應項目!
# 10.0.0.0/8     → 大型企業內網(Hetzner、AWS 內部網路等請注意)
# 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
#
# 重要:請將「你的管理員IPv4」換成您當前連線的 IPv4 位址!
#       若有 IPv6 連線,請一併填入;若無 IPv6 管理需求,可刪除該項。
IN_TCP_PORTALLOWED="22,你的管理員IPv4 22,你的管理員IPv6 80 443"



ESC儲存並離開
:wq




----------------
設定腳本權限
----------------

設定腳本權限 (700 表示僅 root 可讀寫執行,提高安全性)

chmod 700 /usr/local/bin/firewall.sh



-----------------
測試防火牆腳本
-----------------

執行腳本
/usr/local/bin/firewall.sh


執行後會進入 30 秒測試模式:

規則立即套用

若 30 秒內未中斷(Ctrl+C),規則自動清除,不影響後續連線

若 30 秒內按下 Ctrl+C,規則保留;此時即可確認測試通過


---------------------------------------
另開終端機確認連線 (測試期間進行)
---------------------------------------

測試SSH連線 (應成功)
ssh 你的伺服器IP


測試 IPv4 對外連線 (應成功)
ping -c 3 8.8.8.8


測試 IPv6 對外連線 (若有 IPv6)
ping6 -c 3 google.com


測試 Web (若本機有服務)
curl -I http://localhost

curl -I https://localhost


若有開放其他服務,也一併測試


---------------
查看規則狀態
---------------

查看 IPv4 規則 (含封包計數)
iptables -L -v -n --line-numbers


查看 IPv6 規則
ip6tables -L -v -n --line-numbers



--------------------------
確認無誤後永久套用規則
--------------------------

在測試倒數結束前按 Ctrl+C 保留規則,然後執行

/usr/local/bin/firewall.sh start








-----------------------------
systemd 開機自動啟動
-----------------------------

建立 systemd 服務檔
vi /etc/systemd/system/firewall.service


複製貼上以下內容

[Unit]
Description=Custom iptables/ip6tables Firewall (nf_tables backend)
Before=network-pre.target
Wants=network-pre.target
DefaultDependencies=no


[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/firewall.sh start
ExecStop=/usr/local/bin/firewall.sh stop
StandardOutput=journal

[Install]
WantedBy=multi-user.target


ESC儲存並離開
:wq


------------------
啟用並啟動服務
------------------

重新載入 systemd 設定
systemctl daemon-reload


設定開機自動啟動
systemctl enable firewall.service


立即啟動
systemctl start firewall.service


檢查服務狀態,應顯示 active (exited)
systemctl status firewall.service


查看啟動日誌
journalctl -u firewall.service


確認 IPv4 規則已套用
iptables -L -v -n


確認 IPv6 規則已套用
ip6tables -L -v -n



------------------------
Fail2ban 安裝與配置
------------------------

Fail2ban會持續掃描系統日誌 (如 /var/log/auth.log),偵測到多次登入失敗時,自動將來源IP加入 iptables/ip6tables 封鎖規則,提供動態的入侵防護


安裝 Fail2ban (whois用於查詢被封鎖IP的資訊)
apt update

apt install -y fail2ban whois



確認版本,顯示為 Fail2Ban v1.1.0
fail2ban-client --version






------------------
建立自訂設定檔
------------------

為何不直接修改 jail.conf?

/etc/fail2ban/jail.conf 是套件提供的預設設定,套件更新時會被覆蓋

正確做法是建立 /etc/fail2ban/jail.local,Fail2ban啟動時 .local 的設定會覆蓋 .conf,這樣可以在套件更新後保留你的自訂設定



建立 jail.local 覆蓋預設值
vi /etc/fail2ban/jail.local



貼上以下內容

請將內容中 你的管理員IPv4 / 你的管理員IPv6,替換為你的實際IP



[DEFAULT]
# 白名單:這些IP永遠不會被封鎖,務必填入你的管理員IP (包含IPv6)
# 可填多個,空格分隔;支援 CIDR 網段
ignoreip = 127.0.0.1/8 ::1 你的管理員IPv4 你的管理員IPv6


# 封鎖時間:24 小時 (秒)
bantime = 86400


# 計算失敗次數時間窗:10 分鐘 (秒)
findtime = 600


# 允許失敗次數:超過此次數即觸發封鎖
maxretry = 5


# 封鎖動作:不使用 ipset,使用標準 iptables-multiport
# 支援 IPv4 與 IPv6 雙棧 (Fail2ban會自動選用 iptables 或 ip6tables)
banaction = iptables-multiport
banaction_allports = iptables-allports


# 永久封鎖條件 (recidive 會用到)
bantime.increment = true
bantime.factor = 2
bantime.formula = bantime * (1<<(ban_count if ban_count<20 else 20)) / 2


# ---------------------------------------------------------
# 以下是各個要啟動的監獄 (Jail) 設定
# ---------------------------------------------------------

# SSH登入防護
[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s
backend = %(sshd_backend)s

# SSH 暴力掃描 (更嚴格)
# 針對短時間大量嘗試的掃描機器人,3次即封鎖
[sshd-ddos]
enabled = true
port    = ssh
filter = sshd
logpath = %(sshd_log)s
maxretry = 3
bantime  = 604800


ESC儲存並離開
:wq



暫時只設定SSH防護,等待LNMP服務都安裝配置完畢,再回來增加 監獄 (Jail) 設定





------------------------
啟動 Fail2ban
------------------------

啟用並立即啟動
systemctl enable fail2ban --now


檢查狀態
systemctl status fail2ban



檢查監獄狀態
fail2ban-client status

fail2ban-client status sshd








-------------------
驗證與重開機測試
-------------------

重開機
reboot


防火牆規則應自動載入
iptables -L -v -n

ip6tables -L -v -n



確認 防火牆 服務狀態,應顯示為 active (exited)
systemctl status firewall.service


確認 fail2ban 服務狀態,應顯示為 active (running)
systemctl status fail2ban.service



驗證iptables規則,檢查是否已產生 f2b- 開頭的規則鏈 (這代表 Fail2ban 已成功介入 iptables)
iptables -L -n | grep f2b

ip6tables -L -n | grep f2b





查看開機期間的服務日誌
journalctl -u firewall.service --boot


journalctl -u fail2ban.service --boot



查看防火牆日誌
journalctl -k | grep -E "BADPKT|DROP"




---------------------
常見陷阱與排錯指南
---------------------

陷阱 1:IPv6 防火牆未設定

症狀:IPv4 連線正常,IPv6 連線失敗或完全開放

解決:確認 ip6tables -L -n 有規則,且 ICMPv6 類型已開放

ip6tables -L -n





陷阱 2:ICMPv6 被封鎖

症狀:IPv6 連線時通時不通,或無法取得 IPv6 位址

解決:確認 IN_ICMPV6_ALLOWED 包含必要類型(133-136 等)



陷阱 3:雲端內網 IP 被封鎖

症狀:重開機後負載平衡器或監控系統無法連線

解決:在 IMPOSSIBLE_IPS 中移除對應的私有網段(如 10.0.0.0/8)



陷阱 4:忘記加入管理 IP

症狀:執行 firewall.sh start 後 SSH 立即斷線

解決:透過帶外管理重啟,或等待測試模式自動復原



陷阱 5:服務綁定問題

症狀:IPv6 防火牆開放但服務仍無法連線

解決:檢查服務是否監聽在 ::(雙棧):

ss -tlnp | grep :80

:::80 表示雙棧,0.0.0.0:80 表示僅 IPv4



陷阱 6:Fail2ban 與自訂鏈衝突

症狀:Fail2ban 封鎖失效,或規則順序錯誤

解決:確認 f2b- 鏈在 INPUT 鏈中的順序(應在最後)



陷阱 7:conntrack 模組未載入

症狀:執行腳本時出現 iptables: No chain/target/match by that name

解決:手動載入模組:
modprobe nf_conntrack

echo "nf_conntrack" >> /etc/modules





-----------------
維護與日誌查看
-----------------

查看被封鎖的封包

核心日誌中的防火牆記錄
journalctl -k | grep -E "BADPKT|DROP"


即時監控
dmesg -w | grep -E "BADPKT|DROP"



手動管理 Fail2ban

解除封鎖特定 IP
fail2ban-client set sshd unbanip 203.0.113.99

重新載入設定
fail2ban-client reload

查看所有 jail 狀態
fail2ban-client status



------------------
防火牆腳本維護
------------------

手動停止防火牆 (清除所有規則)
/usr/local/bin/firewall.sh stop

手動啟動防火牆
/usr/local/bin/firewall.sh start


修改規則後測試
測試模式
/usr/local/bin/firewall.sh


測試通過後
/usr/local/bin/firewall.sh start

本帖最后于,由Jack编辑

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

帐户

导航

搜索

配置浏览器推送通知

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