iptables 防火牆配置實戰指南 | Linux 網絡安全教程

iptables 是 Linux 系統中最強大的網絡防火牆工具,通過內核級的 netfilter 框架實現數據包過濾、網絡地址轉換(NAT)和端口轉發。本文將帶你從零開始,系統掌握 iptables 的核心概念與實戰配置。
一、iptables 基礎概念
1.1 表與鏈的結構
iptables 由 表(Tables) 和 鏈(Chains) 組成,不同表負責不同功能:
| 表名 | 作用 | 包含的鏈 |
|---|---|---|
| filter | 數據包過濾(防火牆) | INPUT、FORWARD、OUTPUT |
| nat | 網絡地址轉換 | PREROUTING、POSTROUTING、OUTPUT |
| mangle | 數據包修改(TOS、TTL) | 全部 5 個鏈 |
| raw | 連接跟蹤前處理 | PREROUTING、OUTPUT |
數據包流經順序:
進入 → PREROUTING (raw → mangle → nat)
↓
路由判斷
↓
本地進程?── 是 ──→ INPUT (mangle → filter) → 本地應用 → OUTPUT (raw → mangle → nat → filter) → POSTROUTING → 發出
↓ 否
FORWARD (mangle → filter)
↓
POSTROUTING (mangle → nat) → 發出1.2 鏈的默認策略
每個鏈都有默認策略(Policy),決定沒有匹配規則時的處理方式:
- ACCEPT:允許數據包通過
- DROP:丟棄數據包(不回覆)
- REJECT:拒絕數據包(回覆拒絕信息)
二、iptables 基本命令
2.1 查看規則
# 查看 filter 表所有規則(默認)
iptables -L -n -v --line-numbers
# 查看 nat 表規則
iptables -t nat -L -n -v --line-numbers
# 查看指定鏈規則
iptables -L INPUT -n -v --line-numbers參數說明:
-L:列出規則-n:數字形式顯示 IP 和端口(不解析)-v:詳細信息(包數、字節數)--line-numbers:顯示規則編號-t <表名>:指定表
2.2 添加規則
# 在鏈末尾追加規則
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 在鏈開頭插入規則
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
# 在指定位置插入規則(第 3 條)
iptables -I INPUT 3 -p tcp --dport 443 -j ACCEPT2.3 刪除規則
# 按編號刪除 INPUT 鏈第 2 條規則
iptables -D INPUT 2
# 按內容刪除規則
iptables -D INPUT -p tcp --dport 22 -j ACCEPT
# 清空指定鏈的所有規則
iptables -F INPUT
# 清空所有鏈
iptables -F
# 清空 nat 表
iptables -t nat -F2.4 修改默認策略
# 設置 INPUT 鏈默認策略為 DROP(謹慎操作!)
iptables -P INPUT DROP
# 設置 FORWARD 鏈默認策略為 DROP
iptables -P FORWARD DROP
# 設置 OUTPUT 鏈默認策略為 ACCEPT
iptables -P OUTPUT ACCEPT⚠️ 警告:遠程操作時,切勿將 INPUT 默認策略設為 DROP 且未允許 SSH 端口,否則會被鎖在服務器外!
三、常用匹配條件
3.1 協議與端口
# 匹配 TCP 協議
iptables -A INPUT -p tcp -j ACCEPT
# 匹配指定端口
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 匹配端口範圍
iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT
# 匹配源端口
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT
# 匹配 ICMP(ping)
iptables -A INPUT -p icmp -j ACCEPT3.2 IP 地址匹配
# 匹配源 IP
iptables -A INPUT -s 192.168.1.100 -j ACCEPT
# 匹配源 IP 段
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
# 匹配目的 IP
iptables -A OUTPUT -d 8.8.8.8 -j DROP
# 匹配接口
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
# 匹配出站接口
iptables -A FORWARD -o eth1 -j ACCEPT3.3 狀態匹配(連接跟蹤)
# 允許已建立和相關的連接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允許新連接
iptables -A INPUT -m state --state NEW -p tcp --dport 80 -j ACCEPT
# 丟棄無效數據包
iptables -A INPUT -m state --state INVALID -j DROP狀態說明:
NEW:新連接的第一個包ESTABLISHED:已建立連接的包RELATED:與已有連接相關的包(如 FTP 數據連接)INVALID:無法識別的無效包
四、實戰:基礎防火牆配置
4.1 完整防火牆腳本
#!/bin/bash
# 清空所有規則
iptables -F
iptables -X
iptables -Z
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
# 設置默認策略
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允許本地迴環
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# 允許已建立和相關連接
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# 允許 SSH(先放好,避免被鎖)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允許常見服務端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT # HTTP
iptables -A INPUT -p tcp --dport 443 -j ACCEPT # HTTPS
# 允許 ping(可選)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# 丟棄無效包
iptables -A INPUT -m state --state INVALID -j DROP
echo "防火牆配置完成!"保存為 firewall-setup.sh,執行:
chmod +x firewall-setup.sh
./firewall-setup.sh4.2 規則保存與恢復
# Debian/Ubuntu 保存規則
iptables-save > /etc/iptables/rules.v4
# 安裝 iptables-persistent 實現開機自動加載
apt install -y iptables-persistent
# 手動恢復規則
iptables-restore < /etc/iptables/rules.v4
# CentOS/RHEL 保存規則
service iptables save
# 或
iptables-save > /etc/sysconfig/iptables五、NAT 與端口轉發
5.1 SNAT(源地址轉換)
用於內網機器共享公網 IP 上網:
# 啟用 IP 轉發
echo 1 > /proc/sys/net/ipv4/ip_forward
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
# SNAT:內網 192.168.1.0/24 通過 eth0 的公網 IP 上網
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j SNAT --to-source 公網IP
# 動態 IP 用 MASQUERADE(如撥號上網)
iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE5.2 DNAT(目的地址轉換 / 端口映射)
將公網端口映射到內網服務器:
# 將公網 8080 端口映射到內網 192.168.1.100:80
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
# 允許 FORWARD 轉發(確保目標可達)
iptables -A FORWARD -d 192.168.1.100 -p tcp --dport 80 -j ACCEPT
# 同時映射多個端口(範圍)
iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8000:8100 -j DNAT --to-destination 192.168.1.100:8000-81005.3 本機端口重定向
# 將 80 端口重定向到 8080(透明代理常用)
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
# 本機訪問也重定向(OUTPUT 鏈)
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to-port 8080六、高級應用場景
6.1 防端口掃描
# 限制同一 IP 每秒新建連接數(防 SYN 洪水)
iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
# 限制同一 IP 併發連接數
iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j REJECT
# 檢測端口掃描並記錄日誌
iptables -N PORT_SCAN
iptables -A PORT_SCAN -p tcp --tcp-flags ALL NONE -j DROP
iptables -A PORT_SCAN -p tcp --tcp-flags ALL ALL -j DROP
iptables -A PORT_SCAN -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
iptables -A INPUT -j PORT_SCAN6.2 按時間控制訪問
# 僅工作日 9:00-18:00 允許 SSH
iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
# 週末不允許訪問某服務
iptables -A INPUT -p tcp --dport 3306 -m time --weekdays Sat,Sun -j DROP6.3 字符串匹配(簡單應用層過濾)
# 阻止包含特定字符串的 HTTP 請求
iptables -A INPUT -p tcp --dport 80 -m string --string "admin.php" --algo bm -j DROP
# 阻止特定 User-Agent
iptables -A INPUT -p tcp --dport 80 -m string --string "sqlmap" --algo bm -j DROP⚠️ 字符串匹配對 HTTPS 無效,且無法替代專業的 WAF。
6.4 日誌記錄
# 記錄被拒絕的 SSH 連接嘗試
iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min -j LOG --log-prefix "iptables-ssh: " --log-level 4
# 記錄所有被丟棄的包(先定義 DROP_LOG 鏈)
iptables -N DROP_LOG
iptables -A DROP_LOG -m limit --limit 10/min -j LOG --log-prefix "iptables-drop: " --log-level 4
iptables -A DROP_LOG -j DROP
# 使用自定義鏈
iptables -A INPUT -j DROP_LOG日誌默認記錄在 /var/log/syslog 或 /var/log/messages。
七、企業級防火牆最佳實踐
7.1 規則優化原則
- 最小權限原則:默認拒絕,按需開放
- 規則順序優化:高頻匹配規則放在前面
- 使用狀態檢測:減少規則數量,提高效率
- 合理註釋:每條重要規則說明用途
- 定期審計:清理不再使用的規則
7.2 安全加固建議
# 1. 防止 IP 欺騙(私網地址從公網接口進來)
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
# 2. 防止 SYN Flood
iptables -A INPUT -p tcp --syn -m limit --limit 5/s --limit-burst 10 -j ACCEPT
# 3. 防止 Ping of Death
iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 10 -j ACCEPT
# 4. 碎片包檢測
iptables -A INPUT -f -j DROP7.3 常見服務端口配置清單
| 服務 | 端口 | 協議 | 建議開放 |
|---|---|---|---|
| SSH | 22 | TCP | ✅ 按需 |
| HTTP | 80 | TCP | ✅ 網站服務 |
| HTTPS | 443 | TCP | ✅ 網站服務 |
| DNS | 53 | TCP/UDP | ⚠️ DNS 服務器 |
| FTP | 21 | TCP | ❌ 建議用 SFTP |
| MySQL | 3306 | TCP | ❌ 僅內網 |
| Redis | 6379 | TCP | ❌ 僅內網 |
| MongoDB | 27017 | TCP | ❌ 僅內網 |
八、故障排查
8.1 常見排查命令
# 查看規則匹配計數(哪些規則生效了)
iptables -L -n -v
# 實時跟蹤數據包(調試用)
iptables -A INPUT -p tcp --dport 80 -j LOG --log-prefix "DEBUG-80: "
tail -f /var/log/syslog | grep DEBUG-80
# 清空計數器
iptables -Z
# 查看 NAT 表規則
iptables -t nat -L -n -v8.2 被鎖在服務器外怎麼辦?
如果你遠程操作 iptables 時不小心把自己封了:
- VNC/控制檯:通過雲服務商的 VNC 或控制檯登錄
- 重啟服務器:如果規則沒保存,重啟會恢復默認
- 定時任務保險:配置前先設置定時任務回滾
安全操作建議:
# 配置前先設置 5 分鐘後自動清空規則(保險)
echo "iptables -F; iptables -P INPUT ACCEPT" | at now + 5 minutes
# 確認配置無誤後,取消定時任務
at -l # 查看任務
atrm <ID> # 刪除任務九、iptables 與 ufw / firewalld
- iptables:底層工具,靈活強大,適合高級配置
- ufw:Ubuntu 默認,iptables 的簡化封裝
- firewalld:CentOS/RHEL 默認,支持區域(zone)概念
它們本質上都是 iptables/nftables 的前端工具,底層原理一致。
十、總結
iptables 是 Linux 系統管理員的必備技能,掌握它可以:
- ✅ 構建堅固的網絡防火牆
- ✅ 實現 NAT 和端口轉發
- ✅ 控制進出站流量
- ✅ 防範常見網絡攻擊
- ✅ 實現複雜的網絡策略
建議在測試環境中多加練習,熟練掌握後再應用到生產環境。配置防火牆時一定要做好回滾預案,避免遠程操作時把自己鎖在外面。
相關閱讀: