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
相关文章
相关标签/搜索