原理
寫代碼的人都知道,在寫一個系統(tǒng)的時候,為了保持這個系統(tǒng)的靈活性和可擴(kuò)展性,我們經(jīng)常會在系統(tǒng)的某些地方留個坑,換句話說就是留一些鉤子,讓別人在這鉤子里干一些事情,擴(kuò)展整個系統(tǒng)的功能。iptables 實(shí)際上是對 Linux 網(wǎng)絡(luò)棧鉤子里實(shí)現(xiàn)的邏輯。
iptables原理圖
官網(wǎng)的Iptables架構(gòu)圖:
更加詳細(xì)的圖:
最完整的一張?jiān)韴D
一個數(shù)據(jù)包進(jìn)來,首先會經(jīng)過 PREROUTING 鏈,PREROUTING 鏈最重要的一個功能就是可以修改數(shù)據(jù)包目的地址和端口。過了 PREROUTING 之后,內(nèi)核會根據(jù)數(shù)據(jù)包的目的地址來決定該數(shù)據(jù)包是進(jìn)入 INPUT 鏈還是 FORWARD 鏈。發(fā)送給本機(jī)的數(shù)據(jù)包經(jīng)過 INPUT 鏈之后就直接交給本地的進(jìn)程處理了;至于非本機(jī)的數(shù)據(jù)包就會根據(jù) FORWARD 的規(guī)則來判斷是否需要轉(zhuǎn)發(fā)該數(shù)據(jù)包。所有從本機(jī)出去的數(shù)據(jù)包最后都需要經(jīng)過 POSTROUTING 鏈,POSTROUTING 鏈的最重要的一個作用是修改數(shù)據(jù)包的源地址。
層級調(diào)用關(guān)系
These chains have no policy; if a packet reaches the end of the chain it is returned to the chain which called it
換句話說,iptables 有類似于函數(shù)調(diào)用的層級關(guān)系!
NAT
SNAT
SNAT 發(fā)生在 postrouting 階段,將本機(jī)產(chǎn)生的所有的數(shù)據(jù)的源地址進(jìn)行相應(yīng)的修改。如果要啟用 SNAT,只需在 iptables 規(guī)則鏈中添加-j SNAT
和--to-source
指定數(shù)據(jù)包的 IP 地址即可,下面是幾個例子:
# 將數(shù)據(jù)包的源地址修改為1.2.3.4。
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4
# 將數(shù)據(jù)包的源地址修改為1.2.3.4至1.2.3.6中的任意一個。
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6
Masquerading
有的時候 IP 地址可能會動態(tài)的發(fā)生變化,因此,如果像上面的例子那樣指定死了 IP 地址的話,當(dāng) IP 地址一發(fā)生變化,就需要重新修改規(guī)則了。為了省去這樣的麻煩,你可以使用-j MASQUERADE
,-j MASQUERADE
告訴 iptables 總是將數(shù)據(jù)包的源地址修改為網(wǎng)絡(luò)接口的 IP 地址(如果從 eth0 出去,就使用 eth0 的地址,如果從 eth1 出去,就使用 eth1 的地址)。下面是一個例子:
# 將所有從ppp0出去的數(shù)據(jù)包的源地址修改為ppp0的IP地址
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE
DNAT
DNAT 是在 PREROUTING 鏈中修改數(shù)據(jù)包的目的地址,你可以在規(guī)則中使用-j DNAT
和--to-destination
來使用 DNAT,--to-destination
是指定數(shù)據(jù)包的目的地址是什么。下面是 iptables 的一些例子:
# 將來自eth0的數(shù)據(jù)包的目的地址修改為5.6.7.8
iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8
# 指定隨意選用一段IP地址
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10
## Change destination addresses of web traffic to 5.6.7.8, port 8080.
iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT --to 5.6.7.8:8080
一些心得
PREROUTING 和 POSTROUTING 兩條鏈?zhǔn)怯坞x在 Linux 系統(tǒng)之外的,所有一些修改數(shù)據(jù)包的邏輯可以放在這里面做。