iptables之六tcp_wrapper

1、iptables补充与回顾

一、iptables修改连接跟踪表最大容量大小的方式

  iptables的连接跟踪表最大容量为/proc/sys/net/ipv4/ip_conntrack_max(有的地方可能叫nf_conntrack_max),连接碰到各类状态的超时后就会从表中删除。node

  因此解決方法通常有两个:linux

   (1)、加大 ip_conntrack_max 值web

  vi /etc/sysctl.conf

  net.ipv4.ip_conntrack_max = 393216

  net.ipv4.netfilter.ip_conntrack_max = 393216

   (2)、下降 ip_conntrack timeout时间服务器

  vi /etc/sysctl.conf

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60

  net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120

  iptables -t nat -L -n

 

 

 

二、iptables练习

练习:INPUT和OUTPUT默认策略为DROP;网络

    一、限制本地主机的web服务器在周一不容许访问;新请求的速率不能超过100个每秒;web服务器包含了admin字符串的页面不容许访问;web服务器仅容许响应报文离开本机;并发

    二、在工做时间,即周一到周五的8:30-18:00,开放本机的ftp服务给172.16.0.0网络中的主机访问;数据下载请求的次数每分钟不得超过5个;app

    三、开放本机的ssh服务给172.16.x.1-172.16.x.100中的主机,x为你的座位号,新请求创建的速率一分钟不得超过2个;仅容许响应报文经过其服务端口离开本机;框架

    四、拒绝TCP标志位所有为1及所有为0的报文访问本机;ssh

    五、容许本机ping别的主机;但不开放别的主机ping本机;tcp

 

练习:判断下述规则的意义:

    # iptables -N clean_in(自定义规则链)

    # iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP

    # iptables -A clean_in -d 172.16.255.255 -p icmp -j DROP

 

    # iptables -A clean_in -p tcp ! --syn -m state --state NEW -j DROP(拒绝非法(多是别人通过巧妙假装的视图发起攻击的)报文)

    # iptables -A clean_in -p tcp --tcp-flags ALL ALL -j DROP

    # iptables -A clean_in -p tcp --tcp-flags ALL NONE -j DROP

    # iptables -A clean_in -d 172.16.100.7 -j RETURN (调用自定义规则链并从自定义规则链中返回的)

  

    # iptables -A INPUT -d 172.16.100.7 -j clean_in

 

    # iptables -A INPUT  -i lo -j ACCEPT

    # iptables -A OUTPUT -o lo -j ACCEPT

  

    # iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 53,113,135,137,139,445 -j DROP

    # iptables -A INPUT  -i eth0 -m multiport -p udp --dports 53,113,135,137,139,445 -j DROP

    # iptables -A INPUT  -i eth0 -p udp --dport 1026 -j DROP

    # iptables -A INPUT  -i eth0 -m multiport -p tcp --dports 1433,4899 -j DROP

 

    # iptables -A INPUT  -p icmp -m limit --limit 10/second -j ACCEPT

 

 

三、课外扩展

recent模块

  补充:利用iptables的recent模块来抵御DOS攻击: 22,创建一个列表,保存有全部访问过指定的服务的客户端IP;

  recent模块可以实现对于某一个服务的请求频率知足之后作后续拒绝一段时间访问的;

 

    ssh: 远程链接:

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

  iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH

  iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j LOG --log-prefix "SSH Attach: "

  iptables -I INPUT  -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

    1.利用connlimit模块将单IP的并发设置为3;会误杀使用NAT上网的用户,能够根据实际状况增大该值;

    2.利用recent和state模块限制单IP在300s内只能与本机创建2个新链接。被限制五分钟后便可恢复访问。

    下面对最后两句作一个说明:

    1.第二句是记录访问tcp 22端口的新链接,记录名称为SSH

     --set 记录数据包的来源IP,若是IP已经存在将更新已经存在的条目

    2.第三句是指SSH记录中的IP,300s内发起超过3次链接则拒绝此IP的链接。

     --update 是指每次创建链接都更新列表;

     --seconds必须与--rcheck或者--update同时使用

     --hitcount必须与--rcheck或者--update同时使用

    3.iptables的记录:/proc/net/xt_recent/SSH

  

    也可使用下面的这句记录日志:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --name SSH --second 300 --hitcount 3 -j LOG --log-prefix "SSH Attack"

 

四、iptables实现七层访问过滤

(学习向内核打补丁编译使用)

  iptables直接访问应用层协议,根据应用层协议作控制,好比访问http协议没有问题,可是访问ftp协议就拒绝。再好比qq协议就拒绝。

 

  模块layer7

    用于识别应用层协议;

  注意:layer7是一个扩展,不过这个扩展iptables没有自带,因此要想实现七层访问过滤,得为iptables补上layer7这一模块,而layer7模块须要内核的netfilter框架的支持也须要用户空间iptables命令在写规则能支持,因此若是咱们要想使用layer7,第一,得对内核打补丁,从新编译升级内核;第二,得对iptables打补丁,从新编译升级iptables。layer7提供的补丁包只适用于较老版本的内核和较老版本的iptables,因此从互联网上直接下载的补丁包用起来可能会有必定的问题。

     iptables/netfilter

         iptables -m state,

         netfilter state

 

  对内核中的netfilter,打补丁layer7,从新编译内核

  对iptables打补丁,补上layer7模块,从新iptables

  

    diff/patch:文本操做工具

    diff是Unix系统的一个很重要的工具程序。它用来比较两个文本文件的差别,是代码版本管理的核心工具之一。其用法很是简单:

  diff <变更前的文件> <变更后的文件>

        因为历史缘由,diff有三种格式:

         * 正常格式(normal diff)

         * 上下文格式(context diff)

         * 合并格式(unified diff)

       一、正常格式的diff

           例如,对file1(变更前的文件)和file2(变更后的文件)进行比较可以使用以下命令:

  diff file1 file2

      显示结果中,第一行是一个提示,用来讲明变更位置。它分红三个部分:前面的数字,表示file1的第n行有变化;中间的"c"表示变更的模式是内容改变(change),其余模式还有"增长"(a,表明addition)和"删除"(d,表明deletion);

       二、上下文格式的diff

           上个世纪80年代初,加州大学伯克利分校推出BSD版本的Unix时,以为diff的显示结果太简单,最好加入上下文,便于了解发生的变更。所以,推出了上下文格式的diff。它的使用方法是加入-c选项(即context)。

  diff -c f1 f2

           结果分红四个部分。第一部分的两行,显示两个文件的基本状况:文件名和时间信息,"***"表示变更前的文件,"---"表示变更后的文件。第二部分是15个星号,将文件的基本状况与变更内容分割开。第三部分显示变更前的文件,即file1。

           另外,文件内容的每一行最前面,还有一个标记位。若是为空,表示该行无变化;若是是感叹号(!),表示该行有改动;若是是减号(-),表示该行被删除;若是是加号(+),表示该行为新增。

           第四部分显示变更后的文件,即file2。

       三、合并格式的diff

           若是两个文件类似度很高,那么上下文格式的diff,将显示大量重复的内容,很浪费空间。1990年,GNU diff率先推出了"合并格式"的diff,将f1和f2的上下文合并在一块儿显示。

           它的使用方法是加入u参数(表明unified)。

    diff -u f1 f2

           其结果的第一部分,也是文件的基本信息。"---"表示变更前的文件,"+++"表示变更后的文件。第二部分,变更的位置用两个@做为起首和结束。第三部分是变更的具体内容。

           除了有变更的那些行之外,也是上下文各显示3行。它将两个文件的上下文,合并显示在一块儿,因此叫作"合并格式"。每一行最前面的标志位,空表示无变更,减号表示第一个文件删除的行,加号表示第二个文件新增的行。

       diff

           -u

 

       patch

       尽管并无指定patch和diff的关系,但一般patch都使用diff的结果来完成打补丁的工做,这和patch自己支持多种diff输出文件格式有很大关系。patch经过读入patch命令文件(能够从标准输入),对目标文件进行修改。一般先用diff命令比较新老版本,patch命令文件则采用diff的输出文件,从而保持原版本与新版本一致。

       patch的标准格式为

  patch [options] [originalfile] [patchfile] 

       若是patchfile为空则从标准输入读取patchfile内容;若是originalfile也为空,则从patchfile(确定来自标准输入)中读取须要打补丁的文件名。所以,若是须要修改的是目录,通常都必须在patchfile中记录目录下的各个文件名。绝大多数状况下,patch都用如下这种简单的方式使用:

       patch命令能够忽略文件中的冗余信息,从中取出diff的格式以及所须要patch的文件名,文件名按照diff参数中的"源文件"、"目标文件"以及冗余信息中的"Index:"行中所指定的文件的顺序来决定。

       -p参数决定了是否使用读出的源文件名的前缀目录信息,不提供-p参数,则忽略全部目录信息,-p0(或者-p 0)表示使用所有的路径信息,-p1将忽略第一个"/"之前的目录,依此类推。如/usr/src/linux-2.4.15/Makefile这样的文件名,在提供-p3参数时将使用linux-2.4.15/Makefile做为所要patch的文件。

           patch

              -p

              -R

 

mockbuild

 

总结:操做步骤

  一、获取并编译内核

  # useradd mockbuild

  # rpm -ivh kernel-2.6.32-431.5.1.x86_64.el6.src.rpm

  # cd rpmbuild/SOURCES

  # tar linux-2.6.32-*.tar.gz -C /usr/src
  
  # cd
/usr/src   # ln -sv

  二、给内核打补丁

  # tar xf netfilter-layer7-v2.23.tar.bz2

  # cd /usr/src/linux

  # patch -p1 < /root/netfilter-layer7-v2.23/kernel-2.6.32-layer7-2.23.patch

  # cp /boot/config-*  .config

  # make menuconfig

    按以下步骤启用layer7模块      

       Networking support → Networking Options →Network packet filtering framework → Core Netfilter Configuration

       <M>  “layer7” match support

  三、编译并安装内核

  # make

  # make modules_install

  # make install

 

  四、重启系统,启用新内核

 

  五、编译iptables

  # tar xf iptables-1.4.20.tar.gz

  # cp /root/netfilter-layer7-v2.23/iptables-1.4.3forward-for-kernel-2.6.20forward/* /root/iptables-1.4.20/extensions/

  # cp /etc/rc.d/init.d/iptales /root

  # cp /etc/sysconfig/iptables-config /root

  # rpm -e iptables iptables-ipv6 --nodeps

  # ./configure  --prefix=/usr  --with-ksource=/usr/src/linux

  # make && make install

  # cp /root/iptables /etc/rc.d/init.d

  # cp /root/iptables-config /etc/sysconfig

  六、为layer7模块提供其所识别的协议的特征码

  # tar zxvf l7-protocols-2009-05-28.tar.gz

  # cd l7-protocols-2009-05-28

  # make install    

  七、如何使用layer7模块

      ACCT的功能已经能够在内核参数中按需启用或禁用。此参数须要装载nf_conntrack模块后方能生效。

       net.netfilter.nf_conntrack_acct = 1

  

       l7-filter uses the standard iptables extension syntax

       # iptables [specify table & chain] -m layer7 --l7proto [protocol name] -j [action]

       # iptables -A FORWARD -m layer7 --l7proto qq -j REJECT

       编译内核:

       make menuconfig

       make -j #

       make modules_install

       make install

       清理内核源码树:

       提示:xt_layer7.ko依赖于nf_conntrack.ko模块

 

2、tcp_wrapper

tcp_wrappertcp包装器

  是一个相似于iptables的实现访问控制工具。可是,只是对基于TCP协议开发并提供服务的应用程序,提供的一层访问控制工具;

    iptables是工做在内核中的,因此只要是一个网络服务经由经由内核中的TCP/IP协议栈就可以收到netfilter的控制,那tcp_wrapper也须要在用户请求的报文所必经的路上实现对于某个服务的访问控制的功能,可是tcp_wrapper不像netfilter是在内核中实现而是基于库调用来实现其功能的。这就意味着只有那些在开发时不光是TCP协议还必须是基于TCP协议开发提供服务而且在开发时调用了tcp_wrapper相关库的(这个库叫libwrap)的应用tcp_wrapper的应用才能生效。

    很显然,tcp_wrapper比起netfilter的适用范围要窄的多了,那咱们怎么知道哪个应用程序调用了tcp_wrapper而且支持对于tcp_wrapper进行控制呢?

  判断服务是否可以由tcp_wrapper进行访问控制:

    此前说过,一个程序在开发时若是调用了某个接口,可是它在编译时却有两种方式编译,第一,动态编译,第二,静态编译。动态编译表示基于动态连接库的方式使用库,静态编译表示把调用的库文件直接编译进应用程序内部,因此这有两种情形,它的判断方式不同:

  • (1) 动态编译:ldd命令(ldd命令显示出连接至libwrap便可);
  • (2) 静态编译:strings命令查看应用程序文件,其结果中若是出现下述两个文件:
    •   hosts.allow
    •   hosts.deny

    则表示支持tcp_wrapper控制,不然则表示不支持;

    由此,咱们看看系统上有哪些应用程序可以支持这样的访问控制机制,以CentOS 7为例:

    先清空iptables规则:

  查看sshd是否支持tcp_wrapper规则:

      说明它是接受tcp_wrapper控制的。

  再看httpd:

    未连接至libwrap库,说明httpd不接受tcp_wrapper控制。

  再看vsftpd:

    所以它接受tcp_wrapper控制

    经过这种方式查看的结果当中,但凡那些连接当中出现了libwrapper的才表示它可以受tcp_wrapper控制。

    那么若是收tcp_wrapper控制,咱们如何实现基于tcp_wrapper对服务作访问控制呢?其实tcp_wrapper比iptables要简单太多了,很是容易实现。

    要想实现服务访问控制,它是经过在配置文件中为各服务分别定义访问控制规则实现访问控制:

   配置文件:

  • /etc/hosts.allow
  • /etc/hosts.deny

    因此咱们写在allow或deny文件中就能实现某个服务可以容许可以有哪些客户端主机进行访问了,在此直接定义便可。

   配置文件语法:

  daemon_list(指定是哪个服务,能够是单个服务也能够是服务列表,如有多个使用逗号隔开):client_list(容许或拒绝哪些客户端主机)[:options(其它选项)](此项若是写在allow文件中表示容许,写在deny文件中表示拒绝,仅此而已)

  若是在两个文件中写了同一个条目,事实上,这两个文件有其检查次序的概念的。首先咱们检查hosts.allow,其次才是hosts.deny,也就是说当一个客户端来访问某个服务时,先检查在allow文件中是否有与之匹配的规则,若是有匹配的规则,就容许访问即放行。若是allow文件中没有,则检查deny文件,若是deny文件中有匹配的,则拒绝访问,若是hosts.deny也没有匹配的,那就要取决于默认策略了。

  流程大体以下图所示:

    因此说若是咱们仅放行某一个网络对服务访问,怎么办呢?在allow中allow这个网络,在deny中deny all便可。因此这就是为何当前主机上这么多受libwrap控制的服务默认都没有拒绝的缘由,由于在这两个文件中什么都没有定义。默认状况下这两个文件是空的。那两个文件是空的就意味着咱们的服务即使是受tcp_wrapper控制它也是被容许的,由于第一个文件匹配第二个文件也没匹配,那默认是allow的。

  能够看出,上述文件默认都是注释的,即规则为空。

 

  接下来,咱们就来试试让它们来控制服务的访问了。

  咱们先来讲一说咱们怎么在配置文件中去写这些规则,也就是说咱们给出daemon_list规则的格式是什么。

  daemon_list格式:

  • 应用程序的文件名称,而非服务名

    必定是应用程序的文件的名字,由于咱们说过它是文件经过连接至libwrap库文件来完成访问控制的,因此说应用程序列表中的应用程序给的必须是文件名而不能是服务名,好比咱们要控制named,应用程序叫named而不能写成DNS;

  • 应用程序文件名称列表,彼此之间使用逗号分隔

    例如:想要vsftpd和ssh基于一样法则控制

    编写格式为:sshd,vsftpd;

    ALL表示全部受tcp_wrapper控制的应用程序服务;

   client_list格式:

  • IP地址;表示单个主机;
  • 主机名;表示单个主机;
  • 网络地址;必须使用完整格式的掩码,不能使用前缀格式掩码,因此相似于172.16.0.0/16不合法;表示此网络中的全部主机;
  • 简短格式的网络地址;咱们在讲到httpd的allow、from时说过172.16网络可使用172.16表示,不过这不能那样写,由于最后那个点不能省略,例如:172.16.表示172.16.0.0/255.255.0.0;
  • ALL;表示全部来源主机;
  • KNOW;表示全部能够解析到的主机;
  • UNKNOWN;表示全部没法解析的主机;
  • PARANOID;(瘫痪、麻痹)表示主机名的正反解结果不匹配;

 

例如:

  vsftpd服务不容许192.168.241.1访问:

 

    注意:这不是一个服务,而是一个库,而库在应用程序本身运行时就可能会调用的库的,所以这也不用重启任何服务;

  192.168.241.6这台主机上的ftp服务仅容许192.168.241.0网络访问的实现:

 

    换一个主机测试:

  可是对于telnet服务来讲有些特殊:

    telnet的服务叫作telnet-server:(在CentOS6上telnet是受超级守护进程控制的,由于超级守护进程是接受tcp_wrapper控制的,因此telnet也受tcp_wrapper控制,但在CentOS7上telnet是做为一个独立的进程的,不受tcp_wrapper控制了。所以此处在CentOS 6上实验)

  启动telnet要先启动超级守护进程,可是在此以前须要先修改配置文件

    它是受xinet.d控制的

    改成disable no至关于checkconfig telnet on。

  telnet只能使用普通用户登陆,所以添加用户:

    先在本地链接一下:

    如今咱们对telnet作访问控制:

    安装的应用程序名叫in.telnetd。

    在本地测试:

  再找一台主机:

  这就是如何使用tcp_wrapper来作访问控制的。

 

    此外,在众多options中有一个特殊的应用,这种用法就是EXCEPT

    EXCEPT:意为除了;如在hosts.allow文件中定义:

  vsftpd:172.16. EXCEPT 172.16.100.1

    表示这个网络开放给172.16访问可是这个172.16.100.1不能访问。另外一个例子:

  vsftpd:172.16. EXCEPT 172.16.100.0/255.255.255.0 EXCEPT 172.16.100.1

    表示vsftpd开放给172.16.这个网络,可是不包括172.16.100.0这个网络,可是又包含172.16.100.1这个主机。

    如:

      自行测试!

 

[:options]

  •   deny:表示拒绝,主要用于host.allow文件中;在容许的文件中实现拒绝的功能;
  •   allow:表示容许,用于hosts.deny文件,实现allow的功能;

举例:

  /etc/hosts.allow文件中:

  vsftpd:192.168.241. :deny

  再如,/etc/hosts.allow:

  vsftpd:192.168.241. EXCEPT 192.168.241.6 :deny

  表示匹配192.168.241.6以外的192.168.241.0网络中的主机都拒绝(注意:这里只是不包含192.168.241.6这个主机即未匹配到,这条规则可以匹配到192.168.241.0网络中的全部主机可是不包含192.168.241.6)。

    /etc/hosts.deny:

  vsftpd:ALL

    (此处拒绝全部,因此刚才未匹配到的192.168.241.6也被拒绝了,最终的规则表示全部主机都不能访问)

 

  •   spawn

  表示启动额外应用程序;一旦被匹配到的话它能够启动,不作拒绝容许了,意思是你原本是拒绝的文件同样是拒绝,原本是容许的文件同样是容许,但额外它还能够启动其它应用程序。能够完成一部分的管理或其它功能。

      如在定义某一个服务时,若是说不容许访问的主机访问了,或者容许访问的主机访问了,均可以将其记录到日志里边来。

  举例:本地开放了ftp服务,可是不容许任何人访问,一旦有人访问了,将其记录到日志中:

    %c表示client ip,客户端地址,%s表示server ip,服务器端地址,%d为daomon name即访问的是服务器上的哪一个守护进程;

  iptables到此就告一段落了,指望把iptables中的网络防火墙和nat规则当作重点,nat转换和地址转换后,哪些容许访问哪些不容许访问呢?因此还能够把filter和nat结合起来使用。因此应该把nat当作重点。

相关文章
相关标签/搜索