iptables學習筆記:埠轉發命令優化
大約一年前,在一個x86板子系統上實現埠轉發。現在又出現問題,又要抽空整理整理。雖說是另一同事在另一專案中遇到的,但中秋節前我出差之前老大叫我幫忙協助該同事排查,出差時該同事又call我,出差後老大又叫我繼續協助,所以是我的鍋,最終還是逃不掉的。這也使得自己對自己做(過)的事不敢懈怠,因為不知道哪一天又回到自己手中。甩鍋能力,還有待提高。
一、應用場合
一臺X86板子安裝linux系統,作為“工作站”,既提供telnet服務(23埠)、web服務(80埠)、ssh服務(22埠),又提供h.264編碼、h.264解碼,又提供jpeg編碼、jpeg解碼,還提供大容量硬碟資料儲存、視訊顯示,而且還提供無線AP接入。該工作站有2個網絡卡,eth1連線裝置,外部PC通過eth0訪問工作站和裝置。裝置既提供telnet服務(23埠)、web服務(80埠)、ssh服務(22埠),又提供視訊源,還有其它socket埠提供內部工具通訊使用。工作站需要接入若干臺裝置。
簡化網路拓撲圖如下:
PC <----------->[工作站 eth0]-[工作站 eth1] <-----(交換機)-----> [裝置 eth0]-[裝置 eth1] <------> (無連線)
172.18.44.142 172.18.44.44 100.100.100.44 100.100.100.144 172.18.44.X
PC的IP為172.18.44.142,工作站eth0的IP是172.18.44.44,兩者處於同一網段:172.18.0.0/16。
工作站eth1的IP是100.100.100.44,通過交換機連線到裝置的eth0,裝置eth0的IP為100.100.100.144,兩者網段為100.100.100.0/24,裝置預設閘道器為100.100.100.44(即工作站的eth1的IP地址)。圖中列出三個裝置,但這裡只選擇第一個做說明。
另外,裝置還有另一個網絡卡eth1,有實際用途,但這裡連線任何網路,但該網絡卡IP卻和PC、工作站eth0處於同一網段。——是的,現實就這麼殘酷!雖然我想不明白為何PC和裝置都處於同一網段了,還要通過一個“工作站”來做轉發訪問。但就技術層面而言,還是可以研究一下的。
當初實施時,使用“埠轉發”這一機制實現。即對外只提供工作站eth0的IP(因為只有該IP對客戶可見),通過不同的埠號對不同的裝置(不同埠)進行訪問,但又要排除工作站本身的埠。比如工作站172.18.44.44的80埠是工作站web服務,81埠轉發到第一臺連線裝置的web服務,82轉發到第二臺的web服務,等等。其它類似。
這一應用場景,類似於在外網環境中通過某一方式訪問內網資料。
二、舊版本
以前版本使用的命令如下:
iptables -t nat -A PREROUTING -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to-destination 100.100.100.144:23
iptables -t nat -A POSTROUTING -d 100.100.100.144 -p tcp --dport 23 -j SNAT --to 172.18.44.44
如上所述,該命令可以在PC端通過工作站的IP地址外加一個指定的埠號2324,對100.100.100.144這臺裝置進行訪問telnet訪問。
三、遇到問題
舊版本命令存在一個問題。當裝置存在另一個網口,且該網口和PC端IP網段相同的情況時(如文中網路拓撲所示),就會出現問題,無法訪問。因為裝置端收到的資料包源地址為172.18.0.0/16網段,恰好這個裝置存在一條172.18.0.0/16網段的路由(eth1),無法向eth0傳送資料(因為eth0走的是100.100.100.0/24網段)。如果不存在這種情況,則一切正常。為什麼呢?因為裝置有預設閘道器,而裝置預設閘道器為100.100.100.0/24網段,當資料包沒有路由匹配時,就走預設閘道器,所以,在沒有eth1裝置或者eth1網段與PC端網段不相同情況下,都會走預設閘道器——所以一直沒有問題,直到現在。四、改進版本
其實,舊版本的源IP並沒有進行轉換(或稱“偽裝”),還是172.18.0.0/24網段的,只要在裝置上將來自eth0的資料包源IP地址修改為工作站的eth1地址,就是100.100.100.0/24網段,就能通過eth0出去了。命令如下:
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.144 -p tcp --dport 23 -j SNAT --to 100.100.100.44
與舊版本命令對比,只是將PSTROUTING鏈的SNAT改為工作站的eth1網絡卡的IP地址,其它沒變化。——這是當初沒有繼續深入研究導致的。現將命令翻譯成白話(可與下文iptables表做參照),如下:
第一條命令:插入一條PREROUTING鏈(用於改目的地址,即DNAT),如果是從eth0進來(-i eth0)的IP為172.18.44.44(因為用-d,所以是目的IP)且是tcp協議埠為2324的資料包,則把它的目的IP轉換為100.100.100.144:2323。
第二條命令:插入一條PSOTROUTING鏈(用於改源地址,即SNAT),如果是從eth1出去(-o eth1)的IP為100.100.100.144(因為用-d,所以是目的IP)且是tcp協議埠為23的資料包,則把它的源IP轉換為100.100.100.44。
第二條命令指定了具體的IP地址及埠號,由於此時埠已經一致不須轉換,可以去掉。另外可以使用IP段來簡化。得到最終版本如下:
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44
下面是工作站的iptables表:
[email protected]:~# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere 172.18.44.44 tcp dpt:2324 to:100.100.100.144:23
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- anywhere 100.100.100.0/24 to:100.100.100.44
另外,iptables引數使用-d指定目的地址/網段,用-s表示源地址/網段。所以,在POSTROUTING鏈中可以用-s指定源IP網段,其它引數不變,如下:
iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -p tcp --dport 2324 -j DNAT --to 100.100.100.144:23
iptables -t nat -A POSTROUTING -o eth1 -s 172.18.0.0/16 -j SNAT --to 100.100.100.44 // 用-s將“源IP”為172.18網段的轉換為100.100.100.44
命令對應的iptables表如下:
[email protected]:test# iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere 172.18.44.44 tcp dpt:2324 to:100.100.100.144:23
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
SNAT all -- 172.18.0.0/16 anywhere to:100.100.100.44
這兩個iptables表,一個是匹配destination,一個是匹配source,但都可以達到相同的目的。這也體現了iptables語法自由的一面。
五、小結
這裡給出經過測試的內外網互訪iptables命令示例。 “外網訪問內網”:iptables -t nat -A PREROUTING -i eth0 -d 172.18.44.44 -j DNAT --to 100.100.100.144
iptables -t nat -A POSTROUTING -o eth1 -d 100.100.100.0/24 -j SNAT --to 100.100.100.44
“內網訪問外網”:
iptables -t nat -A POSTROUTING -o eth0 -s 100.100.100.0/24 -j MASQUERADE
此處僅做命令備份,不展開討論。可以參考後續文章。
六、其它
本文為“外網”訪問“內網”這一應用場合做了實踐,所有命令都通過測試,測試方式是在PC上使用telnet命令連線工作站的eth0地址的2324埠來訪問裝置的telnet服務,同時在工作站上抓包分析,有一定事實依據。
網上有很多資料介紹iptables,有部分存在誤導性,做參考時注意甄別。
由於應用場合特殊性(見本文開頭介紹),無法實現純粹的IP級別的轉發。但這缺點也是經常被領導點評的。我認知中,交換機只做二級交換功能,路由器是做路由功能的。一個大而全的東西,看看什麼時候可實現吧。
參考資料:
李遲 2016.9.24 週六
相關推薦
iptables學習筆記:埠轉發命令優化
大約一年前,在一個x86板子系統上實現埠轉發。現在又出現問題,又要抽空整理整理。雖說是另一同事在另一專案中遇到的,但中秋節前我出差之前老大叫我幫忙協助該同事排查,出差時該同事又call我,出差後老大又叫我繼續協助,所以是我的鍋,最終還是逃不掉的。這也使得自己對自己做(過)的
學習筆記:docker基礎命令
docker 容器與映象區別 映象一個docker映象可以構建於另一個docker映象之上,它們層疊關係可以是多層。第1層映象層為基礎映象,其他層映象(除了最頂層)為父層映象,這些映象繼承他們父層映象所有屬性和設定,並在dockerfile中新增自己配置 容器它會在所有映象層
iptables學習筆記:使用NAT實現簡單的無線AP
之前使用的是無線路由讓手機上網。學習了iptables後,嘗試在非openwrt系統的Linux上實現相同功能。本文簡單記錄一下。 手上有塊X86的板子,上面安裝了Linux系統。幾個月前研究了WIFI並實現了一個無線AP,最近又重新拾起了iptables,於是順便讓這個A
學習筆記:Linux系統網絡命令常用匯總
services 統計 ant 查看本機 modprobe tun 所有 自動 使用 在Linux系統,DNS 主機 IP 的設定在 /etc/resolv.conf 文件裏確認Linux 核心是否捕捉到網絡卡:指令 demesg | grep -in eth或者透過
Kafka學習筆記:Kafka命令列工具
Kafka命令列工具 啟動Kafka kafka-server-start.sh /opt/software/kafka_2.11-1.1.0/config/server.properties & 檢視所有Topic列表 kafka-topics.sh --z
Docker學習筆記:Docker 埠對映
# Find IP address of container with ID <container_id> 通過容器 id 獲取 ip $ sudo docker inspect <container_id&g
Docker學習筆記:Docker 基礎用法和命令幫助
Usage of docker: --api-enable-cors=false Enable CORS headers in the remote API # 遠端 API 中開啟 CORS
Docker學習筆記:Docker容器常用命令
容器是映象的一個執行例項。兩者不同的是,映象是靜態的只讀檔案,而容器帶有執行時需要的可寫檔案層。 一、建立容器 1、新建容器 &nb
學習筆記:瀏覽器渲染優化——關鍵渲染路徑
幀 但瀏覽器還需要對每幀進行處理,所以要在10ms內完成所有任務並及時渲染每幀。 渲染樹(render tree) 只有實際上會顯示在網頁上的元素,才會進入渲染樹 它和DOM樹很
Linux學習筆記:存儲管理
linux 磁盤管理 Linux系統中所有的硬件設備都是通過文件的方式來表現和使用的,我們將這些文件稱為設備文件,在Linux下的/dev目錄中有大量的設備文件,根據設備文件的不同,又分為字符設備文件和塊設備文件。字符設備文件的存取是以字符流的方式來進行的,一次傳送一個字符。常見的有打印
學習筆記:javascript內置對象:數組對象
b- sort splice 刪除 分隔 href 結果 join() strong 1.數組對象的創建 1.設置一個長度為0的數組 var myarr=new array(); 2.設置一個長度為n的數組 var myarr=new arr(n); 3.聲明一個
學習筆記:javascript內置對象:日期對象
etsec sel mil cond ava com 描述 學習筆記 asp 2.日期對象的常用函數 2.日期對象的常用函數 Date 對象方法 方法描述 Date() 返回當日的日期和時間。 getDate() 從 Date 對象返回一個月
Linux學習筆記:btrfs
可擴展性 linux btrfs Technical Preview, 技術預覽版 BtrFS(B-tree文件系統,又稱為Butter FS或Better FS),2007由oracle開源後,得到了IBM、intel等廠商的大力支持,其目標計劃是替代linux目前的ext3/4,成為下
Linux學習筆記:rpm程序包管理
源代碼 rpm 程序包 以CentOS為例,rpm程序包管理器的相關內容如下:CentOS的程序包管理器: 程序包的命名規則: 源代碼包: software_name-VERSION.tar.gz VERSION:major.mino
kafka學習筆記:知識點整理
一個 eight true med 分組 pos 間接 fig ges 一、為什麽需要消息系統 1.解耦: 允許你獨立的擴展或修改兩邊的處理過程,只要確保它們遵守同樣的接口約束。 2.冗余: 消息隊列把數據進行持久化直到它們已經被完全處理,通過這一方式規避了數據
Emacs學習筆記:移動
size exp http spc ssi 參考 put kill ati 參考網址:https://www.emacswiki.org/emacs/NavigatingParentheses Navigating over balanced expressions C
Linux學習筆記:OSI七層模型
路由器 交換機 比特流 兼容性 linux OSI七層模型: OSI(Open System Interconnection,開放系統互連)七層網絡模型稱為開放式系統互聯參考模型 ,是一個邏輯上的定義,一個規範,它把網絡從邏輯上分為了7層。每一層都有相關、相對應的物理設備,比如路由器
Android學習筆記:超能RecyclerView組件使用總結
popu bin view設置 and col cas mda rac data 個人認為 RecyclerView組件確實值得學習並用到我們的項目中去,前面學了相關的內容。今天再補充一些相關的東東。 1,實現對RecyclerView中的數據進行加入和刪除操作。
python學習筆記:字符串
修改 結束 () 添加 cnblogs hid src 處理 linu string類型由多個字符組成,可以把字符串看成一個整體,也可以取得字符串中的任何一個部分。 函數len() 返回字符串的長度 >>> address = ‘www.baidu.c
MVC學習筆記:MVC實現用戶登錄驗證ActionFilterAttribute用法並實現統一授權
重置 ids filter .config detail close login out gif 在項目下新建一個文件夾來專門放過濾器類,首先創建一個類LoginFilter,這個類繼承ActionFilterAttribute。用來檢查用戶是否登錄和用戶權限。: u