iptables基本应用

iptables概述

iptables是一个规则管理工具,它能实现规则的:

    添加、修改、删除、显示等相关功能;当然也能完成默认规则的定义等等。

    另外iptables还有一个好处在于在实现规则添加时它能自动完成规则的语法检查。

    其实iptables所有规则编写好后都是送往内核的netfilter上去的,而netfilter的功能输出是通过一个系统调用来输出的。所以我们也可以自己编写规则并调用系统调用将规则送进去,不过,对于我们来讲,像这种我们编写的规则即便送进去后万一出现语法错误的话将会造成netfilter工作异常,所以就开发了一个专门的能帮我们去检查语法编写规则并将规则直接通过系统调用送往netfilter的一个工具即iptables

  对于iptables来讲,添加到内核的称为规则,规则要添加到链上,而为了统计每一条规则被放置到链上后它匹配到了多少个报文。所以:规则和链是有计数器的;它能显示自己从启用开始到此刻为止一共匹配到多少个数据包等等。而每一个规则和每一个链自己默认都有两个计数器:

    pkts:由规则或链所匹配到的报文的个数;

    bytes:(字节数)由规则或链匹配到的所有报文大小之和;

  

iptables命令

基本语法:

  iptables [-t table](table省略的话默认是filter) SUBCOMMAND(子命令) CHINA(指定对于表的哪一个链进行管理) CRETERIA(匹配标准) -j TARGET(指明处理动作)
  iptables [-t table] {-A|-C|-D} chain rule-specification
  ip6tables [-t table] {-A|-C|-D} chain rule-specification
  iptables [-t table] -I chain [rulenum] rule-specification
  iptables [-t table] -R chain rulenum rule-specification
  iptables [-t table] -D chain rulenum
  iptables [-t table] -S [chain [rulenum]]
  iptables [-t table] {-F|-L|-Z} [chain [rulenum]] [options...]
  iptables [-t table] -N chain
  iptables [-t table] -X [chain]
  iptables [-t table] -P chain target
  iptables [-t table] -E old-chain-name new-chain-name

 注意:

  •   iptables在编写的时候通常指定一个子命令,指明这个子命令作用在哪个链上并且在这个链上匹配规则时有什么样的匹配标准,一旦匹配到以后我们做出什么样的处理。不过不同的命令和用法是不一样的。
  •     -t table:table一共只有四个:filter、nat、mangle、raw,省略为filter;

   

这些子命令大致可以分为两类:

  一类是对链管理的(链管理命令):

  -F:flush,清空规则链;省略链,表示清空指定表上的所有的链;
  -N:new,创建新的自定义规则链(不能重名);
  -X:drop,删除用户自定义的空的规则链(如果有规则需要使用-F清空);
  -Z:zero,清零,置零规则计数器的;
  -P:Policy,为指定链设置默认策略;对于filter表中的链而言,默认策略通常有ACCEPT(放行报文)、DROP(丢弃报文,类似于对方ping时不存在主机)、REJECT(拒绝报文);
  -E:rEname,重命名自定义链;引用(使用-j把一个链放在target的时候就叫引用)计数不为0的自定义链无法改名,也无法删除;

  一类是对规则管理的(规则管理命令):

  -A:append,将新的规则追加于指定链的尾部;
  -I:insert,将新规则插入指定链的指定位置;(按规则编号进行指定),省略时表示链的第一条。
  -D:delete,删除指定链上的指定规则:
  -R:replace,替换指定链上的指定规则;

   规则有两种指定方式:

  • (1)  指定匹配条件;
  • (2)  指定规则标号

          

查看:

  -L :list,列出指定链上的所有规则;(-L在应用时,它与此前的route或netstat命令一样,由于能显示出IP地址和端口来所以它总是会反解,那反解带来的结果是速度会很慢)
  -n:numberic,以数字格式显示地址和端口号;即不反解
  -v:verbose,显示详细信息;(可以显示出规则计数器)
  -vv,-vvv(v越多显示的格式越详细)
  --line-numbers:显示规则编号;(在一个链上如果有多条规则出现的话,对这个链上的规则编号后显示)
  -x:exactly,显示计数器计数结果的精确值,每一个链即每一个链上都有计数器,当这个计数器的数量很大时,它会自动做单位换算,而且单位换算后可能会自动取整,
    得到的值就不是精确结果了,所以如果不期望其自动单位换算就使用此选项。

举例:

  删除所有用户自定义的空链:

  重命名:

  重启查看:

    port:协议,一般只有TCP、UDP、ICMP三种;

    opt:选项;

    source:表示指明匹配源地址的范围;

    destination:指明匹配目标地址;

    ctstate:连接追踪机制;

  使用-v时每条规则前多了两个计数器:

  修改链的默认策略:

  重启服务:

  显示规则对应的编号:

  删除其第七条规则:

  显示更详细的信息:

  不做单位换算:

规则的匹配条件:

 (1).基本匹配(通用匹配)

  • [!](中括号表示可省,!为取反) -s、-src、--source IP|Netaddr(不加!表示正向匹配,加!表示反向匹配即不被所指定地址所包含的反而是符合条件的):检查报文中的源IP地址是否符合或是否属于此处指定的地址范围;
  • [!] –d、--dest、--destination IP|Netaddr:检查报文中的目标IP地址是否符合此处指定的地址范围(INPUT和OUTPUT的源地址和目标地址是不一样的,一般是相反的)
  • [!] –p、--protocol {tcp|udp|icmp}(此处协议为传输层协议):检查报文中的协议,即IP首部中的protocols所标识的协议;
  • [!] –i、--in-interface INTERFACE:数据报文的流入接口(从哪个接口进入本机的,假如有三块网卡,只对第一块网卡做数据流入检查);仅能用于PREROUTING、INPUT、FORWARD链上;
  • [!] –o、--out-interface INTERFACE:检查数据报文的流出接口;仅能用于FORWARD、OUTPUT、POSTROUTING链上;

 (2).扩展匹配:(支持添加额外的模块实现动态扩展功能)

  查看扩展可使用:

  扩展实现的功能分为两类,一类为对检查的匹配条件做扩展,二为对目标做扩展,像SNAT、REJECT、LOG…就是通过模块来完成的。大写的都是TARGET,小写的都是可以做匹配条件的。而对于协议来讲,协议本身还可以做一些扩展,所以当使用扩展匹配时需要使用-m MATCH_NAME指明我们要使用扩展匹配了,然后每一个扩展都有自己的专用选项,使用--spec_options,例如想检查TCP端口号:-m tcp –dport 22表示使用TCP扩展,而这个扩展有一个专用选项叫做dport,而我们匹配到的22号端口。

       隐式扩展:对-p protocol指明的协议进行的扩展,可省略-m选项;

       隐式扩展指的是,如:已经使用-p指明TCP了,上述例子的-m tcp就可以不用写了。对tcp、upd、ICMP等协议进行扩展时,如果使用-p已经指明是哪种协议了,而-m再指明加载这个协议不用再写,这就是隐式扩展。

  •        -p tcp

           有三个扩展:

      •   --dport PORT[-PORT]:目标端口匹配,可以是单个端口,也可以是连续多个的端口;
      •   --sport PORT[-PORT]:匹配源端口,可以是单个端口,也可以是连续多个的端口;
      •   --tcp-flags LIST1 LIST2:用来指明检查者六个标识位中的哪些个并且哪些个必须为1哪些个必须为0。检查LIST1所指明的所有标识位,且这其中LIST2所表示出的所有标识位必须为1,而余下的必须为0;没在LIST1中指明的,不做检查;

        标识位如下:

                  SYN(请求同步)、ACK(确认号有效)、FIN(断开请求)、RST(重置连接)、PSH(Push,推送,表示收到一个报文后,不要在缓存队列中缓存而是立即送给应用程序)、URG(紧急指定有效)

                例:--tcp-flags SYN,ACK,FIN,RST SYN    #表示只检查SYN、ACK、FIN、RST这四个位,PSH和URG是什么都行,单这四个位中要求SYN必须为1,其它必须为0;相当于TCP三次握手的第一次。还有一个简写方式叫—syn(检查是否为新建TCP连接的第一次请求)

  •        -p udp
    •   --dport
    •   --sport
  •        -p icmp

            --icmp-type:ICMP报文类型非常多,可以去搜索ICMP Type。

         可用数字表示其类型:0(echo-reply回显应答)、8(echo-request)(ping别人发送的报文类型为8,别人给的响应报文类型为0),在匹配时,通常只需要限制0和8。请求和应答不一样这带给我们的直接结果就是可以让主机ping别人,别人不能ping我们,仅允许出去的是8,进来的是0,那么如果进来的是8那就别人进不来了。

      显示扩展:必须使用-m选项指定使用的扩展;(到后面在进行详细介绍)

目标(TARGET)(即匹配到条件后的执行动作):

    -j TARGET:jump,跳转到指定TARGET处理

    TAEGET

  •        ACCEPT(接受)
  •        DROP(丢弃)
  •        REJECT(拒绝)
  •        RETURN(返回至调用链)
  •        REDIRECT(端口重定向,如:本来访问的80改为8080)
  •        LOG(记录日志,将访问记录至日志文件中)
  •        MARK(做防火墙标记)
  •        DNAT(目标地址转换)
  •        SNAT(源地址转换)
  •        MASQUERADE(地址伪装)
  •     …
  •        自定义链(由自定义链上的规则进行匹配检查;使用自定义链是因为当一个链上的规则过多时可以把功能相近的放在一个链上将来做单独管理)

编写规则示例:

  凡是访问本机的报文属于TCP协议的统统都放行:

  凡是由本机发送出去的TCP报文跟任何主机通信都允许出去:

  将filter表的所有链的默认策略都改为DROP:

    因此,此时只要不是TCP协议的统统DROP,将访问不成,而ssh协议是TCP协议,因此远程连接不会断开。因此先写的那两个规则是让远程连接不断开的至关重要的前提。

 

  此时非TCP协议的就无法访问了:

  修改ICMP允许INPUT:

  但是此时为什么还是不行呢?

  因为响应报文无法发送出去,因此还是不能通信。

  添加一条规则即可:

  将来要拒绝某个人访问,可在INPUT与OUTPUT实现,当然最好是在INPUT上拒绝,防患于未然。

  注意:为了防止写规则时一不小心拒绝了SSH远程连接命令,尤其是测试新规则时,可做如下处理:

    或者:将iptables后的-F改成-P,INPUT与OUTPUT为ACCEPT

    或者:也可以定义一个近期任务计划10分钟后执行,写一个脚本,将所有策略统统置为ACCEPT,把所有规则统统清空,让其5分钟后再执行。先提醒一个任务计划测这个脚本,一测连不上去,等5分钟即可。

 

  下面我们来做流入报文接口限制:

  那么放行ssh服务时怎么只单独放行一个而非是所有TCP协议的端口呢?我们来试试:

    测试一下:

      使用Web服务作比较:

      删除其它规则后:

      测试:

        此时无法访问;

        要想Web服务可以被访问,需要开启80端口,自己动手实现即可。

  实现允许ping别人,不允许别人ping自己,演示:

猜你喜欢

转载自www.cnblogs.com/long-cnblogs/p/10660425.html