使用 iptables hashlimit 限制 HTTP 流量與安全回滾方法

在高流量或遭受爬蟲攻擊時,Web Server(如 Apache / Nginx)可能會因為大量連線而消耗過多 PHP-FPM 或系統資源。
Linux iptableshashlimit 模組可以有效限制「每個 IP 的連線速率」,是一種輕量且高效的防護方式。

本文說明:

  • hashlimit 的用途
  • 基本設定方法
  • 測試方式
  • 如何安全取消規則(回滾)

一、什麼是 hashlimit?

hashlimit 是 iptables 的一個 match module。

它的特色是:

✅ 針對「每個來源 IP」獨立計算流量
✅ 不會把所有訪客視為同一個來源
✅ 適合防止單一 IP 短時間內大量請求

-m limit 不同,limit 是全局限制,容易誤傷正常使用者。


二、基本 HTTP 限制範例

以下規則限制:

  • 每個 IP 每秒最多 30 個請求
  • 瞬間最多 80 個 burst
  • 超過後丟棄(DROP)

bash

iptables -A INPUT -p tcp --dport 80 \
-m hashlimit \
--hashlimit 30/sec \
--hashlimit-burst 80 \
--hashlimit-mode srcip \
--hashlimit-name http_limit \
-j ACCEPT

iptables -A INPUT -p tcp --dport 80 -j DROP

參數說明

參數說明
–hashlimit 30/sec每秒最多 30 個封包
–hashlimit-burst 80瞬間可達 80 個
–hashlimit-mode srcip以來源 IP 為單位計算
–hashlimit-name此限制規則的名稱

三、如何確認規則是否生效?

使用:

bash

iptables -L INPUT -n -v

可以看到每條規則的封包計數。

如需查看行號(刪除時會用到):

bash

iptables -L INPUT -n --line-numbers

四、如何安全取消規則?

✅ 方法一(推薦):使用行號刪除

先查看規則:

bash

iptables -L INPUT -n --line-numbers

假設顯示:

basic

num  target
1    ACCEPT  tcp dpt:80 hashlimit ...
2    DROP    tcp dpt:80

刪除方式:

bash

iptables -D INPUT 1
iptables -D INPUT 1

⚠ 注意:刪除第一條後,下面規則會往上移動。


✅ 方法二:使用完整規則刪除

bash

iptables -D INPUT -p tcp --dport 80 \
-m hashlimit \
--hashlimit 30/sec \
--hashlimit-burst 80 \
--hashlimit-mode srcip \
--hashlimit-name http_limit \
-j ACCEPT

iptables -D INPUT -p tcp --dport 80 -j DROP

⚠ 必須與建立規則時完全一致。


五、如果使用 iptables-persistent

若系統有安裝:

iptables-persistent

或使用:

netfilter-persistent

刪除規則後,請記得重新儲存:

bash

iptables-save > /etc/iptables/rules.v4

否則重開機後規則會恢復。


六、安全測試建議(避免誤封)

⚠ 在 Production 環境請勿直接啟用 DROP 規則。

建議測試流程:

1️⃣ 先只加入 hashlimit ACCEPT 規則
2️⃣ 觀察流量與錯誤日誌
3️⃣ 確認正常後再加入 DROP

或先於測試機驗證。


七、適用場景

  • WordPress 遭受爬蟲過度抓取
  • WooCommerce 頁面被大量請求
  • 想降低 PHP-FPM 壓力
  • 防止單一 IP 造成資源耗盡

八、注意事項

  • 若使用 Cloudflare,來源 IP 可能會變成 CDN IP
  • iptables 屬於 L3/L4 防火牆,無法判斷 URL
  • 規則順序非常重要

結語

hashlimit 是一種:

  • 高效
  • 核心層級
  • 不依賴應用程式

的流量控制方式。

但部署前務必測試,並確保有回滾方案,以避免影響正常使用者。

Linux 防火牆完整備份與還原教學(iptables + ipset)

在使用 Fail2Ban + ipset + iptables 的伺服器環境中,
很多人只備份了 iptables,卻忽略了 ipset

結果在災難還原時發現:

  • ✅ 規則還在
  • ❌ 被封鎖的 IP 全部消失

這篇教學會完整說明:

  1. 為什麼要同時備份 iptables 與 ipset
  2. 正確備份方式
  3. 正確還原順序
  4. 建議自動化備份腳本

🔎 一、iptables 與 ipset 差在哪?

在 Fail2Ban 環境中實際架構是:

Fail2Ban
   ↓
ipset(存放被封鎖 IP 清單)
   ↓
iptables(引用 ipset)
   ↓
Linux Kernel 防火牆

✅ iptables 負責「規則」

例如:

-m set --match-set f2b-http-404-scan src -j DROP

意思是:

如果來源 IP 在這個 set 裡 → 就 DROP


✅ ipset 負責「IP 名單」

例如:

add f2b-http-404-scan 65.20.67.134

真正被封鎖的 IP 存在 ipset 裡。


🚨 二、常見錯誤

很多人只做:

iptables-save > /root/iptables.backup

但這只會備份規則,不會備份 ipset 內的 IP。

結果:

  • 重開機後
  • 或手動 restore 後

IP 清單消失。


✅ 三、正確完整備份方式

必須備份兩個部分。


✅ 1️⃣ 備份 iptables

bash

iptables-save > /root/iptables.backup

✅ 2️⃣ 備份 ipset

bash

ipset save > /root/ipset.backup

這個檔案會包含:

sql_more

create f2b-http-404-scan hash:ip
add f2b-http-404-scan 65.20.67.134
add f2b-http-404-scan 1.2.3.4

這才是真正的封鎖名單。


✅ 四、正確還原方式(非常重要)

⚠️ 還原順序不能錯。


✅ Step 1:先還原 ipset

bash

ipset restore < /root/ipset.backup

✅ Step 2:再還原 iptables

bash

iptables-restore < /root/iptables.backup

❗ 為什麼順序不能反?

因為:

iptables 規則會引用 ipset。

如果 ipset 不存在,會出現錯誤:

iptables: Set f2b-http-404-scan doesn't exist

✅ 五、建議每日自動備份

可以建立一個腳本:

nano /root/backup-firewall.sh

內容如下:

bash

#!/bin/bash

DATE=$(date +%F)

iptables-save > /root/fw-$DATE.iptables
ipset save > /root/fw-$DATE.ipset

給執行權限:

bash

chmod +x /root/backup-firewall.sh

加入 crontab:

bash

crontab -e

每天凌晨 3 點備份:

basic

0 3 * * * /root/backup-firewall.sh

✅ 六、如果發生誤封全站怎麼辦?

假設錯誤規則導致:

0.0.0.0/0 tcp dpt:80 DROP

網站全部無法連線。

只要執行:

bash

ipset restore < /root/ipset.backup
iptables-restore < /root/iptables.backup

30 秒內救回網站。


✅ 七、關於 Fail2Ban 的補充

如果你使用:

banaction = iptables-ipset-proto6-allports

Fail2Ban 重啟後會自動重建 ipset。

因此:

✅ 一般重開機不會遺失封鎖
✅ 但手動清空 firewall 會遺失

所以備份仍然是好習慣。


✅ 八、總結

項目是否需要備份
iptables✅ 必須
ipset✅ 必須
只備份 iptables❌ 不完整

🎯 最重要一句話

iptables 只是規則
ipset 才是黑名單

兩個都要備份,才算完整防火牆備份。

Linux 指令教學:如何使用 ss -K 強制中斷指定 IP 的 TCP 連線

在 Linux 伺服器管理中,有時需要立即中斷某個 IP 的現有連線,例如:

  • fail2ban 已經 Ban IP
  • iptables 規則已生效
  • 但既存 TCP 連線仍在持續

這時不必重啟服務,可以使用:

ss -K

來精準關閉指定連線。


什麼是 ss

ss(Socket Statistics)是用來查看 socket 連線狀態的工具,
功能比舊版 netstat 更完整、更快速。


ss -K 是什麼?

-K  = Kill

意思是:

強制關閉符合條件的 TCP 連線

它會透過 kernel 直接發送 TCP RST,立即中斷連線。


基本用法

中斷某個來源 IP 的所有連線

ss -K src 20.91.210.252

意思是:

關閉所有「來源為 20.91.210.252」的 TCP 連線

⚠ 在伺服器上,攻擊者是來源(source),
所以必須使用 src


查看是否有連線存在

執行前可先確認:

ss -ant | grep 20.91.210.252

如果看到:

ESTAB

代表仍有已建立連線,可以使用 ss -K 中斷。


常見錯誤

❌ 錯誤寫法:

ss -K dst 20.91.210.252

在伺服器端通常應該使用 src
否則可能找不到對應連線。


與重啟服務的差別

方法影響範圍
restart Apache所有使用者
ss -K src IP只有指定 IP

使用 ss -K 可以精準操作,而不影響正常流量。


權限需求

必須使用 root 執行:

Operation not permitted

代表權限不足。


小結

ss -K 是一個非常實用的進階網路管理指令:

  • 可立即中斷指定 IP 連線
  • 不必重啟服務
  • 不影響其他使用者
  • 適用於安全事件處理

在需要精準控制 TCP 連線時,是比重啟服務更優雅的做法。

備份/恢複 CentOS 7 系統到網絡磁碟

備份 CentOS 7 系統到網絡磁碟

  • 掛載你的網絡磁碟機
mkdir -p /mnt/backup
mount -t cifs //<SMB_SERVER_IP>/backup /mnt/backup -o username=<USERNAME>,password=<PASSWORD>
  • 使用 tar 備份系統
tar --xattrs --xattrs-include='*' --acls --selinux -cvpzf /mnt/backup/centos7_backup.tar.gz --exclude=/mnt --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run --exclude=/tmp --exclude=/root_backup.tar.gz /

從網絡磁碟 恢複到 CentOS 7 系統

掛載你的網絡磁碟機

mkdir -p /mnt/backup
mount -t cifs //<SMB_SERVER_IP>/backup /mnt/backup -o username=<USERNAME>,password=<PASSWORD>

確認 centos7_backup.tar.gz 在 /mnt/backup

ls -lh /mnt/backup/centos7_backup.tar.gz

還原 tar.gz 備份

解壓 tar.gz 到 /

tar --xattrs --xattrs-include='*' --acls --selinux -xvpzf /mnt/backup/centos7_backup.tar.gz -C /

確保 /dev、/proc、/sys、/run 目錄存在

mkdir -p /dev /proc /sys /run

修復 fstab

獲取磁碟的 UUID

blkid

確保 /etc/fstab 使用正確的 UUID

nano /etc/fstab

修復 Bootloader(GRUB)

掛載必要的系統目錄

mount --bind /dev /dev
mount --bind /proc /proc
mount --bind /sys /sys
mount --bind /run /run

切換到 chroot 環境

chroot /

重新安裝 GRUB

grub2-install --target=i386-pc /dev/sda
grub2-mkconfig -o /boot/grub2/grub.cfg

更新 initramfs

dracut --force --regenerate-all

退出 chroot

exit

SELinux 修復

創建 .autorelabel

touch /.autorelabel

重新啟動並測試

重啟系統

reboot

確認系統是否正常運行

df -h
lsblk

Linux Find Command

ExamplesCreated by @dan_nanni on Instagram

find . -name “my.txt” find all files named “my.txt”

find .-type d-name “mydir” find all directories named “mydir”

find . -type f-name “*.jpg” find all “.jpg” files

find . -type f-size +100M find all files larger than 100MB

find . -type f-size +100M-size -500M find files with a specific size range

find . -type f-mtime-1 find all files modified in last 24 hours

find .-mtime-7-mtime +1 find files modified betn yesterday & a week ago

find . -type f-name “*.tmp” -delete find and remove all “.tmp” files

find . -type f-perm 0777 find all files with “777” permission

find . -type f-perm-u+x find all files executed by the user

find . -type f-name “*.txt” -exec cat {} \; find and cat all “*.txt” files

find . -type f-amin-60 find all files accessed within the last hour

find . -type f-user dan find all files owned by the user “dan”

find .-type f-ctime -2 find files created within last 2 days

find .-maxdepth 1 -name “my.txt” search only in current dir

find . -type f-name “*.txt” | xargs chmod 644 chmod all “.txt” to 644

find . -type f-name “*.jpg” | xargs tar -cf img.tgz archive all “.jpg” files

find . -type f-name “*.png” | xargs -I {} mv {} /tmp move all “.png” files

find . -type f-name “*.txt” | xargs grep “Hello” search for Hello in “.txt”

find .-xtypel-delete find and remove all broken symbolic links

find .-type d-empty-delete find and remove all empty directories

find .-newermt “2024-01-01”! -newermt “2024-03-15” use a time range

fixing VPN problem in Ubuntu Windows

Source : http://blog.wensheng.org/2015/05/fixing … buntu.html

fixing VPN problem in Ubuntu

I set up VPN in Ubuntu 14.04, but when I tried to turn it on in NetworkManager, I kept getting errors like “No suitable device found”, “Could not find source connection” in /var/log/syslog.

The problem turned out to be that my ethernet connection was not managed by NetworkManager. “nmcli c” didn’t show my wired connection.

The solution:
Edit /etc/NetworkManager/NetworkManager.conf, in section [ifupdown], change “managed=false” to “managed=true”, then do a:
“sudo service network-manager restart”
Now both vpn and ethernet connections are managed by NetworkManager, turning on VPN just works.

p.s.
About Having DNS Issues when connected to a VPN

source : https://askubuntu.com/questions/320921/having-dns-issues-when-connected-to-a-vpn-in-ubuntu-13-04

Question
I am connecting to a Cisco VPN Server using vpnc. Once connected, my machine was unable to automatically update DNS setting from the new VPN. I tested by temporarily changing /etc/resolv.conf with the proper nameserver and search domain, and everything worked. This is obviously not a long term solution, so I added an additional DNS server and search domain to the VPN settings in Network manager. With those settings in place, resolvconf does add the search domain, but not the DNS IP, and I still cannot do any lookups.

What is my next step in configuring or troubleshooting from here?

Answer

First make sure that there are no lines beginning with nameserver in any files in /etc/resolvconf/resolv.conf.d. If /etc/resolvconf/resolv.conf.d/tail is a symbolic link to target original, make it point to /dev/null.

Second, disconnect from the VPN. Edit /etc/NetworkManager/NetworkManager.conf

$ sudo gedit /etc/NetworkManager/NetworkManager.conf

and comment out

dns=dnsmasq
(i.e., add a # so that it looks like the following)

#dns=dnsmasq
and then

sudo service network-manager restart

PPTP Client Auto Reconnect Note 

# Create vpn Connection
pptpsetup –create vpnhk –server x.x.x.x –username vpn-user-name –password vpn-password –encrypt –start
pptpsetup –create vpnlw –server y.y.y.y –username vpn-user-name –password vpn-password –encrypt –start
pptpsetup –create vpnfw –server z.z.z.z –username vpn-user-name –password vpn-password –encrypt –start

# Manual Connect VPN
pon vpnhk updetach
pon vpnlw updetach
pon vpnfw updetach

# Manual Disconnect All VPN
poff -a

# Manual Route Add
route add -net 192.168.90.0 netmask 255.255.255.0 dev ppp0
route del -net 192.168.90.0 netmask 255.255.255.0

# Setup Boot up ppp Auto Connection
/etc/network/interface
auto vpnhk
iface vpnhk inet ppp
provider vpnhk

auto vpnlw
iface vpnlw inet ppp
provider vpnlw

auto vpnhk
iface vpnhk inet ppp
provider vpnlw

# added by pptpsetup
/etc/ppp/chap-secrets
joehome vpnhk “AABBccdd” 192.168.45.40
joehome vpnfw “AABBccdd” 192.168.45.60
joehome vpnlw “AABBccdd” 192.168.45.70

# Auto pptp Re-connection modify Sample
/etc/ppp/peers/vpnfw
# written by pptpsetup
pty “pptp 19.15.3.2 –nolaunchpppd”
lock
noauth
nobsdcomp
nodeflate
name joehome
remotename vpnfw
ipparam vpnfw
require-mppe-128
maxfail 0
persist

# Install quagga Dynamic Route tools
apt-get install quagga

# Dynamic Route Configuration, Need install quagga
/etc/quagga/daemons
zebra=yes
bgpd=no
ospfd=no
ospf6d=no
ripd=yes
ripngd=no
isisd=no
babeld=no

# Dynamic Route Table setting, Need install quagga
/etc/quagga/zebra.conf
hostname AnyName
password YourPassword
enable password YourPassword
ip route 192.168.1.0/24 192.168.40.1
ip route 192.168.40.0/24 192.168.40.1
ip route 192.168.60.0/24 192.168.60.1
ip route 192.168.70.0/24 192.168.70.1
ip route 192.168.90.0/24 192.168.40.1

# Dynamic Route Restart
/etc/init.d/quagga restart