iptables

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iptables相关的知识,希望对你有一定的参考价值。

iptables:
iptables/netfilter:包过滤器防火墙;
iptables:用户空间的命令
netfilter:位于内核中的tcp/ip协议的报文处理框架
Centos5/6:iptables命令编写规则
Centos7:firewalld建议关闭systemctl disable firewall.service

防火墙(Firewall):隔离工具;工作与主机或网络的边缘,对经过的报文根据预先定义的规则进行检测,对于能够被规则匹配到的报文实行某些预定义的处理机制的组件

硬件防火墙:在硬件级别 能实现部分的防火墙,另一部分功能要基于软件实现
软件防火墙:应用软件处理的逻辑运行通用于硬件实现的防火墙

主机防火墙:为当前主机提供服务
网络防火墙:为局域网提供服务

hook function:钩子函数
prerouting 刚刚进入本地
input 进入
forward 本地转换
output 本地出去
postprerouting 马上离开本地

iptables的链:
PREROUTING 刚刚进入
INPUT 进入
FORWARD 本地转换
OUTPUT 出去
POSTROUTING 马上离开本地

tables:
filter:过滤,防火墙
nat:network address translation 网络地址转化 :用于修改报文的源地址或目录地址,甚至是端口
mangle:拆解报文,做出修改,并重新封装起来
raw:关闭nat(网络地址转化)表上启用的连接追踪机制

优先级次序:raw-->mangle-->nat-->filter

功能<-->钩子
raw:PREROUTING,OUTPUT
mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
nat:PREROUTING,OUTPUT,OUTPUT,POSTROUTING
filter:INPUT,FORWARD,OUTPUT

报文的流向:
到本机某进程的报文:PREROUTING-->INPUT
由本机转发的报文:PREROUTING-->FORWARD-->POSTROUTING
由本机进程发出:OUTPUT-->POSTROUTING

规则的组成的部分:
匹配条件:
网络层首部属性值
传输层首部属性值
附加的条件
处理动作:

TCP/IP协议
数据链接层:物理到物理设备之间的通信
网络层:源主机到目标主机之间的通信
传输层:进程到进程之间的通信

iptables命令:
规则:根据指定的匹配条件来尝试每个流经过此处的报文,一旦匹配成功,就由规则后面指明的处理动作进行处理
匹配条件:
基本匹配条件:简单检查IP、TCP、UDP等报文的某属性进行匹配的机制
扩展匹配条件:需要借助于扩展模块进行的匹配条件指定即为扩展匹配
处理动作:
基本动作:ACCEPT,DROP,...
扩展动作:需要借组扩展模块进行的动作

添加规则之时需要考量的问题
    1、报文的流的路径,判断添加规则至哪个链上
    2、确定要实现的功能,判断添加规则至哪个表上
    3、指定匹配条件,以用于匹配目标白报文

iptabels的使用格式:
man iptables 以Centos7 为例:
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

    rule-specification = [matches...] [target]

   match = -m matchname [per-match-options]

   target = -j targetname [per-target-options]

规则的编写格式:iptables [-t table] COMMAND chain [-m matchname [per-match-options]] [-j targetname [per-target-options]]
    -t table:默认为filter;也可以用raw,mangle,nat

    命令:
      链:
        -P:policy,策略,定义默认策略 一般有两种选择,ACCEPT(同意)和DROP(终止)
        -N:new,新建一条自定义的规则链 被内建链上的规则调用才能生效
        -X:drop,删除自定义的引用计数为0空链
        -F:flush 清空一个表中的所有或者指定的链
        -E:重命名自定义的引用计数为0的链

      规则:
        -A:追加,在指定链的尾部追加一条规则
        -I:插入,在指定的位置插入一条规则  默认是第一条
        -D:删除,删除指定的规则
        -R:替换,将指定的规则替换成新规则 不能修改规则中部分,而是整条规则完全替换

      查看:
        -L:列出表的链上的规则
        -n:以数值格式显示
        -v:显示详细格式信息
        -x:计数器的精确结果
        --line-numbers:显示链中的规则编号

      计数器:
        规则,以及默认策略有专用的计数器
        记录被当前规则所匹配到的:
          1、报文个数
          2、字节总数

      重置规则计数器:
        -Z:zero,置0

      chain:链
        1、内建链
        2、自定义链

      匹配条件:
        多重条件:逻辑关系为“与”

        基本匹配条件:
          [!]-s, --source address[/mask][,...]:检查报文中的源IP地址是否符合此处指定的地址或范围
          [!]-d, --destination address[/mask][,...]:检查报文中的目标IP地址是否符合此处指定的地址或范围
          [!] -p, --protocol protocol
             protocol:{tcp|udp|tcp}
          [!] -i, --in-interface name  数据报文的流入接口 INPUT FORWARD and PREROUTING
          [!] -o, --out-interface name 数据报文的流出接口 FORWARD OUTPUT and POSTROUTING

        扩展匹配条件:
          隐式扩展:不用-m选择指出matchname(比赛名称)即可使用此match的专用选项进行匹配
          man iptables-extensions   详细说明
            -p tcp 隐含了 -m tcp
              [!] --source-port,--sport port[:port]:匹配报文中传输层的源端口
              [!] --destination-port,--dport port[:port]:匹配报文中传输层的目标端口
              [!] --tcp-flags mask comp
                SYN,ACK,FIN,RST,URG,PSH;
                mask 要检查的标志为列表,以逗号为分隔
                comp 必须为1的标志位,余下的出现在mask列表中的标志位就必须为0

                --tcp-flags SYN ACK FIN FIN RST SYN
              [!]--syn 相当于--tcp-flags SYN ACK FIN FIN RST SYN(三次握手)
            -p udp 隐含了-m udp
              [!] --source-port,--sport port[:port]:匹配报文中传输层的源端口
              [!] --destination-port,--dport port[:port]:匹配报文中传输层的目标端口
             -p lcmp 隐含了-m lcmp
              [!] --lcmp-type {type[/code]|typename}
                8:echo-request
                0:echo-reply

          显示扩展:必须使用-m选项指出matchname,有的match可能存在专用的选项

      处理动作(目标)
        -j targetname [perl-target-options]

        targetname:
          ACCEPT:接受
          DROP:丢弃
          REJECT:拒绝
事例:
    在172.20.126.229机器中不允许172.20.126.181访问
        229:iptables -A INPUT -s 172.20.126.181 -j DROP     不允许访问
        或者:
        229:iptables -A INPUT -s 172.20.126.181 -j REJECT  明确拒绝访问
            iptables -D INPUT 1     将第一条规则删除
            iptables -vnL --line-numbers |less  显示规则的序列号

    229:iptables -A INPUT -s 172.20.102.0/24 -j REJECT     将172.20.102.0/24的网段禁止访问;
    问题将102.71可以访问126.229的机器102.0/24的其他机器不能访问???
        229:iptables -I INPUT 2 -s 172.20.102.71 -j ACCEPT

    126.229机器中有一个这样的规则:iptables -A INPUT -s 172.20.126.181 -j REJECT,不要删除如何将其改成可访问的呢,规则在第二条???
        iptables -R INPUT 2 -s 172.20.126.181 -j ACCEPT

    问题:拒接172.20.126.181发送过来的ping包???
        iptables -A INPUT -s 172.20.126.181 -p icmp -j REJECT

    问题:在126.229本机中定义规则,可以ping通别人,别人无法ping自己如何实现:
        iptables -A INPUT -p icmp --icmp-type -j REJECT

    问题:在126.229的本机中禁止其他机器访问本机的80、21的端口:
        iptables -A INPUT -p tcp -m multiport --dports 21,80 -j REJECT

    问题:126.229机器只放行80端口,其他端口不允许访问???
        iptables -A INPUT -s 172.20.126.229 -j ACCEPT
        iptables -A OUTPUT -d 172.20.126.229 -j ACCEPT

        本机ip地址:192.168.31.124

        iptables -t filter -A INPUT -s 192.168.0.0/16 -d 192.168.31.124 -j ACCEPT   入站的全部放行
        iptables -t filter -A OUTPUT -d 192.168.0.0/16 -s 192.168.31.124 -j ACCEPT   出站的全部放行

        iptables -vnL   查看规则的信息
        Chain INPUT (policy ACCEPT 12 packets, 936 bytes)   进站报文
        pkts bytes target     prot opt in     out     source               destination         
        128 10216 ACCEPT     all  --  *      *       192.168.0.0/16       192.168.31.124      

        Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)       出站报文
        pkts bytes target     prot opt in     out     source               destination         
        12  1120 ACCEPT     all  --  *      *       192.168.31.124       192.168.0.0/16      

        事例:拒绝192.168.31.169主机连上192.168.31.124主机
        要是iptables 里面什么都没有的话:
          iptables -A INPUT -s 192.168.31.169 -d 192.168.31.124 -j REJECT
        要是iptables 里面有别的规则的话:
          iptables -I -s INPUT 192.168.31.169 -d 192.168.31.124 -j REJECT

        添加放行ssh 22端口:
        iptables -A INPUT -s 192.168.0.0/16 -d 192.168.31.124 -p tcp --dport 22 -j ACCECT
        iptables -A OUTPUT -d 192.168.0.0/16 -s 192.168.31.124 -p tcp --sport 22 -j ACCECT
        iptabels -P INPUT DROP
        iptables -P OUTPUT DROP
        iptables -P FORWARD DROP

        iptabels -vnL
        Chain INPUT (policy DROP 10 packets, 1027 bytes)
         pkts bytes target     prot opt in     out     source               destination         
          615 44372 ACCEPT     tcp  --  *      *       192.168.0.0/16       192.168.31.124       tcp dpt:22

        Chain FORWARD (policy DROP 0 packets, 0 bytes)
         pkts bytes target     prot opt in     out     source               destination         

        Chain OUTPUT (policy DROP 0 packets, 0 bytes)
         pkts bytes target     prot opt in     out     source               destination         
          310 41160 ACCEPT     tcp  --  *      *       192.168.31.124       192.168.0.0/16       tcp spt:22
        注意当添加玩规则之后 别人无法连上192.168.31.124这台主机 别人无法ping通你 192.168.31.124这台主机也无法连上别人 ping不出去的

        如果开放192.168.31.124主机可以ping别人的主机:    
        iptabels -A OUTPUT -s 192.168.31.124 -p icmp --icmp-type 8 -j ACCEPT        指定出去的是8 
        iptables -A INPUT -d 192.168.31.124 -p icmp --icmp-type 0 -j ACCEPT         指定进入的是0

        iptables -vnL
        Chain INPUT (policy DROP 650 packets, 65280 bytes)
         pkts bytes target     prot opt in     out     source               destination         
         1883  138K ACCEPT     tcp  --  *      *       192.168.0.0/16       192.168.31.124       tcp dpt:22
            4   336 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.31.124       icmptype 0

        Chain FORWARD (policy DROP 0 packets, 0 bytes)
         pkts bytes target     prot opt in     out     source               destination         

        Chain OUTPUT (policy DROP 194 packets, 15079 bytes)
         pkts bytes target     prot opt in     out     source               destination         
         1177  167K ACCEPT     tcp  --  *      *       192.168.31.124       192.168.0.0/16       tcp spt:22
            4   336 ACCEPT     icmp --  *      *       192.168.31.124       0.0.0.0/0            icmptype 8

        如果让别人也可以连接自己 ping自己的话:
        iptables -A INPUT -d 192.168.31.124 -p icmp --icmp-type 8 -j ACCEPT    
        iptables -A OUTPUT -s 192.168.31.124 -p icmp --icmp-type 0 -j ACCEPT 

        iptables -vnL 

        要是清空iptables内的规则的话:
        iptables -P INPUT ACCEPT
        iptables -P OUTPUT ACCEPT
        iptables -P FORWADR ACCEPT
        iptabels -F
        注意:千万不能直接iptables -F 不然就进入不了

扩展:
1、multiport扩展    多端口
  支持以离散或连续的方式定义多个端口匹配条件
        [!] --source-ports,--sports port[,port|,port:port]...:指定多个源端口
        [!] --destination-ports,--dports port[,port|,port:port]...:指定多个目标端口
        [!] --ports port[,port|,port:port]...:指定多个端口

    测试:主机地址:192.168.31.169
    yum -y install httpd telnet-server.x86_64 vsftpd.x86_64 mariadb-server.x86_64  做为测试
    systemctl start httpd.service telnet.socket     启动服务
    useradd CK      创建用户
    echo "chen" | passwd --stdin CK     给用户添加密码
    下面可以添加iptables规则:
    iptables -A INPUT -d 192.168.31.169 -p tcp -m multiport --dports 22:23,80 -j ACCEPT     开放进站的端口
    iptables -A OUTPUT -s 192.168.31.169 -p tcp -m multiport --dports 22:23,80 -j ACCEPT    开放出去的端口

    iptables -vnL
    Chain INPUT (policy ACCEPT 13 packets, 1264 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      167 11616 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.31.169       multiport dports 22:23,80

    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
       16  1416 ACCEPT     tcp  --  *      *       192.168.31.169       0.0.0.0/0            multiport sports 22:23,80

    iptables -A INPUT -j DROP       将所有进入本地的都给DROP
    iptables -A OUTPUT -j DROP      将所有出去的都给DROP

    iptables -vnL
    Chain INPUT (policy ACCEPT 90 packets, 8326 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      328 23012 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.31.169       multiport dports 22:23,80
        0     0 DROP       all  --  *      *       0.0.0.0/0            192.168.31.169      

    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      118 13996 ACCEPT     tcp  --  *      *       192.168.31.169       0.0.0.0/0            multiport sports 22:23,80
        4   304 DROP       all  --  *      *       192.168.31.169       0.0.0.0/0           

            注意:这是添加在开放端口规则的下面一条,如果在前面的话什么都无法连上去

2、iprange扩展  ip的范围扩展
  连续的ip地址范围指明连续的多地址匹配的条件
        [!] --src-range from[-to]:源IP地址;
        [!] --dst-range from[-to]:目标IP地址;

    iptables -vnL
     Chain INPUT (policy ACCEPT 90 packets, 8326 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      328 23012 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.31.169       multiport dports 22:23,80
        0     0 DROP       all  --  *      *       0.0.0.0/0            192.168.31.169      

    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
      118 13996 ACCEPT     tcp  --  *      *       192.168.31.169       0.0.0.0/0            multiport sports 22:23,80
        4   304 DROP       all  --  *      *       192.168.31.169       0.0.0.0/0           

    现在添加开放进入本地和出去的规则:
    iptables -I INPUT 2 -d 192.168.31.169 -p tcp --dport 3306 -m iprange --src-range 192.168.31.0-192.168.31.200 -j ACCEPT 
    iptables -I OUTPUT 2 -s 192.168.31.169 -p tcp --sport 3306 -m iprange --dst-range 192.168.31.0-192.168.31.200 -j 

    iptables -vnL
    Chain INPUT (policy ACCEPT 44 packets, 3932 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     2538  196K ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.31.169       multiport dports 22:23,80
        0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.31.169       tcp dpt:3306 source IP range 192.168.31.0-192.168.31.200
        0     0 DROP       all  --  *      *       0.0.0.0/0            192.168.31.169      

    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         

    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
     1830  224K ACCEPT     tcp  --  *      *       192.168.31.169       0.0.0.0/0            multiport sports 22:23,80
        0     0 ACCEPT     tcp  --  *      *       192.168.31.169       0.0.0.0/0            tcp spt:3306 destination IP range 192.168.31.0-192.168.31.200
       30  2046 DROP       all  --  *      *       192.168.31.169       0.0.0.0/0           

    测试启用之前安装的mariadb
    systemctl start mariadb.service     端口3306 

    mysql   给mysql添加一个用户和密码
    GRANT ALL ON *.* TO ‘root‘@‘%‘ IDENTIFIED BY ‘chen123‘;

    用192.168.31.124的主机mysql 测试连接mysql:
    mysql -uroot -h192.168.31.169 -pchen123     

3、string扩展   字符串扩展
 对报文中的应用层数据做字符串匹配检测

    [!] --string pattern:要检测字符串模式
    [!] --hex-string pattern:要检测的字符串模式,16进制编码

    测试:vim /var/www/html/test.html       192.168.31.169
           <h1>admin</h1>
    用192.168.31.124主机测试:
    curl http://192.168.31.169/test.html
    在添加一条规则:    注意:访问时ip地址必须是192.168.31.0-192.168.31.200地址范围内的地址才可访问
    iptables -I OUTPUT -s 192.168.31.169 -p tcp --sport 80 -m iprange ! --dst-range 192.168.31.0-192.168.31.200 -m string --string "admin" --algo kmp -j REJECT 

4、time扩展     时间扩展
  根据报文到达的时间与指定的时间范围进行匹配度检测

    --datestart YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:开始日期时间
    --datestop YYYY[-MM[-DD[Thh[:mm[:ss]]]]]:结束日期时间

    --timestart hh:mm[:ss]      开始时间
    [!] --weekdays day[,day...] 结束时间

    iptables -I INPUT -d 192.168.31.169 -p tcp --dport 23 -m time --timestart 18:00:01 --timestop 08:59:59 -j REJECT 
    iptables -I INPUT 2 -d 192.168.31.169 -p tcp --dport 23 -m time ! --weekdays Tue,Thu,Sat -j REJECT 
    或直接有一条命令解决:
    iptables -I INPUT -d 192.169.31.169 -p tcp --dport 23 -m time --timestart 09:00:00 --timestop 18:00:00 --weekdays Tue,Thu,Sat -j ACCEPT 

5、connlimit扩展
  根据每客户端ip做并发连接数匹配
  --connlimit-upto n:连接数的数量小于等于n,此时应该允许
  --connlimit-above n:连接数数量大于n,此时应该拒绝

  测试:
  iptables -A INPUT -p tcp --dport -m connlimit --connlimit-upto 2 -j ACCEPT
  检测192.168.31.124主机能都否登录192.168.31.169
  ssh [email protected]

6、limit扩展    
  基于收发报文的速率进行匹配

  --limit rate[/second|/minute|/hour|/day]:平均速率
  --limit-burst number:峰值速率

  限制访问的速率: 超出就会卡顿
  iptables -I INPUT -d 192.168.31.169 -p icmp --icmp-type 8 -m limit --limit-burst 5 --limit 20/minute -j ACCEPT 

7、state扩展
  状态检测;连接追踪机制(conntrack)

  INVALID 无法识别的状态
  ESTABLISHED 已建立的连接
  NEW 新连接
  RELATED 相关联的连接
  UNTRACKED 未追踪的连接

  nf_conntrack 内核模块
        追踪到的连接:/proc/net/nf_conntrack文件中

        能够追踪的最大连接数量定义在:/proc/sys/net/nf_conntrack_max
            此值可自行定义,建议必要时调整到足够大

        不同的协议的连接追踪的时长
            /proc/sys/net/netfilter

 [!]--state STATE
 如何开放被模式的ftp服务:
 (1) 装载追踪ftp协议的模块
    modprobe nf_conntrack_ftp

 (2) 放行命令连接
  iptables -A INPUT -d 192.168.31.169 -p tcp -m state --state ESTABLISHED -j ACCEPT
  iptables -A INPUT -d 192.168.31.169 -p tcp --dport 21 -m state --state NEW -j ACCEPT

 (3) 放行数据连接
 iptables -A INPUT -d 172.16.100.67 -p tcp -m state --state RELATED -j ACCEPT

 测试:启用mariadb服务监听3306的端口
systemctl start mariadb.service
添加规则:
iptables -A INPUT -d 192.168.31.169 -m state --state ESTABLISHED -j ACCEPT
iptables -A OUTPUT -s 192.168.31.169 -m state --state ESTABLISHED -j ACCEPT

iptables -A INPUT -d 192.168.31.169 -p tcp -m multiport --dports 21,22,23,80,3306 -m state --state NEW -j ACCEPT   开放后面进入的端口
iptables -A INPUT -d 192.168.31.169 -j DROP
iptables -A OUTPUT -s 192.168.31.169 -j DROP

启用vsftpd:
systemctl start vsftpd.service

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

modprobe nf_conntrack_ftp   装载这个模块:nf_conntrack_ftp
lsmod | grep conntrack  用于查看启用的模块
 nf_conntrack_ftp       18638  0 

用另外一台192.168.31.169主机测试能否登录上ftp
[[email protected] ~]# ftp 192.168.31.169
Connected to 192.168.31.169 (192.168.31.169).
220 (vsFTPd 3.0.2)
Name (192.168.31.169:root): chen
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
227 Entering Passive Mode (192,168,31,169,161,77).
150 Here comes the directory listing.
drwxr-xr-x    2 1000     1000            6 May 12  2016 Desktop

保存和重新载入的规则:
iptables-save 后面跟路径 相当于将规则存入一个文件
iptables-restore 后面跟路径 相当于把规则文件重新载入

演示:
iptables-save > /etc/sysconfig/iptable.guiz     将规则存入这个文件
iptables -F     清除所有规则
iptables-restore < /etc/sysconfig/iptable.guiz  将规则文件重新读取 

centos6:开机自动启动:
保存规则:
    service iptables save
    自动保存规则至/etc/sysconfig/iptables文件中;
重载规则:
    server iptables restore
        从/etc/sysconfig/iptables文件中重载规则

规则的优化:
1、可以安全放行所有入站及出站,并且状态为ESTABLISHED的连接
2、服务于同一类功能的规则,匹配条件严格的放前面,宽松的放后面
3、服务于不同功能的规则,匹配报文可能性较大的扩前面,较小的放在后面
4、设置默认策略
(1)最后一条规则设定
(2)默认策略设定

以上是关于iptables的主要内容,如果未能解决你的问题,请参考以下文章

CentOS中iptables防火墙 开放80端口方法

Iptables 网络安全

iptables防火墙

iptables基础知识

Linux中iptables防火墙指定端口范围

iptables防火墙