在玩 IPTables 以前我們必須先了解一下,您所下的 iptables 防火牆規則對封包進行過濾、封包處理、封包狀態變更、NAT、封包 Qos...等,這些工作其實是核心 (kernel) 層級 Netfilter 在處理的,而 iptables 只是一個使用者端的工具讓您方便對 Netfilter 操作而以,以下是對於玩 iptables 時必須先了解的名詞及相關常用指令。
必須注意的是 INPUT 及 Forward 處理封包的路徑是不同的,也就是說 Forward 處理的封包會略過 INPUT 及 OUTPUT 規則
INPUT:經網卡進入的封包 OUTPUT:經網卡出去的封包 FORWARD:經網卡進入 / 出去轉送的封包
PREROUTING:改變經網卡進入的封包狀態 ( DNAT / REDIRECT )
POSTROUTING:改變經網卡出去的封包狀態( SNAT / MASQUERADE )
filter:可以處理 INPUT、OUTPUT、FORWARD 封包狀態 (Default)
nat:可以處理 OUTPUT、PREROUTING、POSTROUTING 封包狀態
mangle:可以處理 INPUT、OUTPUT、FORWRD、PREROUTING、POSTROUTING 封包狀態
NEW:一個新的連線封包 (建立新連線後的第一個封包)
ESTABLISHED:成功建立的連線,即建立追蹤連線後所有封包狀態 (跟在 NEW 封包後面的所有封包)
RELATED:新建連線,由 ESTABLISHED session 所建立的新獨立連線 (ex. ftp-data 連線)
INVALID:非法連線狀態的封包 (DROP 封包)
UNKOWN:不明連線狀態的封包
IPTables 封包處理政策 (Policy) 及 目標 (Target)
ACCEPT:允許封包移動至目的地或另一個 chain
DROP:丟棄封包、不回應要求、不傳送失敗訊息
REJECT:拒絕封包、回應要求、傳送失敗訊息
SNAT:修改 Source Socket
DNAT:修改 Destination Socket
MASQUERADE:動態修改 Source Socket (無法指定 IP,取當時網卡的 IP),較方便但效率較差
REDIRECT:將連線導至本機行程 (Local Process)
RETURN:結束自行定義的 Chain 然後返回原來的 Chain 繼續跑規則 (rules)
QUEUE:封包排隊等待處理
LOG:記錄指定的規則封包 (/etc/syslog.conf , default /var/log/messges)
處理 iptables 規則時常用到如下參數
-h:help information
-V:顯示 iptables 版本
-I:將規則插入至最前面 or 加上號碼插入指定處
-A:將規則插入至最後面
-R:取代指定的規則 (加上規則號碼)
-D:刪除指定的規則 (加上規則號碼)
-F:刪除所有的規則
處理 iptables 規則鏈(chain)時常用到如下參數
-N:建立新的規則鏈(chain)
-X:刪除指定的規則鏈(chain)
-E:更改指定的規則鏈(chain)名稱
-P:變更指定規則鏈(chain)的政策 (ex. policy for DROP、REJECT、ACCEPT)
-Z:將 iptables 計數器歸零
查看目前 iptables 規則時常用到如下參數
-L:列出目前 iptables 規則 (會執行 DNS 位址解析)
-n:不使用 DNS 解析直接以 IP 位址顯示
-v:顯示目前 iptables 規則處理的封包數
-x:顯示完整封包數 (ex.顯示 1151519,而不是 12M)
CentOS 5.1 (Linux 2.6.18-53.1.4.el5)
iptables v1.3.5
步驟1.修改 iptables 設定檔
iptables 主要設定檔位於 /etc/sysconfig/iptables 當系統重開機且設定開機自動啟動時,系統便會讀取此檔案並套用設定的防火牆規則,你可以把預設的防火牆規則拿來該改即可,你可以手動下 iptables 規則然後在 save 我個人的習慣是直接把規則寫在 /etc/sysconfig/iptables 內。
規則語法如下
[-io 網路介面] [-p 協定] [-m 模組] [-s 來源] [-d 目的地] [-j 政策]
-i 網路介面:-i 為 in 網路介面就填 eth0... (用於 PREROUTING、INPUT、FORWARD)
-o 網路介面:-o 為 out 網路介面就填 eth0... (用於 POSTROUTING、OUTPUT、FORWARD)
-m 模組:state、mac、limit、owner、multiport...
-p 協定:tcp、upd、icmp...
-s 來源:可為 IP Address、IP 網段、網域名稱
--sport:指定封包來源 Port、Port Range (配合 -p tcp、-p udp)
-d 目的地:可為 IP、IP 網段、網域名稱
--dport:指定封包目的地 Port、Port Range (配合 -p tcp、-p udp)
-j 政策 / 目標:ACCEPT、DROP、REJECT、SNAT、DNAT、MASQUERADE、REDIRECT、RETURN...
以下為一個很簡單的防火牆規則範例,只允許 SSH Service 可連接該主機
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT //pass Loopback
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT //keep state
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT //pass icmp protocol
-A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT //pass ssh
COMMIT
步驟2.設定開機自動啟動 iptables 服務 確定 iptables 服務是否開機會自動啟動 (ntsysv or setup)
#chkconfig --list |grep iptables
iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
/etc/rc.d/init.d/iptables start //啟動 iptables 服務
stop //停止 iptables 服務
restart //重新啟動 iptables 服務
status //查看目前 iptables 規則
save //將目前規則存入 iptables 設定檔
#/etc/rc.d/init.d/iptables restart
Flushing firewall rules: [ OK ]
Setting chains to policy ACCEPT: filter [ OK ]
Unloading iptables modules: [ OK ]
Applying iptables firewall rules: [ OK ]
Loading additional iptables modules: ip_conntrack_netbios_n[ OK ]
查看我們剛才設定的規則
#/etc/rc.d/init.d/iptables status
Table: filter
Chain INPUT (policy DROP)
num target prot opt source destination
1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
2 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 icmp type 255
4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
Chain FORWARD (policy DROP)
num target prot opt source destination
Chain OUTPUT (policy ACCEPT)
num target prot opt source destination
補充:Web Server 防火牆規則設定 一個 Web Server 的基本 iptables 設定內容如下 (Service SSH、HTTP),我將 INPUT Policy 定義為 DROP 也就是說 eth0 網卡預設行為是丟棄封包、不回應要求、不傳送失敗訊息除新定義的 -j ACCEPT 之外。
#cat /etc/sysconfig/iptables
*filter //定義使用的 chain
:INPUT DROP [0:0] //定義 INPUT Policy
:FORWARD DROP [0:0] //定義 FORWARD Policy
:OUTPUT ACCEPT [0:0] //定義 OUTPUT Policy
-A INPUT -i lo -j ACCEPT //pass Loopback
-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT //keep state
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT //pass icmp protocol
-A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT //pass ssh
-A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT //pass http
COMMIT
IPtables中可以靈活的做各種網絡地址轉換(NAT)
網絡地址轉換主要有兩種:SNAT和DNAT
SNAT是source network address translation的縮寫
即源地址目標轉換
比如,多個PC機使用ADSL路由器共享上網
每個PC機都配置了內網IP
PC機訪問外部網絡的時候,路由器將數據包的報頭中的源地址替換成路由器的ip
當外部網絡的服務器比如網站web服務器接到訪問請求的時候
他的日誌記錄下來的是路由器的ip地址,而不是pc機的內網ip
這是因為,這個服務器收到的數據包的報頭裡邊的「源地址」,已經被替換了
所以叫做SNAT,基於源地址的地址轉換
DNAT是destination network address translation的縮寫
即目標網絡地址轉換
典型的應用是,有個web服務器放在內網配置內網ip,前端有個防火牆配置公網ip
互聯網上的訪問者使用公網ip來訪問這個網站
當訪問的時候,客戶端發出一個數據包
這個數據包的報頭裡邊,目標地址寫的是防火牆的公網ip
防火牆會把這個數據包的報頭改寫一次,將目標地址改寫成web服務器的內網ip
然後再把這個數據包發送到內網的web服務器上
這樣,數據包就穿透了防火牆,並從公網ip變成了一個對內網地址的訪問了
即DNAT,
基於目標的網絡地址轉換
MASQUERADE,地址偽裝,在iptables中有著和SNAT相近的效果,但也有一些區別
但使用SNAT的時候,出口ip的地址範圍可以是一個,也可以是多個,例如:
如下命令表示把所有10.8.0.0網段的數據包SNAT成192.168.5.3的ip然後發出去
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3
如下命令表示把所有10.8.0.0網段的數據包SNAT成192.168.5.3/192.168.5.4/192.168.5.5等幾個ip然後發出去
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j SNAT --to-source 192.168.5.3-192.168.5.5
這就是SNAT的使用方法,即可以NAT成一個地址,也可以NAT成多個地址
但是,對於SNAT,不管是幾個地址,必須明確的指定要SNAT的ip
假如當前系統用的是ADSL動態撥號方式,那麼每次撥號,出口ip192.168.5.3都會改變
而且改變的幅度很大,不一定是192.168.5.3到192.168.5.5範圍內的地址
這個時候如果按照現在的方式來配置iptables就會出現問題了
因為每次撥號後,服務器地址都會變化,而iptables規則內的ip是不會隨著自動變化的
每次地址變化後都必須手工修改一次iptables,把規則裡邊的固定ip改成新的ip
這樣是非常不好用的
MASQUERADE就是針對這種場景而設計的,他的作用是,從服務器的網卡上,自動獲取當前ip地址來做NAT
比如下邊的命令:
iptables -t nat -A POSTROUTING -s 10.8.0.0/255.255.255.0 -o eth0 -j MASQUERADE
如此配置的話,不用指定SNAT的目標ip了
不管現在eth0的出口獲得了怎樣的動態ip,MASQUERADE會自動讀取eth0現在的ip地址然後做SNAT出去
這樣就實現了很好的動態SNAT地址轉換