前言
一個局域網(wǎng)中旧困,主機之間互聯(lián)盯捌,其中只有一臺主機可以上網(wǎng)鉴嗤,其他主機想要上網(wǎng)怎么辦貌夕?答:使用SNAT痊臭。
情景模擬
有主機A辛辨,eth0的IP為內(nèi)網(wǎng)IP:192.168.56.101防泵,eth1為公網(wǎng)IP:120.77.36.222脱盲。
有主機B乾蛤,eth0的IP為內(nèi)網(wǎng)IP:192.168.56.102每界。
主機A可以訪問外網(wǎng)捅僵,主機B和主機A在同一個局域網(wǎng)。下面我們進行配置眨层,讓主機B也可以上網(wǎng)庙楚。
數(shù)據(jù)包流向
發(fā)送數(shù)據(jù)包
B發(fā)送數(shù)據(jù)包時,A也就是NAT主機趴樱,分析數(shù)據(jù)包表頭馒闷,將此數(shù)據(jù)包轉(zhuǎn)到可以連接公網(wǎng)的IP上去。由于私有IP與公有IP不能互通伊佃,A會通過iptables的NAT table內(nèi)的Postrounting鏈將數(shù)據(jù)包表頭偽裝成A的公網(wǎng)IP窜司,并且將這兩個不同來源的數(shù)據(jù)包對應關(guān)系寫入暫存內(nèi)存中,然后將數(shù)據(jù)包傳送出去航揉。此時傳到互聯(lián)網(wǎng)的這個數(shù)據(jù)包塞祈,已經(jīng)表現(xiàn)為來自公網(wǎng)IP,而非來自局域網(wǎng)帅涂。
接收響應包
當互聯(lián)網(wǎng)把數(shù)據(jù)響應給B時议薪,會首先進入NAT主機A,A分析數(shù)據(jù)包的序號媳友,對比剛剛記錄到內(nèi)存中的數(shù)據(jù)斯议,由于發(fā)現(xiàn)該數(shù)據(jù)包為后端主機之前傳送出去的,因此在NAT Prerouting鏈中醇锚,會將目標IP修改成為后端主機哼御,即B的IP,然后發(fā)現(xiàn)目標已經(jīng)不是A的公網(wǎng)IP焊唬,開始通過路由分析恋昼,將數(shù)據(jù)包傳送到A的局域網(wǎng)接口,再傳送到最終目標192.168.56.102上去赶促。
iptables小班
snat的配置液肌,主要用到iptables命令,之前在《CentOS7中firewall的使用》簡單提過iptables鸥滨,今天再認真學習一下嗦哆。
主要參考文檔:
Basic iptables howto
iptables詳解
ipatebles詳解(1):iptales概念
iptables命令
25個iptables常用示例
Linux防火墻iptables學習筆記(三)iptables命令詳解和舉例
歷史
防火墻,其實說白了講婿滓,就是用于實現(xiàn)Linux下訪問控制的功能的老速,它分為硬件的或者軟件的防火墻兩種。無論是在哪個網(wǎng)絡中凸主,防火墻工作的地方一定是在網(wǎng)絡的邊緣烁峭。而我們的任務就是需要去定義到底防火墻如何工作,這就是防火墻的策略,規(guī)則约郁,以達到讓它對出入網(wǎng)絡的IP、數(shù)據(jù)進行檢測但两。
iptables的前身叫ipfirewall (內(nèi)核1.x時代)鬓梅,這是一個作者從freeBSD上移植過來的,能夠工作在內(nèi)核當中的谨湘,對數(shù)據(jù)包進行檢測的一款簡易訪問控制工具绽快。但是ipfirewall工作功能極其有限(它需要將所有的規(guī)則都放進內(nèi)核當中,這樣規(guī)則才能夠運行起來紧阔,而放進內(nèi)核坊罢,這個做法一般是極其困難的)。當內(nèi)核發(fā)展到2.x系列的時候擅耽,軟件更名為ipchains活孩,它可以定義多條規(guī)則,將他們串起來乖仇,共同發(fā)揮作用憾儒,而現(xiàn)在,它叫做iptables乃沙,可以將規(guī)則組成一個列表起趾,實現(xiàn)絕對詳細的訪問控制功能。
原理
五個關(guān)卡
iptables工作在用戶空間中警儒,是定義規(guī)則的工具训裆,本身并不算是防火墻。它定義的規(guī)則蜀铲,可以讓內(nèi)核空間中的netfilter來讀取边琉,并且實現(xiàn)讓防火墻工作。netfilter的架構(gòu)就是在整個網(wǎng)絡流程的若干位置設置一些關(guān)卡(HOOK)蝙茶,而在每個關(guān)卡上登記了一些規(guī)則艺骂,所以這些關(guān)卡的術(shù)語規(guī)則鏈。
在內(nèi)核空間中隆夯,netfilter選擇了5個位置钳恕,來作為控制的關(guān)卡,專業(yè)點叫做規(guī)則鏈蹄衷。朱雙印大神的博客中給出了直觀的圖像:
根據(jù)上圖忧额,我們能夠想象出某些常用場景中,報文的流向:
到本機某進程的報文:PREROUTING --> INPUT
由本機轉(zhuǎn)發(fā)的報文:PREROUTING --> FORWARD --> POSTROUTING
由本機的某進程發(fā)出報文(通常為響應報文):OUTPUT --> POSTROUTING
五個規(guī)則鏈的作用如下:
INPUT鏈:處理輸入數(shù)據(jù)包愧口。
OUTPUT鏈:處理輸出數(shù)據(jù)包睦番。
PORWARD鏈:處理轉(zhuǎn)發(fā)數(shù)據(jù)包。
PREROUTING鏈:用于目標地址轉(zhuǎn)換(DNAT)。
POSTOUTING鏈:用于源地址轉(zhuǎn)換(SNAT)托嚣。
表的概念
我們再想想另外一個問題巩检,我們對每個"鏈"上都放置了一串規(guī)則,但是這些規(guī)則有些很相似示启,比如兢哭,A類規(guī)則都是對IP或者端口的過濾,B類規(guī)則是修改報文夫嗓,那么這個時候迟螺,我們是不是能把實現(xiàn)相同功能的規(guī)則放在一起呢,必須能的舍咖。
我們把具有相同功能的規(guī)則的集合叫做"表"矩父,所以說,不同功能的規(guī)則排霉,我們可以放置在不同的表中進行管理窍株,而iptables已經(jīng)為我們定義了4種表,每種表對應了不同的功能郑诺,而我們定義的規(guī)則也都逃脫不了這4種功能的范圍夹姥,所以,學習iptables之前辙诞,我們必須先搞明白每種表的作用辙售。
iptables為我們提供了如下規(guī)則的分類,或者說飞涂,iptables為我們提供了如下"表":
- filter表:負責過濾功能旦部,防火墻;內(nèi)核模塊:iptables_filter
- nat表:network address translation较店,網(wǎng)絡地址轉(zhuǎn)換功能士八;內(nèi)核模塊:iptable_nat
- mangle表:拆解報文,做出修改梁呈,并重新封裝的功能婚度;iptable_mangle
- raw表:關(guān)閉nat表上啟用的連接追蹤機制;iptable_raw
也就是說官卡,我們自定義的所有規(guī)則蝗茁,都是這四種分類中的規(guī)則,或者說寻咒,所有規(guī)則都存在于這4張"表"中哮翘。
數(shù)據(jù)包流向
可以將數(shù)據(jù)包通過防火墻的流程總結(jié)為下圖:
我們在寫iptables規(guī)則的時候,要時刻牢記這張路由次序圖毛秘,靈活配置規(guī)則饭寺。
規(guī)則
規(guī)則:根據(jù)指定的匹配條件來嘗試匹配每個流經(jīng)此處的報文阻课,一旦匹配成功,則由規(guī)則后面指定的處理動作進行處理艰匙。規(guī)則由匹配條件和處理動作組成限煞。
匹配條件分為基本匹配條件與擴展匹配條件:
基本匹配條件包括源地址Source IP和目標地址 Destination IP。
擴展匹配條件包括源端口Source Port员凝,目標端口Destination Port等等晰骑。
動作也可以分為基本動作和擴展動作,此處列出一些常用動作:
ACCEPT:允許數(shù)據(jù)包通過绊序。
DROP:直接丟棄數(shù)據(jù)包,不給任何回應信息秽荞,這時候客戶端會感覺自己的請求泥牛入海了骤公,過了超時時間才會有反應。
REJECT:拒絕數(shù)據(jù)包通過扬跋,必要時會給數(shù)據(jù)發(fā)送端一個響應的信息阶捆,客戶端剛請求就會收到拒絕的信息。
SNAT:源地址轉(zhuǎn)換钦听,解決內(nèi)網(wǎng)用戶用同一個公網(wǎng)地址上網(wǎng)的問題洒试。
MASQUERADE:是SNAT的一種特殊形式,適用于動態(tài)的朴上、臨時會變的ip上垒棋。
DNAT:目標地址轉(zhuǎn)換,解決外網(wǎng)用戶訪問內(nèi)網(wǎng)的問題痪宰。
REDIRECT:在本機做端口映射叼架。
LOG:在/var/log/messages文件中記錄日志信息,然后將數(shù)據(jù)包傳遞給下一條規(guī)則衣撬,也就是說除了記錄以外不對數(shù)據(jù)包做任何其他操作乖订,仍然讓下一條規(guī)則去匹配。
命令詳解
命令格式:
iptables [選項] [參數(shù)]
選項包括:
-t:指定要操縱的表具练;
-A:向規(guī)則鏈中添加條目乍构;
-D:從規(guī)則鏈中刪除條目;
-I:向規(guī)則鏈中插入條目扛点;
-R:替換規(guī)則鏈中的條目哥遮;
-L:顯示規(guī)則鏈中已有的條目;
-F:清楚規(guī)則鏈中已有的條目占键;
-Z:清空規(guī)則鏈中的數(shù)據(jù)包計算器和字節(jié)計數(shù)器昔善;
-N:創(chuàng)建新的用戶自定義規(guī)則鏈;
-P:定義規(guī)則鏈中的默認目標畔乙;
-h:顯示幫助信息君仆;
-p:指定要匹配的數(shù)據(jù)包協(xié)議類型;
-s:指定要匹配的數(shù)據(jù)包源ip地址;
-d:指定要匹配的數(shù)據(jù)包目標ip地址返咱;
-j:指定要跳轉(zhuǎn)的目標钥庇;
-i:指定數(shù)據(jù)包進入本機的網(wǎng)絡接口(網(wǎng)卡);
-o:指定數(shù)據(jù)包離開本機的網(wǎng)絡接口(網(wǎng)卡)咖摹;
--sport:匹配來源端口號评姨;
--dport:匹配目標端口號。
命令選項輸入順序:
iptables -t 表名 <-A/I/D/R> 規(guī)則鏈名 [規(guī)則號] <-i/o 網(wǎng)卡名> -p 協(xié)議名 <-s 源IP/源子網(wǎng)> --sport 源端口 <-d 目標IP/目標子網(wǎng)> --dport 目標端口 -j 動作
實例
1萤晴、清除已有iptables規(guī)則
iptables -F
iptables -X
iptables -Z
2吐句、開放指定的端口
iptables -A INPUT -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT #允許本地回環(huán)接口(即允許本機訪問本機)
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT #允許已建立的或相關(guān)連的通行
iptables -A OUTPUT -j ACCEPT #允許所有本機向外的訪問
iptables -A INPUT -p tcp --dport 22 -j ACCEPT #允許訪問22端口
iptables -A INPUT -p tcp --dport 80 -j ACCEPT #允許訪問80端口
iptables -A INPUT -p tcp --dport 21 -j ACCEPT #允許ftp服務的21端口
iptables -A INPUT -p tcp --dport 20 -j ACCEPT #允許FTP服務的20端口
iptables -A INPUT -j REJECT #禁止其他未允許的規(guī)則訪問
iptables -A FORWARD -j REJECT #禁止其他未允許的規(guī)則訪問
3、屏蔽IP
iptables -I INPUT -s 123.45.6.7 -j DROP #屏蔽單個IP的命令
iptables -I INPUT -s 123.0.0.0/8 -j DROP #封整個段即從123.0.0.1到123.255.255.254的命令
iptables -I INPUT -s 124.45.0.0/16 -j DROP #封IP段即從123.45.0.1到123.45.255.254的命令
iptables -I INPUT -s 123.45.6.0/24 -j DROP #封IP段即從123.45.6.1到123.45.6.254的命令是
4店读、查看已添加的iptables規(guī)則
iptables -L -n -v
5嗦枢、刪除已添加的iptables規(guī)則
將所有iptables以序號標記顯示,執(zhí)行:
iptables -L -n --line-numbers
比如要刪除INPUT里序號為8的規(guī)則屯断,執(zhí)行:
iptables -D INPUT 8
snat具體配置
主機A
接收數(shù)據(jù)包
允許接收局域網(wǎng)網(wǎng)卡的數(shù)據(jù)包
sudo iptables -I INPUT -i eth0 -j ACCEPT
或者
sudo iptables -P INPUT ACCEPT
開啟路由功能
sudo echo 1 > /proc/sys/net/ipv4/ip_forward
如果報錯:-bash: /proc/sys/net/ipv4/ip_forward: Permission denied
那就切換到root用戶:
sudo -i
echo 1 > /proc/sys/net/ipv4/ip_forward
要想永久有效文虏,還要把/etc/sysctl.conf文件里邊的net.ipv4.ip_forward的值改為1。
偽裝數(shù)據(jù)包
sudo iptables -t nat -A POSTROUTING -s 192.168.56.102 -o eth1 -j MASQUERADE
或者用SNAT直接修改IP數(shù)據(jù)包的表頭來源IP
sudo iptables -t nat -A POSTROUTING -s 192.168.56.102 -o eth1 -j SNAT --to 192.168.56.101
如果需要支持整個網(wǎng)段:
sudo iptables -t nat -A POSTROUTING -s 192.168.56.0/24 -o eth1 -j SNAT --to 192.168.56.101
如果需要支持連續(xù)IP:
sudo iptables -t nat -A POSTROUTING -m iprange --src-range 192.168.56.102-192.168.56.104 -o eth1 -j SNAT --to 192.168.56.101
注意:
- 親測以上所有命令中的
-o eth1
可以省略殖演,所以氧秘,在分不清哪個網(wǎng)卡是內(nèi)網(wǎng)哪個網(wǎng)卡是外網(wǎng)的情況下,直接省略即可趴久。 - 如果想要允許所有IP丸相,
-s 192.168.56.0/24
也可以省略。 -
-j SNAT --to 192.168.56.101
可以換成-j SNAT --to 120.77.36.222
朋鞍。 -
-j SNAT --to 120.77.36.222
建議換成-j MASQUERADE
已添,尤其在外網(wǎng)IP非固定的情況下。 - 綜上滥酥,最簡單的萬能SNAT命令為
sudo iptables -t nat -A POSTROUTING -j MASQUERADE
查看與刪除
查看NAT表鏈規(guī)則
sudo iptables -t nat -nL --line-number
刪除POSTROUTING第一條規(guī)則
sudo iptables -t nat -D POSTROUTING 1
重啟后依舊生效
1更舞、保存規(guī)則
sudo chmod a+w -R /opt
sudo iptables-save > /opt/iptables.rules
2、手動導入規(guī)則
sudo iptables-restore < /opt/iptables.rules
3坎吻、開機自動導入規(guī)則
在ubuntu下要把一個程序加入開機啟動缆蝉,一般可以通過修改rc.local來完成,但ubuntu下有兩個rc.local文件瘦真,分別是/etc/rc.local和/etc/init.d/rc.local刊头。因為/etc/init.d/rc.local調(diào)用了/etc/rc.local,所以我們的開機腳本最好直接寫入/etc/rc.local诸尽,寫在exit 0之前即可原杂。
sudo vim /etc/rc.local
在exit 0之前添加:
/sbin/iptables-restore < /opt/iptables.rules
主機B
centos
如果是centos,那么配置ifcfg文件
sudo vim /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
ONBOOT=yes
IPADDR=192.168.56.102
NETMASK=255.255.255.0
GATEWAY=192.168.56.101
然后service network restart
ubuntu
如果是ubuntu您机,那么配置interfaces文件
sudo vim /etc/network/interfaces
auto lo
iface lo inet loopback
auto em1
iface em1 inet static
address 192.168.56.102
netmask 255.255.255.0
gateway 192.168.56.101
然后sudo /etc/init.d/networking restart
總之穿肄,B主機配置的關(guān)鍵在于網(wǎng)關(guān)年局,網(wǎng)關(guān)要設置成主機A的內(nèi)網(wǎng)IP。
請問咸产,網(wǎng)關(guān)不設置成主機A的內(nèi)網(wǎng)IP可以嗎矢否?可以,那就是另外一種稍微復雜的設置方法了脑溢。
此時僵朗,使用主機B,已經(jīng)可以ping通外網(wǎng)的IP了屑彻。但是ping域名會提示“ping: unknown host”验庙。
DNS配置
方法一
1、編輯resolv.conf
sudo vim /etc/resolv.conf
社牲,添加nameserver的配置
nameserver 180.76.76.76
nameserver 223.6.6.6
上面的兩個IP地址壶谒,分別是百度和阿里的公共DNS。
2膳沽、測試
ping www.baidu.com
3、不過让禀,這種方法在重啟之后會失效挑社。想要永久生效,還需要編輯base文件巡揍。
sudo vim /etc/resolvconf/resolv.conf.d/base
痛阻,添加:
nameserver 180.76.76.76
nameserver 223.6.6.6
方法二
1、編輯interfaces
sudo vim /etc/network/interfaces
2腮敌、添加nameserver的配置
dns-nameserver 180.76.76.76 223.5.5.5
3阱当、重啟服務器
sudo reboot
實際上,重啟后的dns配置會寫入到resolv.conf中糜工。
4弊添、測試
ping www.baidu.com
結(jié)語
至此,snat完美配置成功捌木!在這個過程中油坝,順帶學習了一下iptables,收獲滿滿刨裆。感覺iptables和route有很大關(guān)系澈圈,但是在配置過程中沒有用到route。書簽中有關(guān)于route的文檔帆啃,用到的時候再深入學習瞬女。