跳轉到內容

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

iptables 防火牆配置

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

bash
# 查看 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 添加規則

bash
# 在鏈末尾追加規則
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 ACCEPT

2.3 刪除規則

bash
# 按編號刪除 INPUT 鏈第 2 條規則
iptables -D INPUT 2

# 按內容刪除規則
iptables -D INPUT -p tcp --dport 22 -j ACCEPT

# 清空指定鏈的所有規則
iptables -F INPUT

# 清空所有鏈
iptables -F

# 清空 nat 表
iptables -t nat -F

2.4 修改默認策略

bash
# 設置 INPUT 鏈默認策略為 DROP(謹慎操作!)
iptables -P INPUT DROP

# 設置 FORWARD 鏈默認策略為 DROP
iptables -P FORWARD DROP

# 設置 OUTPUT 鏈默認策略為 ACCEPT
iptables -P OUTPUT ACCEPT

⚠️ 警告:遠程操作時,切勿將 INPUT 默認策略設為 DROP 且未允許 SSH 端口,否則會被鎖在服務器外!


三、常用匹配條件

3.1 協議與端口

bash
# 匹配 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 ACCEPT

3.2 IP 地址匹配

bash
# 匹配源 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 ACCEPT

3.3 狀態匹配(連接跟蹤)

bash
# 允許已建立和相關的連接
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 完整防火牆腳本

bash
#!/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,執行:

bash
chmod +x firewall-setup.sh
./firewall-setup.sh

4.2 規則保存與恢復

bash
# 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 上網:

bash
# 啟用 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 MASQUERADE

5.2 DNAT(目的地址轉換 / 端口映射)

將公網端口映射到內網服務器:

bash
# 將公網 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-8100

5.3 本機端口重定向

bash
# 將 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 防端口掃描

bash
# 限制同一 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_SCAN

6.2 按時間控制訪問

bash
# 僅工作日 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 DROP

6.3 字符串匹配(簡單應用層過濾)

bash
# 阻止包含特定字符串的 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 日誌記錄

bash
# 記錄被拒絕的 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 規則優化原則

  1. 最小權限原則:默認拒絕,按需開放
  2. 規則順序優化:高頻匹配規則放在前面
  3. 使用狀態檢測:減少規則數量,提高效率
  4. 合理註釋:每條重要規則說明用途
  5. 定期審計:清理不再使用的規則

7.2 安全加固建議

bash
# 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 DROP

7.3 常見服務端口配置清單

服務端口協議建議開放
SSH22TCP✅ 按需
HTTP80TCP✅ 網站服務
HTTPS443TCP✅ 網站服務
DNS53TCP/UDP⚠️ DNS 服務器
FTP21TCP❌ 建議用 SFTP
MySQL3306TCP❌ 僅內網
Redis6379TCP❌ 僅內網
MongoDB27017TCP❌ 僅內網

八、故障排查

8.1 常見排查命令

bash
# 查看規則匹配計數(哪些規則生效了)
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 -v

8.2 被鎖在服務器外怎麼辦?

如果你遠程操作 iptables 時不小心把自己封了:

  1. VNC/控制檯:通過雲服務商的 VNC 或控制檯登錄
  2. 重啟服務器:如果規則沒保存,重啟會恢復默認
  3. 定時任務保險:配置前先設置定時任務回滾

安全操作建議:

bash
# 配置前先設置 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 和端口轉發
  • ✅ 控制進出站流量
  • ✅ 防範常見網絡攻擊
  • ✅ 實現複雜的網絡策略

建議在測試環境中多加練習,熟練掌握後再應用到生產環境。配置防火牆時一定要做好回滾預案,避免遠程操作時把自己鎖在外面。


相關閱讀:

最後更新於: