# iptables 防火牆完整教程

# iptables 是什麼?

iptables 是 Linux 內核中用於設置、維護和檢查 IP 包過濾規則的工具。它允許系統管理員定義哪些網路流量應該被允許或阻止,是構建企業防火牆的基礎。

三個核心概念:

  1. 表(Table):按功能分類的規則集合

    • filter :過濾表(默認,用於決定是否接受數據包)
    • nat :網路地址轉換表(用於修改數據包的源地址或目標地址)
    • mangle :修改表(用於修改數據包的服務質量等標記)
    • raw :原始表(用於定義不被跟蹤的連接)
  2. 鏈(Chain):規則的有序列表,代表數據包的不同處理階段

    • INPUT :入站流量(從外部進入本機的數據包)
    • OUTPUT :出站流量(從本機發往外部的數據包)
    • FORWARD :轉發流量(經過本機轉發給其他主機的數據包)
    • PREROUTING :路由前(nat 表特有)
    • POSTROUTING :路由後(nat 表特有)
  3. 規則(Rule):匹配條件和相應動作

    • ACCEPT :允許通過
    • DROP :丟棄(不回應)
    • REJECT :拒絕(回應拒絕信息)
    • REDIRECT :轉向
    • LOG :記錄

# 基本操作

# 查看規則

# 查看 filter 表的所有規則(數字格式,便於刪除)
iptables -nL
# 查看指定表的規則
iptables -t nat -nL
iptables -t mangle -nL
# 查看規則並顯示行號
iptables -nL --line-number
# 查看詳細信息(包括數據包和字節計數)
iptables -nvL
iptables -nvL -t nat
# 查看指定鏈的規則
iptables -nL INPUT
iptables -nL FORWARD

# 添加和刪除規則

# 添加規則到鏈的末尾
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 在指定位置插入規則(例如插入到第 2 行)
iptables -I INPUT 2 -p tcp --dport 80 -j ACCEPT
# 替換指定位置的規則
iptables -R INPUT 3 -p tcp --dport 443 -j ACCEPT
# 刪除規則(按行號)
iptables -D INPUT 3
# 刪除規則(按規則內容)
iptables -D INPUT -p tcp --dport 22 -j ACCEPT

# 清除規則

# 清空 filter 表的所有規則
iptables -F
# 清空特定鏈
iptables -F INPUT
# 清空特定表的所有鏈
iptables -t nat -F
# 刪除用戶自定義的鏈
iptables -X
# 重置表的計數器
iptables -Z

# 常用參數說明

# 匹配條件
-s, --source       # 匹配源地址
-d, --destination  # 匹配目的地址
-p, --protocol     # 匹配協議(tcp, udp, icmp, all)
-i, --in-interface # 進入的網卡(如 eth0)
-o, --out-interface # 離開的網卡(如 eth0)
# TCP/UDP 端口
--sport            # 源端口
--dport            # 目標端口
-m multiport       # 多個端口(需要擴展匹配)
# 其他選項
-j, --jump         # 指定動作(ACCEPT, DROP, REJECT, LOG 等)
-m, --match        # 使用擴展匹配

# 實際應用場景

# 場景 1:允許 SSH 訪問和 HTTP/HTTPS 服務

# 設置默認策略為拒絕(最小化原則)
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# 允許本地迴環接口
iptables -A INPUT -i lo -j ACCEPT
# 允許已建立的連接
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# 允許 SSH(22)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 允許 HTTP(80)和 HTTPS(443)
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
# 允許 ICMP ping
iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT

# 場景 2:限制特定 IP 訪問

# 拒絕來自特定 IP 的訪問
iptables -A INPUT -s 192.168.100.50 -j DROP
# 只允許特定 IP 訪問 SSH
iptables -I INPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

# 場景 3:端口映射

# 轉發外來的 8080 流量到本地 80 端口
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80
# 查看 NAT 規則
iptables -t nat -nL

# 場景 4:日誌記錄與故障排查

# 記錄被拒絕的連接
iptables -A INPUT -p tcp -j LOG --log-prefix "Rejected-TCP: "
iptables -A INPUT -p tcp -j DROP
# 記錄 ICMP
iptables -A INPUT -p icmp -j LOG --log-prefix "ICMP-Packet: "
# 查看日誌
tail -f /var/log/syslog | grep Rejected

# 規則持久化

# 方式 1:導出和導入(推薦)

# 導出當前規則到文件
iptables-save > /etc/iptables/rules.v4
# 導入規則
iptables-restore < /etc/iptables/rules.v4
# 開機自動加載(Ubuntu/Debian)
apt-get install iptables-persistent
netfilter-persistent save
netfilter-persistent reload

# 方式 2:創建啟動腳本

/etc/init.d/iptables-setup 中添加:

#!/bin/bash
# /etc/init.d/iptables-setup
case "$1" in
  start)
    iptables-restore < /etc/iptables/rules.v4
    echo "iptables rules loaded"
    ;;
  stop)
    iptables -F
    echo "iptables rules flushed"
    ;;
esac

然後:

chmod +x /etc/init.d/iptables-setup
update-rc.d iptables-setup defaults

# 常見錯誤和排查

# 無法連接到服務

# 檢查是否有允許該端口的規則
iptables -nL | grep 80
# 確認規則順序( DROP 前必須有 ACCEPT)
iptables -nvL --line-number
# 檢查是否設置了默認拒絕策略
iptables -nvL | head -5

# 性能問題

  • 大規則集時,使用狀態跟蹤可能影響性能
  • 考慮使用 UFW(Ubuntu)或 firewalld(CentOS)作為簡化層

# 排查連接故障

# 臨時允許所有流量進行測試(** 生產環境慎用 **)
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -P OUTPUT ACCEPT
# 然後逐步添加規則測試

# 總結

iptables 雖然學習曲線陡峭,但掌握基本概念後非常強大。建議:

  1. 從簡單的允許清單開始(允許必要服務,其他拒絕)
  2. 充分測試規則後再持久化
  3. 在生產環境前備份工作配置
  4. 對複雜場景,可考慮使用 UFW 或 firewalld 簡化管理