iptables實現網卡包的轉發

mips小板上有兩個網卡eth0、eth1,如今要實現的是將eth0接收到的數據從eth1中轉發出去。linux

 

iptables -t nat -A PREROUTING -i eth0 -p tcp -m tcp -s ! 10.0.0.1 -d 12.0.0.1 --dport 21 -j DNAT --to-destination 10.0.0.2:8888
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j SNAT --to-source 12.0.0.1
或者
iptables -t nat -A POSTROUTING -o eth0 -p tcp -m tcp -d 10.0.0.2 --dport 8888 -j MASQUERADE
IP_FORWARD已經打開

這兩條規則鏈轉發沒有問題
可是問題是  來源地址的IP被  POSTROUTING鏈給修改成了 12.0.0.1
有沒有什麼辦法能夠 讓IPTABLES只作包轉發   不改變 數據包的來源地址。
有哪位知道的話 告訴一下
謝謝!服務器

-------------[   ip 18.0.10.1      ]-------------------[ 12.0.0.1:21]
                                                                          |
                                                                          |
                                                                          |
                                                                  [   10.0.0.1:8888  ]
描述 。IP180.0.10.1訪問  12.0.0.1:21端口
          12.0.0.1把來自21端口的訪問 重定向道公網的  10.0.0.1:8888
          10.0.0.1:8888看到的來源地址  須要時   18.0.10.1 而不是  12.0.0.1網絡

 

 設咱們有一臺計算機,有兩塊網卡,eth0連外網,ip爲1.2.3.4;eth1連內網,ip爲192.168.0.1.如今須要把發往地址1.2.3.4的81端口的ip包轉發到ip地址192.168.0.2的8180端口,設置以下:

  1. iptables -t nat -A PREROUTING -d 1.2.3.4 -p tcp -m tcp --dport 81 -j DNAT --to-destination192.168.0.2:8180

  2. iptables -t nat -A POSTROUTING -s 192.168.0.0/255.255.0.0 -d 192.168.0.2 -p tcp -m tcp --dport 8180 -j SNAT --to-source 192.168.0.1

  真實的傳輸過程以下所示:

  假設某客戶機的ip地址爲6.7.8.9,它使用本機的1080端口鏈接1.2.3.4的81端口,發出的ip包源地址爲6.7.8.9,源端口爲1080,目的地址爲1.2.3.4,目的端口爲81.

  主機1.2.3.4接收到這個包後,根據nat表的第一條規則,將該ip包的目的地址更該爲192.168.0.2,目的端口更該爲8180。同時在鏈接跟蹤表中建立一個條目,(可從/proc/net/ip_conntrack文件中看到),而後發送到路由模塊,經過查路由表,肯定該ip包應發送到eth1接口。在向eth1接口發送該ip包以前,根據nat表的第二條規則,若是該ip包來自同一子網,則將該ip包的源地址更該爲192.168.0.1,同時更新該鏈接跟蹤表中的相應條目,而後送0接口發出.

  此時鏈接跟蹤表中有一項:

  鏈接進入: src=6.7.8.9 dst=1.2.3.4 sport=1080 dport=81

  鏈接返回: src=192.168.0.2 dst=6.7.8.9 sport=8180 dport=1080

  是否使用: use=1

  而從192.168.0.2發回的ip包,源端口爲8180,目的地址爲6.7.8.9,目的端口爲1080,主機1.2.3.4的TCP/IP棧接收到該ip包後,由核心查找鏈接跟蹤表中的鏈接返回欄目中是否有一樣源和目的地址和端口的匹配項,找到後,根據條目中的記錄將ip包的源地址由192.168.0.2更該爲1.2.3.4, 源端口由8180更該爲81,保持目的端口號1080不變.這樣服務器的返回包就能夠正確的返回發起鏈接的客戶機,通信就這樣開始.

  還有一點, 在filter表中還應該容許從eth0鏈接192.168.0.2地址的8180端口:

  iptables -A INPUT -d 192.168.0.2 -p tcp -m tcp --dport 8180 -i eth0 -j ACCEPT架構

 

 

什麼是Iptables? 

iptables 是創建在 netfilter 架構基礎上的一個包過濾管理工具,最主要的做用是用來作防火牆或透明代理。Iptables 從 ipchains 發展而來,它的功能更爲強大。Iptables 提供如下三種功能:包過濾、NAT(網絡地址轉換)和通用的 pre-route packet mangling。app

包過濾:用來過濾包,可是不修改包的內容。Iptables 在包過濾方面相對於 ipchians 的主要優勢是速度更快,使用更方便。socket

NAT:NAT 能夠分爲源地址 NAT 和目的地址 NAT。 

Iptables 能夠追加、插入或刪除包過濾規則。實際上真正執行這些過慮規則的是 netfilter 及其相關模塊(如 iptables 模塊和 nat 模塊)。tcp

Netfilter 是 Linux 核心中一個通用架構,它提供了一系列的 「表」(tables),每一個表由若干 「鏈」(chains)組成,而每條鏈中能夠有一條或數條 「規則」(rule)組成。 工具

iptables 能夠操縱3 個表:filter 表,nat 表,mangle 表。 
NAT 和通常的 mangle 用 -t 參數指定要操做哪一個表。filter 是默認的表,若是沒有 -t 參數,就默認對 filter 表操做。
 「filter」表中包含了 INPUT、FORWARD 和 OUTPUT 3 個鏈。 

每一條鏈中能夠有一條或數條規則,每一條規則都是這樣定義的:若是數據包頭符合這樣的條件,就這樣處理這個數據包。當一個數據包到達一個鏈時,系統就會從第一條規則開始檢查,看是否符合該規則所定義的條件: 若是知足,系統將根據該條規則所定義的方法處理該數據包;若是不知足則繼續檢查下一條規則。最後,若是該數據包不符合該鏈中任一條規則的話,系統就會根據該鏈預先定義的策略來處理該數據包。 網站


 

 


規則:

Rule 規則:過濾規則,端口轉發規則等,例如:禁止任何機器 ping 咱們的服務器,能夠在服務器上設置一條規則: 

iptables -A INPUT -s ! 127.0.0.1 -p icmp -j DROP 

從 –s 開始便是一條規則,-j 前面是規則的條件,-j 開始是規則的行爲(目的)。整條命令解釋爲,在filter 表中的 INPUT 規則鏈中插入一條規則,全部源地址不爲 127.0.0.1 的 icmp 包都被拋棄。 
(下面的一些例子能夠此例子爲參考)代理


Chain (規則鏈):由一系列規則組成,每一個包順序通過 chain 中的每一條規則。chain 又分爲系統 chain和用戶建立的 chain。下面先敘述系統 鏈。 

filter 表的系統 鏈: INPUT,FORWARD,OUTPUT 

nat 表的系統 鏈: PREROUTING,POSTROUTING,OUTPUT 

mangle 表的系統 鏈: PREROUTING,OUTPUT 

每條系統 chain 在肯定的位置被檢查。好比在包過濾中,全部的目的地址爲本地的包,則會進入INPUT 規則鏈,而從本地出去的包會進入 OUTPUT 規則鏈。 

全部的表(table) 和 鏈(chain) 開機時都爲空,設置 iptables 的方法就是在合適的 table 和系統 chain 中添相應的規則。 
 

 



iptables:

表:   iptables從其使用的三個表(filter、nat、mangle)而得名, 對包過濾只使用 filter 表, filter仍是默認表,無需顯示說4明. 

操做命令: 即添加、刪除、更新等。 

鏈:  對於包過濾能夠針對filter表中的INPUT、OUTPUT、FORWARD鏈,也能夠操做用戶自定義的鏈。 

規則匹配器: 能夠指定各類規則匹配,如IP地址、端口、包類型等。 

目標動做: 當規則匹配一個包時,真正要執行的任務,經常使用的有: 

ACCEPT 容許包經過 

DROP 丟棄包 


 

一些擴展的目標還有: 

REJECT 拒絕包,丟棄包同時給發送者發送沒有接受的通知 

LOG 包有關信息記錄到日誌 

TOS 改寫包的TOS值 

 




爲使FORWARD規則可以生效,可以使用下面2種方法的某種: 

[root@rhlinux root]# vi /proc/sys/net/ipv4/ip_forward 
[root@rhlinux root]# echo "1" > /proc/sys/net/ipv4/ip_forward 

[root@rhlinux root]# vi /etc/sysconfig/network 
[root@rhlinux root]# echo "FORWARD_IPV4=true" > /etc/sysconfig/network 

 

 




iptables語法能夠簡化爲下面的形式: 

iptables [-t table] CMD [chain] [rule-matcher] [-j target] 

CMD  經常使用操做命令: 

-A 或 -append 在所選鏈尾加入一條或多條規則 


-D 或 -delete 在所選鏈尾部刪除一條或者多條規則 

-R 或 -replace 在所選鏈中替換一條匹配規則 

-I 或 -insert 以給出的規則號在所選鏈中插入一條或者多條規則. 若是規則號爲1,即在鏈頭部. 

-L 或 -list 列出指定鏈中的全部規則,若是沒有指定鏈,將列出鏈中的全部規則. 

-F 或 -flush 清除指定鏈和表中的所由規則, 假如不指定鏈,那麼全部鏈都將被清空. 

-N 或 -new-chain 以指定名建立一條新的用戶自定義鏈,不能與已有鏈名相同. 

-X 或 -delete-chain 刪除指定的用戶定義簾,必需保證鏈中的規則都不在使用時才能刪除,若沒有指定鏈,則刪除全部用戶鏈. 

-P 或 -policy 爲永久簾指定默認規則(內置鏈策略),用戶定義簾沒有缺省規則,缺省規則也使規則鏈中的最後一條規則,用-L顯示時它在第一行顯示. 

-C 或 -check 檢查給定的包是否與指定鏈的規則相匹配. 

-Z 或 -zero 將指定簾中所由的規則包字節(BYTE)計數器清零. 

-h 顯示幫助信息. 

matcher  經常使用匹配規則器: 

-p , [!] protocol 指出要匹配的協議,能夠是tcp, udp, icmp, all, 前綴!爲邏輯非,表示除該協議外的全部協議. 

-s [!] address[/mask] 指定源地址或者地址範圍. 

-sport [!] port[:port] 指定源端口號或範圍,能夠用端口號也能夠用/ETC/SERVICES文件中的名子. 

-d [!] address[/mask] 指定目的地址或者地址範圍. 

-dport [!] port[:port] 指定目的端口號或範圍,能夠用端口號也能夠用/ETC/SERVICES文件中的名子. 

-icmp-type [!] typename 指定匹配規則的ICMP信息類型(可使用 iptables -p icmp -h 查看有效的ICMP類型名) 

-i [!] interface name[+] 匹配單獨或某種類型的接口,此參數忽略時,默認符合全部接口,接口可使用"!"來匹配捕食指定接口來的包.參數interface是接口名,如 eth0, eht1, ppp0等,指定一個目前不存在的接口是徹底合法的,規則直到接口工做時才起做用,折中指定對於PPP等相似鏈接是很是有用的."+"表示匹配全部此類型接口.該選項只針對於INPUT,FORWARD和PREROUTING鏈是合法的. 

-o [!] interface name[+] 匹配規則的對外網絡接口,該選項只針對於OUTPUT,FORWARD,POSTROUTING鏈是合法的. 

[!] --syn 僅僅匹配設置了SYN位, 清除了ACK, FIN位的TCP包. 這些包表示請求初始化的TCP鏈接.阻止從接口來的這樣的包將會阻止外來的TCP鏈接請求.但輸出的TCP鏈接請求將不受影響.這個參數僅僅當協議類型設置爲了TCP才能使用. 此參數可使用"!"標誌匹配已存在的返回包,通常用於限制網絡流量,即只容許已有的,向外發送的鏈接所返回的包. 

 -m module_name 使用擴展模塊來進行數據包的匹配。如: 

        -m tcp 的意思是使用 tcp 擴展模塊的功能 (tcp擴展模塊提供了 --dport, --tcp-flags, --sync等功能).

 

 


-j target :

 ACCEPT target

這個target沒有任何選項和參數,使用也很簡單,指定-j ACCEPT便可。一旦包知足了指定的匹配條件,就會被ACCEPT,而且不會再去匹配當前鏈中的其餘規則或同一個表內的其餘規則,但它還要經過其餘表中的鏈,並且在那兒可能會百DROP也說不許哦

 

DNAT target 

這個target是用來作目的網絡地址轉換的,就是重寫包的目的IP地址。若是一個包被匹配了,那麼和它屬於同一個流的全部的包都會被自動轉換,而後就能夠被路由到正確的主機或網絡。DNAT target是很是有用的。

好比,你的Web服務器在LAN內部,並且沒有可在Internet上使用的真實IP地址,那就可使用這個 target讓防火牆把全部到它本身HTTP端口的包轉發給LAN內部真正的Web服務器。目的地址也能夠是一個範圍,這樣的話,DNAT會爲每個流隨機分配一個地址。所以,咱們能夠用這個target作某種類型地負載平衡。

注意,DANT target只能用在nat表的PREROUTING和OUTPUT鏈中,或者是被這兩條鏈調用的鏈裏。但還要注意的是,包含DANT target的鏈不能被除此以外的其餘鏈調用,如POSTROUTING。

例:

 

Option

--to-destination

Example

iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.1.1-192.168.1.10 

解釋

指定要寫入IP頭的地址,這也是包要被轉發到的地方。上面的例子就是把全部發往地址15.45.23.67的包都轉發到一段LAN使用的私有地址中,即192.168.1.1到 192.168.1.10。如前所述,在這種狀況下,每一個流都會被隨機分配一個要轉發到的地址,但同一個流老是使用同一個地址。咱們也能夠只指定一個IP地址做爲參數,這樣全部的包都被轉發到同一臺機子。咱們還能夠在地址後指定一個或一個範圍的端口。好比:--to-destination 192.168.1.1:80或 --to-destination 192.168.1.1:80-100。SNAT的語法和這個target的同樣,只是目的不一樣罷了。要注意,只有先用--protocol指定了TCP或 UDP協議,才能使用端口。

 

 

由於DNAT要作不少工做,因此我要再羅嗦一點。咱們經過一個例子來大體理解一下它是如何工做的。好比,我想經過Internet鏈接發佈咱們的網站,可是HTTP server在咱們的內網裏,並且咱們對外只有一個合法的IP,就是防火牆那個對外的IP——$INET_IP。防火牆還有一個內網的IP——$LAN_IP,HTTP server的IP是$HTTP_IP (這固然是內網的了)。爲了完成咱們的設想,要作的第一件事就是把下面的這個簡單的規則加入到nat表的PREROUTING鏈中:

iptables -t nat -A PREROUTING --dst $INET_IP -p tcp --dport 80 -j DNAT \ --to-destination $HTTP_IP 

如今,全部從Internet來的、到防火牆的80端口去的包都會被轉發(或稱作被DNAT )到在內網的HTTP服務器上。若是你在Internet上試驗一下,一切正常吧。再從內網裏試驗一下,徹底不能用吧。這實際上是路由的問題。下面咱們來好好分析這個問題。爲了容易閱讀,咱們把在外網上訪問咱們服務器的那臺機子的IP地址記爲$EXT_BOX。

 

DROP target

顧名思義,若是包符合條件,這個target就會把它丟掉,也就是說包的生命到此結束,不會再向前走一步,效果就是包被阻塞了。在某些狀況下,這個target會引發意外的結果,由於它不會向發送者返回任何信息,也不會向路由器返回信息,這就可能會使鏈接的另外一方的sockets因苦等迴音而亡:) 解決這個問題的較好的辦法是使用REJECT target,(譯者注:由於它在丟棄包的同時還會向發送者返回一個錯誤信息,這樣另外一方就能正常結束),尤爲是在阻止端口掃描工具得到更多的信息時,能夠隱蔽被過濾掉的端口等等(譯者注:由於掃描工具掃描一個端口時,若是沒有返回信息,通常會認爲端口未打開或被防火牆等設備過濾掉了)。還要注意若是包在子鏈中被DROP了,那麼它在主鏈裏也不會再繼續前進,不論是在當前的表仍是在其餘表裏。總之,包死翹翹了。


 

 


如何制定永久規則集: /etc/sysconfig/iptables 文件是 iptables 守護進程調用的默認規則集文件. 可使用如下命令保存執行過的IPTABLES命令: /sbin/iptables-save > /etc/sysconfig/iptables 要恢復原來的規則庫,可使用: /sbin/iptables-restore < /etc/sysconfig/iptables iptables命令和route等命令同樣,重啓以後就會恢復,因此: [root@rhlinux root]# service iptables save 將當前規則儲存到 /etc/sysconfig/iptables: [ 肯定 ] 令一種方法是 /etc/rc.d/init.d/iptables 是IPTABLES的啓動腳本,因此: [root@rhlinux root]# /etc/rc.d/init.d/iptables save 將當前規則儲存到 /etc/sysconfig/iptables: [ 肯定 ] 以上幾種方法只使用某種便可. 若要自定義腳本,可直接使用iptables命令編寫一個規則腳本,並在啓動時執行: 例如若規則使用腳本文件名/etc/fw/rule, 則能夠在/etc/rc.d/rc.local中加入如下代碼: if [-x /etc/fw/rule]; then /etc/fw/sule; fi; 這樣每次啓動都執行該規則腳本,若是用這種方法,建議NTSYSV中中止IPTABLES. 

相關文章
相關標籤/搜索