利用iptables和netfilter進行NAT和數據報處理
利用iptables和netfilter進行NAT
Linux以前的內核僅僅支持有限的NAT功能,被稱為偽裝。Netfilter則支持任何一種NAT。一般來講NAT可以分為源NAT和目的NAT。
源NAT在數據報經過NF_IP_POST_ROUTING時修改數據報的源地址。偽裝是一個特殊的SNAT。
目的NAT在數據報經過NF_IP_LOCAL_OUT或NF_IP_PRE_ROUTING 時修改數據報目的地址。端口轉發和透明代理都是DNAT。
iptables的NAT目標動作擴展
SNAT
變換數據包的源地址。
例:
iptables -t nat -A POSTROUTING -j SNAT --to-source 1.2.3.4
MASQUERADE
用於具有動態IP地址的撥號連接的SNAT,類似於SNAT,但是如果連接斷開,所有的連接跟蹤信息將被丟棄,而去使用重新連接以後的IP地址進行IP偽裝。
例:
iptables -t nat -A POSTROUTING -j MASQUERADE -o ppp0
DNAT
轉換數據報的目的地址,這是在PREROUTING鉤子鏈中處理的,也就是在數據報剛剛進入時。因此Linux隨後的處理得到的都是新的目的地址。
例:
iptables -t nat -A PREROUTING -j DNAT --to-destination 1.2.3.4:8080 -p tcp --dport 80 -i eth1
REDIRECT
重定向數據報為目的為本地,和DNAT將目的地址修改為接到數據報的接口地址情況完全一樣。
例:
iptables -t nat -A PREROUTING -j REDIRECT --to-port 3128 -i eth1 -p tcp --dport 80
利用iptables和netfilter進行數據報處理(Packet mangling)
mangle表提供了修改數據報各個字段的值的方法。
針對數據包處理的目標擴展
MARK
設置nfmark字段的值。我們可以修改nfmark字段的值。nfmark僅僅是一個用戶定義的數據報的標記(可以是無符號長整數范圍內的任何值)。該標記值用於基於策略的路由,通知ipqmpd (運行在用戶空間的隊列分撿器守護進程)將該數據報排隊給哪個哪個進程等信息。
例: iptables -t mangle -A PREROUTING -j MARK --set-mark 0x0a -p tcp
TOS
設置數據報的IP頭的TOS字段值。若希望適用基於TOS的數據報調度及路由,這個功能是非常有用處的。
例: iptables -t mangle -A PREROUTING -j TOS --set-tos 0x10 -p tcp --dport ssh
排隊數據報到用戶空間
前面已經提到,任何時候在任何nefilter規則鏈中,數據報都可以被排隊轉發到用戶空間去。實際的排隊是由內核模塊來完成的(ip_queue.o)。
數據報(包括數據報的原[meta]數據如nfmark和mac地址)通過netlink socket被發送給用戶空間進程.該進程能對數據報進行任何處理。處理結束以後,用戶進程可以將該數據報重新注入內核或者設置一個對數據報的目標動作(如丟棄等)。
這是netfilter的一個關鍵技術,使用戶進程可以進行復雜的數據報操作。從而減輕了內核空間的復雜度。用戶空間的數據報操作進程能很容易的適用ntfilter提供的稱為libipq的庫來進行開發。
參考文獻:
LaForge's talk about Netfilter
http://www.lisoleg.org/forum-source/messages/1410.Html
The netfilter framework in Linux 2.4
http://www.gnumonks.org/papers/netfilter-lk2000/presentation.html
Linux 2.4 Packet Filtering HOWTO
http://netfilter.kernelnotes.org/unreliable-guides/packet-filtering-HOWTO/index.html
Linux 2.4 NAT HOWTO
http://netfilter.kernelnotes.org/unreliable-guides/NAT-HOWTO/index.html
netfilter hacking HOWTO
http://netfilter.kernelnotes.org/unreliable-guides/netfilter-hacking-HOWTO/index.html