zoukankan      html  css  js  c++  java
  • 3、iptables扩展及使用

    iptables/netfilter

    netfilter: kernel framework,位于内核中的协议框架

    iptables  是规则管理命令行工具

     

    四表:filter, nat, mangle, raw

    五链:PREROUTING, INPUT, FORWARD, OUTPUT, POSTROUTING

     

    iptables

    子命令:

    链:-F, -X, -N, -E, -Z, -P, -L

    规则:-A, -I, -D, -R

     

    -j TARGET:

        ACCEPT, DROP, REJECT, RETURN, LOG, MARK, DNAT, SNAT, MASQUEARDE, ...

     

    匹配标准:

    • 通用匹配:-s, -d, -p, -i, -o
    • 扩展匹配
    • 隐含扩展:
    • -p tcp: --dport, --sport, --tcp-flags, --syn (--tcp-flags SYN,ACK,FIN,RST SYN)
    • -p udp: --dport, --sport
    • -p icmp: --icmp-type
    • 显式扩展: -m

    iptables:

    显式扩展

    multiport扩展、iprange扩展、string扩展、time扩展、connlimit扩展、limit扩展、state扩展

    必须显式指明使用的扩展模块(rpm -ql iptables | grep ".so"或rpm -ql iptables | grep "[[:lower:]]+.so$")

    CentOS 6: man iptables

    CentOS 7: man iptables-extensions

     

    1、multiport扩展   (--dport/--sport指明端口时必须是单个的或连续的)

    以离散方式定义多端口匹配;最多指定15个端口;

    [!] --source-ports,--sports port[,port|,port:port]...:指明多个源端口;

    [!] --destination-ports,--dports port[,port|,port:port]...:指明多个离散的目标端口;

    [!] --ports port[,port|,port:port]...:既能匹配源端口,也能匹配目标端口

    -m multiport 示例

    # iptables -A INPUT -d 192.168.184.142 -p tcp --dport 22 -j ACCEPT  //放行22号端口

    # iptables -A OUTPUT -s 192.168.184.142 -p tcp --sport 22 -j ACCEPT

    # iptables -P INPUT DROP     //修改表的默认策略
    # iptables -P FORWARD DROP
    # iptables -P OUTPUT DROP

    此时web服务是无法响应的,下面演示一次性定义开放22和80端口

    # iptables -I INPUT -s 192.168.184.0/24 -d 192.168.184.142 -p tcp -m multiport --dports 22,80 -j ACCEPT   入栈

           // -s 指定源IP,这里指的是一个网段,-m 指是使用显式扩展,--dports指定多个离散端口

    # iptables -I OUTPUT -d 192.168.184.0/24 -s 192.168.184.142 -p tcp -m multiport --sports 22,80 -j ACCEPT

    # iptables -D INPUT 2    
    # iptables -D OUTPUT 2

    此时的80端口也可以访问了

    2、iprange扩展     ip范围

    指明连续的(但一般是不能扩展为整个网络)ip地址范围时使用;

    [!] --src-range from[-to]:指明连续的源IP地址范围;

    [!] --dst-range from[-to]:指明连续的目标IP地址范围;

    iprange示例

    # iptables -I INPUT  -d 192.168.184.142 -p tcp -m multiport --dports 22:23,80 -m iprange --src-range 192.168.184.1-192.168.184.150 -j ACCEPT
    # iptables -I OUTPUT -s 192.168.184.142 -p tcp -m multiport --sports 22:23,80 -m iprange --dst-range 192.168.184.1-192.168.184.150 -j ACCEPT
                                                      //连续端口之间用冒号隔开:22:23,不连续的用80隔开
    # iptables -D INPUT 2   
    # iptables -D OUTPUT 2

    3、string扩展

    功能:基于字符串匹配去检查协议传输单元中的内容

    1、任何通过网络传输的数据都必定是可以被流式化的数据,

    2、数据通过网络传输时,会被封装上各种首部,

    string可以检查在网络上发送的每一个报文,报文虽然编码,却可以匹配编码中是否出现了string指定的字符串的。

    iptables工作在网络层和传输层,却可以通过string扩展去检查所传输的内容中是否有要匹配的字符串的

     

    检查报文中出现的字符串;

    --algo {bm|kmp}  指明字符串比对算法,必须给定算法

    bm = Boyer-Moore

    kmp = Knuth-Pratt-Morris

    [!] --string pattern  指明字符串是什么

    string示例

    在web服务器的web页面文件中定义一个bad.html

    # vim /var/www/html/bad.html

      This is a movie page.   //网页内容,如果用户请求的网页中包含movie,那么就拒绝

    一般来说当用户请求一个网页,他请求的报文中一般不包含非法内容,因为只有网页响应的时候,网页上的内容有可能包含非法内容,所以应该在output规则上添加规则,同时应该放在output定义的80规则上面,因为如果放在80下面,那么响应报文被80规则匹配到以后直接就发送出去了

    未定义之前是可以被访问的

    # iptables -I OUTPUT -m string --algo bm --string 'movie' -j REJECT  //下图未做修改

    142的默认网页可以查看

    但是带有movie的网页无法查看

    请求可以进来,但由于含有movie字符串,所以web服务器并不响应

    4、time扩展

    根据报文到达的时间与指定的时间范围进行匹配;

    #man  iptables-extensions 即可查看下面的用法

    • --datestart  YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
    • --datestop  YYYY[-MM[-DD[Thh[:mm[:ss]]]]]
    • --timestart   hh:mm[:ss]
    • --timestop   hh:mm[:ss] 
    • [!] --monthdays  day[,day...]
    • [!] --weekdays    day[,day...]

    从0点到23点之间不允许访问,因为Linux系统用的是CST时间,这里既然拒绝就直接在请求上即INPUT上拒绝,同时同类规则匹配范围小的放前面,所以放在INPUT第一条规则

    # iptables -I INPUT -d 192.168.184.142 -p tcp --dport 80 -m time --timestart 00:00 --timestop 23:59 -j REJECT

    此时在浏览器中输入192.168.184.142就不再提供web服务了 

    5、connlimit扩展

    根据每客户端IP(也可以是地址块)做并发连接数数量匹配;即对每个IP可以对服务器同时发送请求的数量的限制。

    --connlimit-above n:连接的数量大于n     

    --connlimit-upto n: 连接的数量小于等于n    

    默认策略是拒绝, 使用--connlimit-upto来允许,默认是允许,使用--connlimit-above允许

    限制ssh的并发链接数,放在INPUT链上ssh服务即22号端口的规则的上面

    # iptables -I INPUT -p tcp --dport 22 -m connlimit --connlimit-above 3 -j REJECT

    6、limit扩展

    基于收发报文的速率做检查;

    令牌桶过滤器    令牌桶算法 https://jinnianshilongnian.iteye.com/blog/2305117      https://blog.csdn.net/SunnyYoona/article/details/51228456#commentBox

    --limit rate[/second|/minute|/hour|/day]   //表示每秒钟/分钟/小时/天多少个          30/minute:表示每两秒响应一个请求

    --limit-burst number  表示未响应前的峰值即第一次响应可以一次性响应多少个请求

    示例

    • 0:echo-reply   回显应答
    • 8: echo-request 回显请求

    # iptables -A OUTPUT -s 192.168.184.144 -p icmp --icmp-type 8 -j ACCEPT  ping别的主机,先从本主机出去,目标地址不知道,ping请求是8
    # iptables -A INPUT -d 192.168.184.144 -p icmp --icmp-type 0 -j ACCEPT   ping别的主机,要接受ping后的报文,目标地址是本机,报文类型是回显应答

    以上是只能本机ping别的主机,别的主机无法ping本主机,下面就定义规则为限制别的主机ping本主机的速率

    # iptables -A INPUT -d 192.168.184.142 -p icmp --icmp-type 0 -m limit --limit-burst 5 --limit 30/minute -j ACCEPT  //响应请求的速率

    //-s源地址省略,表示所有主机可以ping本主机;别的主机ping本主机,请求类型为8,表示回显请求;limit:表示做速率限制,--limit-burst 5:表示第一次可以一次性响应5个请求;--limit 30/minute:表示每两秒一个,
    # iptables -A OUTPUT -s 192.168.184.142 -p icmp --icmp-type 8 -j ACCEPT   //响应请求后,从本机响应的报文不再做限制,只要ping进来就能响应

    # ping -W 1 192.168.184.142    //使用-W表示ping每隔1秒钟向外发一个包

    7、state扩展  状态扩展  (重要)

    根据连接追踪机制检查连接的状态,对链接做出匹配检查;

    连接追踪是iptables在内核内部找一段内核空间,并在这段内核空间中记录下来此前每一个源地址,和这个源地址访问的目标地址(目标地址一般是本机地址),然后给每一个源地址和目标地址的链接记录下来,并在后面记录一个倒计时的计时器(可以记录的非常详细,比如包括协议、源端口、目标端口等),这个内存空间是在内核中,所以这个内核比较小

    链接与链接之间的状态,跟tcp、udp、icmp协议无关,是iptables自己在内核中的一个功能

    调整连接追踪功能所能够容纳的最大连接数量:

    /proc/sys/net/nf_conntrack_max

     

    已经追踪到并记录下的连接:

    /proc/net/nf_conntrack

     

    不同协议或连接类型追的时长:

    /proc/sys/net/netfilter/

    可追踪的连接状态:

    NEW:新发出的请求;连接追踪模板中不存此连接相关的信息条目,因此,将其识别为第一次发出的请求;

    ESTABLISHED:NEW状态之后,连接追踪模板中为其建立的条目失效之前,这段期间内所进行的通信的状态;

    RELATED:相关的连接;如ftp协议的命令连接与数据连接之间的关系;

    INVALIED:无法识别的连接;

    RELATED:一个新的链接请求发起时本来是NEW,但是对ftp这样的应用来讲,数据链接是与一个已存在的命令链接或控制链接是相互关联的,因此在这种场景中,数据链接新发起的链接状态可以识别为NEW,实际上更多在nf_conntrack_ftp打开以后被识别成RELATED请求,不过RELATED这个链接请求建立完成后,后续的传输过程中都是ESTABLISHED。

    --state STATE1,STATE2,...            --state NEW,ESTABLISHED

    示例

    对22和80端口只能是响应,不能去请求。所以对NEW状态的应该放行,因为别的主机可能请求服务器,对于ESTABLISHED也应该放行,因为这是响应。但是对于响应的只能放行ESTABLISHED状态的

    # iptables -I INPUT -d 192.168.184.142 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

           //--state NEW,ESTABLISHED   这里是入栈的链接,放行22端口的NEW和ESTABLISHED两种状态

    # iptables -I OUTPUT -s 192.168.184.142 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT //出去的报文,只放行状态为ESTABLISHED

    像放行22号端口一样放行80端口,就直接修改上面的规则

    # iptables -I INPUT -d 192.168.184.142 -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT

    # iptables -I OUTPUT -s 192.168.184.142 -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

    下面把两个端口合二为一

    # iptables -I INPUT -d 192.168.184.142 -p tcp -m multiport --dports 22,80 -m state --state NEW,ESTABLISHED -j ACCEPT

    # iptables -I OUTPUT -s 192.168.184.142 -p tcp -m multiport --sports 22,80 -m state --state ESTABLISHED -j ACCEPT

    如果别的主机ping本主机?

    # iptables -A INPUT -d 192.168.184.142 -p icmp --icmp-type 0 -m state --state NEW,ESTABLISHED -j ACCEPT
    # iptables -A OUTPUT -s 192.168.184.142 -p icmp --icmp-type 8 -m state --state ESTABLISHED -j ACCEPT

    此时ping就可以建立链接了

    从以上可以发现无论是tcp协议还是icmp协议,或者无论是22号端口或者80端口,只要允许进入INPUT,都要放行,所以可以在OUTPUT上定义一条规则,这条规则不定义端口、协议、源IP和目标IP,只定义链接状态ESTABLISHED。

    # iptables -I OUTPUT -m state --state ESTABLISHED -j ACCEPT    //此时这里只定义链接状态

    一条规则就可以直接对N条规则直接放行,这就是规则优化

    可以假设入栈的只要是ESTABLISHED状态的,就说明此前访问过,那么所有ESTABLISHED状态就可以统统放行,只要对NEW状态不放行就可以。

    # iptables -I INPUT -m state --state ESTABLISHED -j ACCEPT  //无论tcp、icmp协议的请求,只要是已经建立的链接,只要被第一条匹配到直接通过

    # iptables -I INPUT 2 -d 192.168.184.142 -p tcp -m multiport --dports 22,80 -m state --state NEW -j ACCEPT

    问题:如何开放被动模式的ftp服务?

    对21号端口开放NEW和ESTABLISHED,因为命令链接一般是通过21号端口实现,由于数据链接工作在非固定的随机端口上,

    所以只需要检查这个链接的状态是不是为RELATED就可以了,如果是RELATED,无论是入栈还是出栈直接放行就可以。

    (1) 装载ftp追踪时的专用的模块:

    /lib/modules/3.10.0-693.el7.x86_64/kernel/net

    /lib/modules/3.10.0-693.el7.x86_64/kernel/net/netfilter

    # modprobe nf_conntrack_ftp   //装载模块

    # lsmod   //可以查看装载的模块

     

    (2) 放行请求报文:

    命令连接:NEW, ESTABLISHED

    数据连接:RELATED, ESTABLISHED   

           (数据刚建立链接时的状态叫RELATED,这个只是第一次建立数据链接时,而且不叫新连接,而是RELATED链接,而不是NEW,命令链接才是NEW)

    ftp专用放行规则

    # iptables -A INPUT -d LocalIP -p tcp --dport 21 -m state --state NEW,ESTABLISHED -j ACCEPT   //放行的命令链接

    # iptables -A INPUT -d LocalIP -p tcp -m state --state RELATED,ESTABLISHED -j ACCEPT      //放行的数据链接,不再限制端口

    (3) 放行响应报文:

    ESTABLISEHD

    # iptables -A OUTPUT -s LocalIP -p tcp -m state --state ESTABLISHED -j ACCEPT     //出栈放行

    示例

    1、安装vsftpd软件并启动

    # yum install vsftpd -y

    # cp /etc/issue /var/ftp/pub/   //cp文件到vsftp的默认下

    # systemctl start vsftpd        //启动ftp服务

    # ss -tunl                     //查看21号端口是否启动

    2、关闭防火墙并清空规则,下图是已经配置的iptables规则链,可以先保存

    # iptables-save > /root/iptables.1

    修改成下图的样子

    可以在浏览器中访问ftp服务

    3、添加规则链

    # iptables-restore < /root/iptables.1   //把之前保存的规则重新导入,这里换成了141服务器,在文件中修改IP即可

    # modprobe nf_conntrack_ftp   //装载ftp模块
    # lsmod | grep ftp

    nf_conntrack_ftp   18638   0
    nf_conntrack       133387  3  xt_conntrack,nf_conntrack_ftp,nf_conntrack_ipv4

    # iptables -R INPUT 2 -d 192.168.184.141 -p tcp -m multiport --dport 21,22,80 -m state --state NEW -j ACCEPT  

        //这里直接修改了INPUT的第二条规则,即在--dport上添加了21号端口,这是放行(进栈)的命令链接,是NEW状态

    # iptables -R INPUT 1 -m state --state ESTABLISHED,RELATED -j ACCEPT 

       //RELATED无法确定是tcp的哪个端口,而且只有用到RELATED功能的才会检查RELATED状态,所以很少用,所以直接把第一条规则改为ESTABLISHED和RELATED都放行

    出栈的无论什么协议、什么IP、什么端口只要是ESTABLISHED状态全都放行,所以无需再改,所以ftp服务就可以访问了

     命令链接和数据链接的区别?

    一个新的链接请求发起时本来是NEW,但是对ftp这样的应用来讲,数据链接是与一个已存在的命令链接或控制链接是相互关联的,因此在这种场景中,数据链接新发起的链接状态可以识别为NEW,实际上更多在nf_conntrack_ftp打开以后被识别成RELATED请求,不过RELATED这个链接请求建立完成后,后续的传输过程中都是ESTABLISHED。

  • 相关阅读:
    【bzoj2561】最小生成树 网络流最小割
    【bzoj4407】于神之怒加强版 莫比乌斯反演+线性筛
    【bzoj4816】[Sdoi2017]数字表格 莫比乌斯反演
    【bzoj3252】攻略 贪心+DFS序+线段树
    【bzoj1690】[Usaco2007 Dec]奶牛的旅行 分数规划+Spfa
    【bzoj3291】Alice与能源计划 模拟费用流+二分图最大匹配
    【bzoj2752】[HAOI2012]高速公路(road) 线段树
    wpf--- TextBlock文字设置属性
    无边框WPF窗体——允许拖动
    C# 枚举、字符串、值的相互转换
  • 原文地址:https://www.cnblogs.com/hanshanxiaoheshang/p/9790642.html
Copyright © 2011-2022 走看看