iptables路由轉發及控制

基於狀態的iptables(就是一個包過濾的條件)

包過濾的條件:
如: 
-p 協議  
-sport/dport xxx   
-s/-d xxxx   
-m state --state 狀態


若是按照tcp/ip來劃分鏈接狀態,有11種之多
但iptables裏只有4種狀態;ESTABLISHED、NEW、RELATED及INVALID

這兩個分類是兩個不相干的定義。例如在TCP/IP標準描述下UDP及ICMP數據包是沒有鏈接狀態的,但在state模塊的描述下,任何數據包都有鏈接狀態。


    1、ESTABLISHED
   
    (1)與TCP數據包的關係:首先在防火牆主機上執行SSH Client,而且對網絡上的SSH服務器提出服務請求,而這時送出的第一個數據包就是服務請求的數據包,若是這個數據包可以成功的穿越防火牆,那麼接下來SSH Server與SSH Client之間的全部SSH數據包的狀態都會是ESTABLISHED。

    (2)與UDP數據包的關係:假設咱們在防火牆主機上用firefox應用程序來瀏覽網頁(經過域名方式),而瀏覽網頁的動做須要DNS服務器的幫助才能完成,所以firefox會送出一個UDP數據包給DNS Server,以請求名稱解析服務,若是這個數據包可以成功的穿越防火牆,那麼接下來DNS Server與firefox之間的全部數據包的狀態都會是ESTABLISHED。
    (3)與ICMP數據包的關係:假設咱們在防火牆主機ping指令來檢測網絡上的其餘主機時,ping指令所送出的第一個ICMP數據包若是可以成功的穿越防火牆,那麼接下來剛纔ping的那個主機與防火牆主機之間的全部ICMP數據包的狀態都會是ESTABLISHED。
    由以上的解釋可知,只要第一個數據包可以成功的穿越防火牆,那麼以後的全部數據包(包含反向的全部數據包)狀態都會是ESTABLISHED。

    2、NEW
   
    首先咱們知道,NEW與協議無關,其所指的是每一條鏈接中的第一個數據包,假如咱們使用SSH client鏈接SSH server時,這條鏈接中的第一個數據包的狀態就是NEW。

    3、RELATED

    RELATED狀態的數據包是指被動產生的數據包。並且這個鏈接是不屬於如今任何鏈接的。RELATED狀態的數據包與協議無關,只要迴應回來的數據包是由於本機送出一個數據包致使另外一個鏈接的產生,而這一條新鏈接上的全部數據包都是屬於RELATED狀態的數據包。

    4、INVALID

    INVALID狀態是指狀態不明的數據包,也就是不屬於以上三種狀態的封包。凡是屬於INVALID狀態的數據包都視爲惡意的數據包,所以全部INVALID狀態的數據包都應丟棄掉,匹配INVALID狀態的數據包的方法以下:
    iptables -A INPUT -p all -m state INVALID -j DROP
    咱們應將INVALID狀態的數據包放在第一條。


                    |
            隨機        |     80  web
            --------- |--》        
        client            |       server        
            《--------- |--
            隨機        |     80    
                    |

client訪問server過去
第一個數據包(new狀態),若是拒絕,那麼後續包都會被拒絕(由於後面來的都會是第一個,都爲new狀態)
第一個數據包若是容許過去,那麼後續包的狀態爲established



server返回給client
返回的全部包都爲established



例1:
有下面兩臺機

        10.1.1.2        10.1.1.3
         client              server        



10.1.1.2是能夠ssh訪問10.1.1.3,也能夠elinks訪問10.1.1.3

1,在10.1.1.3上
iptables -P INPUT DROP
iptables -P OUTPUT DROP
這裏就把雙鏈都關掉,10.1.1.2任何訪問都過不來了

2,
按之前的作法
在10.1.1.3上容許別人ssh進來
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
在10.1.1.3上容許別人elinks進來
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT

或者把上面四條合下面兩條
iptables -A INPUT -p tcp -m multiport  --dport 22,80 -j ACCEPT
iptables -A OUTPUT -p tcp -m multiport  --sport 22,80 -j ACCEPT


把上面的兩條再換成
iptables -A INPUT -p tcp -m multiport  --dport 22,80 -j ACCEPT
iptables -A OUTPUT -p tcp -m state --state established -j ACCEPT
(後面一句能夠翻譯成tcp協議的鏈接只要你進得來,你就回得去)
(不管他是用哪一個隨機端口訪問進來的;由於只要能進來,那麼後續的包都屬於ESTABLISHED狀態)




例2:
有些服務器,可能但願客戶端ping不通此服務器,可是此服務器能夠ping通客戶端(前提是客戶端沒有防火牆限制)

方法一:
在服務器上把/proc/sys/net/ipv4/icmp_echo_ignore_all的值改成1
臨時修改兩種方式:

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

sysctl -w net.ipv4.icmp_echo_ignore_all=1

永久修改
# vim /etc/sysctl.conf    --加上下面一句
net.ipv4.icmp_echo_ignore_all = 1
# sysctl -p    --使用此命令讓其生效



方法二:
經過iptables的狀態來實現
有下面兩臺機

10.1.1.2        10.1.1.3

實現10.1.1.3這個IP能ping通全部人.但全部人不能ping通10.1.1.3

                    |
                --------------》|  ------->
          client        |  server        
              10.1.1.2        |  10.1.1.3
                  <-------------|  <--------   


                   NEW       ESTABLISHED
            INPUT       拒絕       容許
            OUTPUT       容許       容許


1,在10.1.1.3上
iptables -P INPUT DROP
iptables -P OUTPUT DROP
這裏就把雙鏈都關掉,10.1.1.2任何訪問都過不來了


2,在10.1.1.3上
iptables -A INPUT -p icmp -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p icmp -m state --state NEW,ESTABLISHED -j ACCEPT

--重點是INPUT那條不能容許NEW狀態的;
--注意第二步的第二條(也就是output這條),若是隻寫了NEW狀態,那麼10.1.1.3ping全部人,都只能通第一個包;加上ESTABLISHED狀態,全部包都能通    



例3:
有一個服務器,搭建了http,ftp(主動和被動都要支持,被動端口爲3000-3005)兩個服務(須要開放給全部人訪問),還要開放ssh和ping(但只開放給一個管理ip訪問,好比此IP爲10.1.1.X),其它任何進來的訪問都拒絕
但此服務器要出去訪問別的任何服務,本身的防火牆都要容許


需求一個一個的寫
iptables -P INPUT DROP
iptables -P OUTPUT DROP

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 80 -j ACCEPT

iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 21 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 20 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT

iptables -A INPUT -p tcp --dport 3000:3005 -j ACCEPT
iptables -A OUTPUT -p tcp --sport 3000:3005 -j ACCEPT 

iptables -A INPUT -p tcp --dport 22 -s 10.1.1.X -j ACCEPT
iptables -A OUTPUT -p tcp --sport 22 -d 10.1.1.X -j ACCEPT

iptables -A INPUT -p icmp -s 10.1.1.X -j ACCEPT
iptables -A OUTPUT -p icmp -d 10.1.1.X -j ACCEPT

iptables -A OUTPUT -p all -m state --state new,established,related -j ACCEPT
iptables -A INPUT -p all -m state --state established,related -j ACCEPT


需求綜合起來寫
iptables -P INPUT DROP
iptables -P OUTPUT DROP

iptables -A INPUT -p tcp -m mutliport --dport 80,21,20,3000,3001,3002,3003,3004,3005 -j ACCEPT

iptables -A INPUT -p tcp --dport 22  -s 10.1.1.X -j ACCEPT

iptables -A INPUT  -p icmp -s 10.1.1.X -j ACCEPT

iptables -A OUTPUT -p all -m state --state new,established,related -j ACCEPT
iptables -A INPUT -p all -m state --state established,related -j ACCEPT


=============================================================================


# 源A--B-->C目標



        A          B        

            交換機


        C          D


=============================================================================

路由
什麼是交換,什麼是路由,什麼是路由表?
交換是指同網絡訪問(兩臺機器連在同一個交換機上,配置同網段的不一樣ip就能夠直接通迅)
路由就是跨網絡訪問(路徑選擇)
路由表是記錄路由信息的表(能夠單路由表,也能夠多路由表)


            因特網   ---》  物聯網(互聯網+)
  (無數個網絡組成,因此從一個網絡到另外一個網絡,中間可能還要通過不少個網絡,必須要走路由)



咱們如今討論的是單路由表,你在linux下用route -n查看

# route -n
Kernel IP routing table
 路由表                  網關              子網掩碼                                             網卡類型
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.2.1     0.0.0.0         UG    0      0                        0 br0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0                      0 br0
169.254.0.0     0.0.0.0         255.255.0.0     U     1003   0                  0 br0
192.168.2.0     0.0.0.0         255.255.255.0   U     0      0                   0 br0
192.168.100.0   0.0.0.0         255.255.255.0   U     0      0                 0 virbr1
192.168.101.0   0.0.0.0         255.255.255.0   U     0      0                 0 virbr2
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0                 0 virbr0



問題1:按上面的路由表來看,若是我ping一個公網IP(如ping 14.215.177.38),應該怎麼走?
答案:
我在本機訪問一個IP,先看目標ip是否爲本地ip,若是是,則直接訪問本地;
若是不是,則找路由表裏是否有你訪問的網段,有的話則從這個路由條目後面指定的網卡出去;
若是路由表裏沒有你訪問的網段,則會找默認路由(也就是網關);
若是網關也沒有的話,則會報錯網絡不可達。


問題2:爲何route -n能看到這幾條路由(不一樣機器可能還不同)
答案:由於我對應的網卡有相關網段的ip,因此就會有對應的默認路由(好比個人機器br0網卡ip爲10.1.1.1/24,因此我默認就會有10.1.1.0     0.0.0.0         255.255.255.0   U     0      0        0 br0 這一條路由)


問題3:如何加網關和刪除網關,加網關有什麼要求?
route add default gw  x.x.x.x    --臨時加網關,立刻生效
route del default gw  x.x.x.x     --臨時刪網關,立刻生效
route add -net 4.4.4.0 netmask 255.255.255.0 dev eth1 --臨時加路由,立刻生效
route del  -net 4.4.4.0 netmask 255.255.255.0 dev eth1  --臨時刪除路由,立刻生效

永久加網關的方法
在網卡配置文件裏/etc/sysconfig/network-scripts/ifcfg-br0
加一句GATEWAY=x.x.x.x;而後重啓network服務生效


加網關只能加你已經有的路由網段裏的一個IP才行(ping不通此IP均可以)
加網關不須要指定子網掩碼(由於是已有的一個網段的ip,因此掩碼已經確認了)


問題4:若是你有br0:0這種子接口配置文件,那麼每一個文件裏都要寫一個網關嗎?
準確來講:一個路由表上能夠加多個網關,但只有一個生效(從上往下找,上面的優先生效;rhel6上面的網關無論通不通,都不會找下面的網關;centos7測試結果爲上面的網關不能通,則自動找下面的網關;上面的網關能夠通,則只會找上面的網關)。
但一臺linux是能夠作多路由表的,一個路由表一個有效網關,多路由表就是多個網關了。

# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.1.1.150       0.0.0.0         UG    0      0        0 br0
0.0.0.0         10.1.1.254       0.0.0.0         UG    0      0        0 br0
169.254.0.0     0.0.0.0         255.255.0.0     U     1010   0        0 br0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 br0
192.168.100.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr1
192.168.101.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr2
192.168.100.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0



問題5:一臺linux上若是有雙物理網卡,請問可不能夠兩個網卡配置同網段的不一樣IP呢?
假設個人    eth0 10.1.1.5/24        
    eth1 10.1.1.6/24    

10.1.1.0     0.0.0.0         255.255.255.0   U     0      0        0  eth0
10.1.1.0     0.0.0.0         255.255.255.0   U     0      0        0  eth1


若是兩個網卡同網段,則會有下面兩條路由
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth0
10.1.1.0        0.0.0.0         255.255.255.0   U     0      0        0 eth1

它會實現從兩張網卡進來的包,卻從一張網卡出去,問題就產生了


domain name--->IP---->MAC
       dns    arp

把ip比喻成 "張三的家"
把MAC比喻成 "xx省xx市xx區xx街道xx小區xx單元xx室"


實驗:
步驟一:
一個虛擬機,開兩個網卡,都爲橋接網絡,配置兩個IP,以下
# ip addr |grep eth 
2: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:41:e4:22 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.5/24 brd 10.1.1.255 scope global br0
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 52:54:00:39:c0:e6 brd ff:ff:ff:ff:ff:ff
    inet 10.1.1.6/24 brd 10.1.1.255 scope global eth1

步驟二:
在另外一臺機器(我這裏爲宿主機,ip爲10.1.1.1),分別ping上面兩個ip,獲得結果爲兩我的的MAC都爲第一個網卡的
# ip neigh |grep -E "^10.1.1.5 |^10.1.1.6 "
10.1.1.5 dev br0 lladdr 52:54:00:41:e4:22 REACHABLE
10.1.1.6 dev br0 lladdr 52:54:00:41:e4:22 REACHABLE


--按arp協議的原理,找誰誰纔會迴應mac地址(找張三,只能張三迴應;找李四,只能李四迴應)。而上面的實驗狀況能夠比喻成(張三,李四同一臺機器,就是一家人,找張三,張三回,找李四,也張三回)


步驟三:
# vim /etc/sysctl.conf        --加上
net.ipv4.conf.eth0.arp_ignore = 1        
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.eth1.arp_ignore = 1        
net.ipv4.conf.eth1.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2

# sysctl -p   --用此命令讓其生效

這幾個參數的目的就是把上面的一家人(張三又迴應張三也迴應李四)的狀況變成了本來的arp狀況(張三隻能回張三,李四隻能回李四)



最終的效果的是宿主機只能ping通10.1.1.5了,ping不通10.1.1.6了(這就對了,由於一臺機器雙網卡同網段會路由衝突)



=============================================================================


靜態路由
以下圖的實驗:
IP分配以下(掩碼假設全爲24位),作實驗的話使用iptables -F把全部的防火牆規則清空
1.1.1.0/24網段用default來模擬
2.2.2.0/24網段用default1來模擬
3.3.3.0/24網段用default2來模擬
4.4.4.0/24網段用default3來模擬

        


VM1          VM2              VM3              VM4
         eth1(default1)       eth0(default1)     eth1(default3)
                  2.2.2.2    《--》    2.2.2.3            4.4.4.4  
    
         ip_forward          ip_forward

eth0 (default)     eth0(default)       eth1(default2)     eth0(default2)
1.1.1.1      --》      1.1.1.2           3.3.3.3     《--        3.3.3.4




sip:1.1.1.1    dip:4.4.4.4
返回
sip:4.4.4.4    dip:1.1.1.1



步驟一:
從1.1.1.1 ping 1.1.1.2

在宿主機上ping 1.1.1.2,能通

步驟二:
ping 2.2.2.2 不能通

解決方法:
在vm1上加網關
route add default gw 1.1.1.2

步驟三:
在宿主機加了一個網關指向1.1.1.2的基礎上,我再繼續在宿主機上ping 2.2.2.3 不能通 
解決方法:
在vm3上加網關指向2.2.2.2
route add default gw 2.2.2.2
還要在VM2上打開ip_forward,打開方法有三種
1,# echo 1 > /proc/sys/net/ipv4/ip_forward    --立刻生效,但重啓後就不生效了
2,# sysctl -w net.ipv4.ip_forward=1        --立刻生效,但重啓後就不生效了
3,# vim /etc/sysctl.conf    
net.ipv4.ip_forward = 1        --加這一句到此配置文件裏
# sysctl -p            --保存後,使用此命令讓它永久生效



步驟四:
繼續ping 3.3.3.3    不通
解決:再在VM2上route add default gw 2.2.2.3

步驟五:
繼續ping 3.3.3.4    不通

解決:在VM3上打開ip_forward
還要在VM4上route add default gw 3.3.3.3

步驟六
繼續ping 4.4.4.4  不通
解決:若是在VM3上加一個網關指向3.3.3.4,實際上是有問題的,由於VM3上這樣就有兩個網關了。若是你不使用多路由表的作法,這兩個網關只能有一個網關有效。
因此加網關的方式不可行,只能在VM3加路由
route add -net 4.4.4.0 netmask 255.255.255.0 dev eth1


上面終於從1.1.1.1ping到4.4.4.4


那麼若是還有5網段,6網段,7網段,甚至更多(相似因特網),所有靠指網關來通迅不現實。實際的作法就是使用路由協議(rip,ospf,bgp等)來作,這就是動態路由了。



若是我把上面的全部網關和ip_forward去掉,而後手動加上路由(也就是說四臺機都有四個網段的路由),那麼就只能ping通到2.2.2.2,ping2.2.2.3就不通了


linux下能夠安裝相似zebra這樣的軟路由軟件,能夠把linux模擬成一臺cisco路由器來進行配置。


============================================================================

準備三臺虛擬機作實驗(把iptables都先關閉);
--注意:這裏我沒有用宿主機模擬中間的機器(由於用宿主機有多個子接口的狀況下,在作firewalld測試的時候會有不穩定的狀況;並且宿主機打開firewalld,那麼就會默認拒絕vnc等,帶來不方便)



    A                                             B(作路由只須要兩個不一樣ip)                       C

  內網(虛擬機)                            雙網卡機器(虛擬機)                                       外網(虛擬機)
            
192.168.100.128 -----》      192.168.100.2  eth1(default1)    
  (A主機的網卡信息也寫B主機的ip)
                                      ip_forward        
                                   # echo "1" > /proc/sys/net/ipv4/ip_forward   --臨時
                   10.1.1.2    eth0 (br0)    《----------------------  10.1.1.3(C機10段的ip設置爲本身的網卡信息)
                            


--注意:模擬上面的環境時,宿主機能夠模擬中間的雙網卡機器,但不能模擬內網或外網其中一臺(緣由是宿主機原本就是與虛擬的全部網段是直通的,你若是把它作爲內網,則它會直接鏈接外網而不會走中間的網關)
--因此兩種模擬方法:1,宿主機模擬雙網卡機器,兩臺虛擬機分別模擬內外網;2,不要宿主機,三臺虛擬機來模擬,中間的雙網卡網關使用一臺雙網關的虛擬機模擬,另兩臺用單網卡來模擬


把gateway加上路由功能

# echo "1" > /proc/sys/net/ipv4/ip_forward   --臨時生效

# vim /etc/sysctl.conf 
net.ipv4.ip_forward = 1

# sysctl -p    --改完後使用此命令,使之修改永久生效

路由功能加了後,網關都指向了gateway這臺物理機,那麼  兩個網段的這兩臺機就能互相ping通


例一:禁止內網192.168.100.128和外網10.1.1.3互ping
iptables -A FORWARD -p icmp -s 192.168.100.128 -j DROP
或者
iptables -A FORWARD -p icmp -s 10.1.1.3 -j DROP



例二:禁止內網192.168.100.128上外網的10.1.1.3這個網站
iptables -A FORWARD -p tcp --dport 80 -s 192.168.100.128 -d 10.1.1.3 -j DROP



=============================================================================




問題:這裏咱們模擬內外網的訪問,網關互指,中間雙網卡機器打開ip_forward,但實際的網絡訪問環境中,外網客戶會把網關指向你公司的網關嗎?

張三                     李四                   王五

  內網用戶             雙網卡機器             外網服務器
              (其實就是模擬一個路由器)
192.168.100.128    ---->  192.168.100.2   eth1    
                  網關指向    
                  打開ip_forward            

                      10.1.1.2       eth0                10.1.1.3
相關文章
相關標籤/搜索