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.

新增NAT規則與IP轉發 + Debian 13防火牆建置:iptables (nf_tables backend) IPv4/IPv6 雙棧防護、Fail2ban入侵防護、Systemd開機自動啟動

Featured Replies

解決論壇顯示 內網IP/私有IP(VPC)的問題,新增NAT規則與IP轉發



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

在阿里雲、騰訊雲等大廠雲服務商,雲主機通常會同時分配:

公網IP:用於對外提供服務

內網IP / 私有IP(VPC):用於內部網路通訊

論壇後端(如 PHP、Nginx、管理後台)在顯示使用者來源IP時,若未經設定,可能會顯示內網IP而非真實的公網IP,導致日誌分析、防護機制、使用者管理等功能異常

因此,需透過網路介面與NAT規則設定,確保對外服務的IP正確對應







------------------
解決方案總覽
------------------

1.設定 iptables NAT 規則:將來自公網IP的封包來源轉換為私有IP

2.設定開機自動載入規則:使用 systemd 服務確保重啟後規則仍生效



----------------------------------------
建立 iptables NAT 規則腳本
----------------------------------------

建立腳本存放目錄
mkdir -p /usr/local/bin



建立NAT規則腳本
vi /usr/local/bin/firewall-NAT.sh

貼入 NAT 規則

firewall-NAT.sh

修改為你的實際IP (你的公網IP 與 你的私有IP)

# ========== 請修改以下設定 ==========

# 你的公網IP(必填)

PUBLIC_IP=""

# 你的私有IP(若無則與公網相同)

PRIVATE_IP=""

# ============

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter


-----------------
賦予執行權限
-----------------


賦予執行權限
chmod 700 /usr/local/bin/firewall-NAT.sh


chown root:root /usr/local/bin/firewall-NAT.sh



立即執行
/usr/local/bin/firewall-NAT.sh start




檢查NAT規則是否已加入
iptables -t nat -L -n -v



----------------------------
啟用IP轉發 (核心參數)
----------------------------

建立配置文件(只需執行一次)

這兩行一起複製貼上

echo "net.ipv4.ip_forward = 1" | sudo tee /etc/sysctl.d/99-ipforward.conf
sudo sysctl --system










---------------------
立即生效
---------------------

立即生效
sysctl --system


確認狀態
sysctl net.ipv4.ip_forward



注意:若未啟用IP轉發,NAT規則將無法正確轉送封包




----------------------------------------
建立 systemd 服務 (開機自動執行)
----------------------------------------

為了讓NAT規則在重啟後自動生效,建立一個新的 systemd 服務


建立 systemd 服務檔案
vi /etc/systemd/system/ip-forward.service




貼上以下內容



[Unit]
Description=IP Forward NAT Rule for Aliyun VPC Public IP
After=network.target firewall.service
Wants=network.target

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

[Install]
WantedBy=multi-user.target





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




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


重新載入 systemd
systemctl daemon-reload



啟用並啟動服務
systemctl enable ip-forward.service



systemctl start ip-forward.service




確認服務狀態,應顯示 active (exited)
systemctl status ip-forward.service





------------------------
驗證步驟,稍後再測
------------------------


等待到設置 iptables (nf_tables backend) IPv4 IPv6 雙棧 防火牆 設置完成,重開機後,再來驗證IP轉發




----------------
小結
----------------

在阿里雲等 VPC 環境下,將VPS 公網IP 正確對應至內網IP的完整設定流程,解決論壇後台顯示內網IP的問題

透過iptables NAT規則的搭配,並使用 systemd 確保規則持久化,能有效提升論壇的IP識別正確性與系統穩定性

若仍有網路異常或效能問題,建議進一步檢查:主機商安全組 / 防火牆規則是否開放對應埠號、是否與 Docker、其他防火牆工具衝突

Edited by Jack

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


******************************************************************************************
Fail2ban Part 1

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





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

在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


查詢 IPv4
curl -4 ifconfig.me



查詢 IPv6(若有)
curl -6 ifconfig.me



請記下你的管理 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 內容複製貼上

firewall.sh

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



# 1. 禁止連線的 IP 或網段(支援 IPv4 與 IPv6)
BADIPS=""


# 2. 私有 IP 網段(RFC 1918 / 私有 IPv6)
# ⚠️ 重要:只加入【實際會連線到本機】的內網網段!
# 例如:VPC 內網是 10.0.0.0/8 → 只加 10.0.0.0/8
# 如果沒有內網連線需求,請留空:PRIVATE_IPS_V4=""
# 千萬不要加入所有私有網段,以免降低安全性!

# 請根據實際需求填入,例如:"10.0.0.0/8"
PRIVATE_IPS_V4=""


# IPv6 唯一本地位址(如有需要)
PRIVATE_IPS_V6="fc00::/7"



# 3. 允許對內連線的 TCP 通訊埠
# 格式:埠號,來源IP(多個項目用空格分隔)
# ⚠️ 重要:請將「您的管理員IPv4」和「您的管理員IPv6」替換為實際 IP
# 查詢當前 IP:curl -4 ifconfig.me (IPv4) / curl -6 ifconfig.me (IPv6)
IN_TCP_PORTALLOWED="22,您的管理員IPv4 22,您的管理員IPv6 888,您的管理員IPv4 80 443"






儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter

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

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

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


chown root:root /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


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


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

查看 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



儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




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

重新載入 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

貼上以下內容

jail.local.txt

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

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

----------------------------------------
IPv6 雙棧封鎖實作 (iptables方案)
----------------------------------------

建立自訂動作,同時操作 IPv4 與 IPv6:

vi /etc/fail2ban/action.d/iptables-ipv4-ipv6.conf



貼上內容


[Definition]
actionstart = iptables -N f2b-<name>
              ip6tables -N f2b-<name>
              iptables -I INPUT -p <protocol> -m multiport --dports <port> -j f2b-<name>
              ip6tables -I INPUT -p <protocol> -m multiport --dports <port> -j f2b-<name>

actionstop = iptables -D INPUT -p <protocol> -m multiport --dports <port> -j f2b-<name>
             ip6tables -D INPUT -p <protocol> -m multiport --dports <port> -j f2b-<name>
             iptables -F f2b-<name>
             ip6tables -F f2b-<name>
             iptables -X f2b-<name>
             ip6tables -X f2b-<name>

actionban = iptables -I f2b-<name> 1 -s <ip> -j DROP
            ip6tables -I f2b-<name> 1 -s <ip> -j DROP

actionunban = iptables -D f2b-<name> -s <ip> -j DROP
              ip6tables -D f2b-<name> -s <ip> -j DROP

[Init]
# 預設參數
port = http,https
protocol = tcp




儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter



注意:此動作會同時建立 iptables 與 ip6tables 規則,確保 IPv4 與 IPv6 請求皆能被封鎖









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

啟用
systemctl enable fail2ban --now



---------------------
驗證與測試
---------------------


測試 Fail2ban 設定檔語法
fail2ban-client -t


預期輸出:OK: configuration test is successful




重新啟動
systemctl restart fail2ban





-------------------
重開機驗證
-------------------


重開機
reboot



防火牆規則應自動載入

iptables -L -v -n


ip6tables -L -v -n




確認IP轉發已啟用,應顯示 net.ipv4.ip_forward = 1
sysctl net.ipv4.ip_forward




確認 NAT 服務,應顯示 active (exited)
systemctl status ip-forward.service



查看網路介面是否包含公網IP
ip addr show | grep "公網IP"
例如:你主機的公網IP是 45 開頭的情況

ip addr show | grep "45"





確認 NAT 規則已套用
iptables -t nat -L -n -v


應顯示,例如 0     0 SNAT       all  --  *      *       10.25.x.x           0.0.0.0/0            to:45.x.x.x






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




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




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


IPv4
iptables -L -n | grep f2b


IPv6
ip6tables -L -n | grep f2b


若剛剛拿到VPS,立刻做到這個步驟,應該無顯示任何結果

並且主機需要在線幾天後,還有 DNS 你的域名.com 有修改並指向新主機的IP,才會顯示 f2b- 開頭的規則鏈




查看所有啟用的監獄
fail2ban-client status



查看特定監獄的狀態
fail2ban-client status sshd




使用 fail2ban-client 指令來檢查指定監獄 (例如 sshd) 目前正在使用的白名單列表

確認你的修改已成功加載 VPS分配的 私有IP

fail2ban-client get sshd ignoreip



----------------------------------------
測試 IPv4 與 IPv6 是否會被封鎖
----------------------------------------

使用 fail2ban-client 手動觸發封鎖


手動封鎖一個測試 IPv4 地址
fail2ban-client set sshd banip 192.0.2.100



手動封鎖一個測試 IPv6 地址
fail2ban-client set sshd banip 2001:db8::100




查看監獄狀態,Banned IP 列表應顯示被封鎖的 IP
fail2ban-client status sshd



查看防火牆是否真的封鎖了該 IP

剛剛手動封鎖一個測試 IPv4 192.0.2.100

iptables -L f2b-sshd -n -v



剛剛手動封鎖一個測試 IPv6 2001:db8::100

ip6tables -L f2b-sshd -n -v





解除封鎖

fail2ban-client set sshd unbanip 192.0.2.100

fail2ban-client set sshd unbanip 2001:db8::100




----------------------
查看日誌
----------------------

查看開機期間的服務日誌
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

Edited by Jack

Guest
This topic is now closed to further replies.

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.