• linux iptables


    • 查看防火墙是否启动

      systemctl status firewalld.service

    • 启动/停止防火墙服务

      systemctl start/stop firewalld.service

    • 查看iptables里的表项:iptables -vnL

    • 清空iptabls里的规则:

      iptables -F

    iptables:包过滤型的防火墙

    • Firewall:防火墙,隔离工具,工作主机或网络边缘,对于进出本主机或网络的的报文,根据事先定义的检查规则做匹配检测,做出响应的处理
    • Firewall分类1:
      • 主机防火墙:设置进入本机进程的规则
      • 网络防火墙:设置转发的规则
    • Firewall分类2:
      • 软件防火墙:一般的pc,安装上linux系统,在软件上设置规则
      • 硬件防火墙:专门的cpu,在cpu指令级别设置规则,效率比软件防火墙高,但是价格很贵,cisco有专门的硬件防火墙。

    linux历代软件防火墙产品:

    • ipfw(firewall framework)
    • ipchains(firewall framework)
    • iptables(netfilter)
      • netfilter:kernel
      • iptables:rules until
    • iptables hook function
      • input
      • output
      • forward
      • prerouting
      • postrouting
    • 链(内置)
      • PREROUTING
      • INPUT
      • FORWARD
      • OUTPUT
      • POSTROUTING

    功能:

    • filter:过滤,防火墙
    • nat:network address translation:用于修改源IP或目的IP,也可以修改端口
    • mangle:拆解报文,做出修改,并重新封装起来
    • raw:关闭net表的连接追踪机制

    功能<--链:

    • raw:PREROUTING,OUTPUT
    • mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
    • nat:PREROUTING,[INPUT],OUTPUT,POSTROUTING
    • filter:INPUT,FORWARD,OUTPUT

    报文流向:

    • 流入本机:PREROUTING->INPUT
    • 由本机流出:OUTPUT->POSTROUTING
    • 转发:PREROUTING->FORWARD->POSTROUTING

    路由功能发生的时刻:

    • 报文进入本机后:判断目标主机是什么
    • 报文离开本机之前:判断经由哪个接口,送到下一跳

    优先顺序:

    iptables/netfilter概要

    1,规则

    • 组成部分:根据规则匹配来尝试匹配报文,一旦匹配成功,就由规则定义的处理动作作出处理。
      • 匹配条件:
        • 基本匹配条件:内核自带的
        • 扩展匹配条件:由扩展模块提供(使用rpm -ql iptables查看)
      • 处理动作:
        • 基本动作处理:内核自带的
        • 扩展动作处理:由扩展模块提供(使用rpm -ql iptables查看)
        • 自定义处理:自定义链
    • iptables的链:内置链和自定义链
      • 内置链:对应于hook function
      • 自定义链:用于内置链的扩展和补充,可实现更灵活的管理机制

    2,添加规则是的注意

    • 根据要实现的功能,判断把规则添加到相应的表上
    • 根据报文流经的方向,判断添加到哪个链上

    3,规则书写的次序

    • 同类规则,匹配范围越精确的,放到上面书写
    • 不同类规则(比如http和ssh),匹配到报文频率大的放在上面
    • 尽量将那些可由一条规则描述的多个规则合并起来
    • 设置默认策略(是白名单还是黑名单)

    4,查看都有哪些扩展模块

    使用rpm -ql iptables查看都有哪些扩展模块。

    小写字母是匹配条件(match)要使用的扩展模块;大写字母是处理动作(target)要使用的扩展模块

    • libip6t_:对于IPv6
    • libipt_:对于IPv4
    • libxt_:对于IPv4
    /usr/lib64/xtables/libip6t_DNAT.so
    /usr/lib64/xtables/libip6t_DNPT.so
    /usr/lib64/xtables/libip6t_HL.so
    /usr/lib64/xtables/libip6t_ah.so
    /usr/lib64/xtables/libip6t_dst.so
    /usr/lib64/xtables/libipt_DNAT.so
    /usr/lib64/xtables/libipt_ECN.so
    /usr/lib64/xtables/libipt_ah.so
    /usr/lib64/xtables/libipt_icmp.so
    /usr/lib64/xtables/libxt_AUDIT.so
    /usr/lib64/xtables/libxt_CHECKSUM.so
    /usr/lib64/xtables/libxt_addrtype.so
    /usr/lib64/xtables/libxt_bpf.so
    
    

    iptables命令格式

    格式:iptables [-t table] COMMAND chain [-m matchname [per-match-options]] -j targetname [per-target-options]

    • -t table:raw,mangle,nat,[fliter]

    • COMMAND:

      • 链管理:

        -N:new,自定义一条规则链

        -X:delete,删除自定义的规则链;只能删除自定义链,且引用是0,且是空的链(链上没有规则)。

        -P:Policy,设置默认策略;对filter表中的链而言,其默认策略有:

        • ACCEPT:允许(白名单策略),内嵌的策略
        • DROP:丢弃(黑名单策略),内嵌的策略。推荐使用此策略。不给对方响应,所以对方不知道你是怎么处理的。
        • REJECT:不允许,扩展的策略。会给对方响应。对方会马上知道,你拒绝了。

        -E:重命名自定义链;引用计数不为0的自定义链不能被重命名,也不能被删除

      • 规则管理:

        -A:append,追加

        -I:insert,插入,要指明位置,省略时表示插入到首行之前

        -D:delete,删除

        • 指明规则序号
        • 指明规则本身

        -R:replace,替换指定链上的指定规则

        -F:flush,清空指定的规则链

        -Z:zero,置零。iptables的每条规则都有2个计数器:

        • 匹配到的报文的个数
        • 匹配到的报文的大小之和
      • 查看:

        -L:list,列出指定链上的所有规则

        -n:numberic,以数字格式显示地址和端口号

        -v:verbose,显示详细信息。-vv:更详细;-vvv:更更详细。

        -x:exactly,显示计数器接口的精确值

        --line-numbers:显示规则的序号

    • chain:

      PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING

    • matchname (匹配条件)

    查看表和链

    1,查看各个表

    # iptables -t raw -L
    # iptables -t mangle -L
    # iptables -t nat -L
    # iptables -L
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
    num      pkts      bytes target     prot opt in     out     source               destination
    1         213    16360   ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0 
    2           0        0   ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    
    • Chain:链名
    • policy:策略
    • num:行号
    • packets:报文个数的计时器
    • bytes:报文的大小之和的计时器
    • target:处理内容
    • prot:协议
    • opt:选项
    • in:入接口
    • out:出接口
    • source:源网络地址
    • destination:目的网络地址

    2, 查看某个表的某个链

    # iptables -t mangle -vnxL INPUT --line-numbers
    Chain INPUT (policy ACCEPT 366 packets, 30889 bytes)
    num      pkts      bytes target     prot opt in     out     source               destination
    1         366    30889 INPUT_direct  all  --  *      *       0.0.0.0/0            0.0.0.0/0
    

    修改链

    1,新建/删除自定义链

    # iptables -N in_web
    # iptables -vnL
    Chain INPUT (policy ACCEPT 33 packets, 2408 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain OUTPUT (policy ACCEPT 18 packets, 1920 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain in_web (0 references)
     pkts bytes target     prot opt in     out     source               destination
    # iptables -X in_web
    # iptables -vnL
    Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain OUTPUT (policy ACCEPT 4 packets, 480 bytes)
     pkts bytes target     prot opt in     out     source               destination
    

    2,重命名自定义链

    # iptables -N old
    # iptables -E old new
    # iptables -L
    Chain INPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    
    Chain OUTPUT (policy ACCEPT)
    target     prot opt source               destination
    
    Chain new (0 references)
    target     prot opt source               destination
    

    3,修改处理动作(策略)。

    不要上来就把INPUT链上的所有协议都改成DROP,DROP后,自己的不能远程连接主机了。至少要保留ssh协议。

    # iptables -t mangle -L FORWARD
    Chain FORWARD (policy ACCEPT)
    target     prot opt source               destination
    # iptables -t mangle -P FORWARD DROP
    # iptables -t mangle -L FORWARD
    Chain FORWARD (policy DROP)
    target     prot opt source               destination
    

    更新规则

    1,添加/删除规则

    # iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.1.103 -p tcp
    # iptables -vnL
    Chain INPUT (policy ACCEPT 8 packets, 576 bytes)
     pkts bytes target     prot opt in     out     source               destination
        0     0            tcp  --  *      *       192.168.56.0/24      192.168.1.103
    # iptables -t filter -D INPUT -s 192.168.56.0/24 -d 192.168.1.103 -p tcp
    # iptables -vnL
    Chain INPUT (policy ACCEPT 8 packets, 576 bytes)
     pkts bytes target     prot opt in     out     source               destination
     
    # iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p tcp
    # iptables -vnL INPUT
    Chain INPUT (policy ACCEPT 20 packets, 1440 bytes)
     pkts bytes target     prot opt in     out     source               destination
       20  1440            tcp  --  *      *       192.168.56.0/24      192.168.56.103
    # iptables -t filter -D INPUT 1
    # iptables -vnL INPUT
    Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    

    添加放行tcp协议的规则后(ssh使用tcp),就可以把规则修改成DROP了。但是就ping不通192.168.56.103

    # iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p tcp -j ACCEPT
    # iptables -t filter -P INPUT DROP
    # iptables -vnL INPUT
    Chain INPUT (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
       88  6336 ACCEPT     tcp  --  *      *       192.168.56.0/24      192.168.56.103
    

    由于ping使用的是icmp协议,所有要添加可以进来和可以出去的icmp协议的规则

    # iptables -t filter -A INPUT -s 192.168.56.0/24 -d 192.168.56.103 -p icmp -j ACCEPT
    # iptables -t filter -A OUTPUT -d 192.168.56.0/24 -s 192.168.56.103 -p icmp -j ACCEPT
    # iptables -vnL
    Chain INPUT (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
      378 30432 ACCEPT     tcp  --  *      *       192.168.56.0/24      192.168.56.103
        4   240 ACCEPT     icmp --  *      *       192.168.56.0/24      192.168.56.103
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain OUTPUT (policy DROP 18 packets, 2640 bytes)
     pkts bytes target     prot opt in     out     source               destination
       27  3144 ACCEPT     tcp  --  *      *       192.168.56.103       192.168.56.0/24
        4   240 ACCEPT     icmp --  *      *       192.168.56.103       192.168.56.0/24
    
    # ping 192.168.56.103
    PING 192.168.56.103 (192.168.56.103) 56(84) bytes of data.
    64 bytes from 192.168.56.103: icmp_seq=1 ttl=64 time=0.042 ms
    

    接口

    # iptables -t filter -A INPUT -i enp0s3 -j REJECT
    # iptables -t filter -A OUTPUT -o enp0s3 -j REJECT
    # iptables -vnL
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
      506 39408 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 22,80
        0     0 REJECT     all  --  enp0s3 *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    
    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
      207 25960 ACCEPT     tcp  --  *      *       192.168.56.103       0.0.0.0/0            multiport sports 22,80
        0     0 REJECT     all  --  *      enp0s3  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    

    使用扩展模块

    使用man iptables-extensions查看扩展模块的帮助信息。

    隐式使用:

    1,tcp

    • [!]--source-port,--sport port[:port]:匹配报文的源端口,可以是端口范围

    • [!]--destination-port,--dport port[:port]:匹配报文的目的端口,可以是端口范围

    • [!]--tcp-flags mask comp

      mask is the flags which we should examine,written as a comma-seperator list,例如SYN,ACK,FIN,RST

      comp is a comma-seperator list of flags which must be set ,例如SYN

      例如:--tcp-flags SYN,ACK,FIN,RST SYN表示,要检查的标识位是SYN,ACK,FIN,RST四个,其中SYN必须为1,其他必须为0.

    • --syn:用于匹配第一次握手,相当于--tcp-flags SYN,ACK,FIN,RST SYN

    例子:开放ssh

    # iptables -I INPUT 1 -d 192.168.56.103 -s 192.168.56.0/24 -p tcp --dport 22 -j ACCEPT
    # iptables -I OUTPUT 1 -s 192.168.56.103 -d 192.168.56.0/24 -p tcp --sport 22 -j ACCEPT
    # iptables -vnL
    Chain INPUT (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
      523 40120 ACCEPT     tcp  --  *      *       192.168.56.0/24      192.168.56.103       tcp dpt:22
       28  1968 ACCEPT     icmp --  *      *       192.168.56.0/24      192.168.56.103
    
    Chain FORWARD (policy ACCEPT 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
       95 45704 ACCEPT     tcp  --  *      *       192.168.56.103       192.168.56.0/24      tcp spt:22
        4   240 ACCEPT     icmp --  *      *       192.168.56.103       192.168.56.0/24
    

    2,udp

    • [!]--source-port,--sport port[:port]:匹配报文的源端口,可以是端口范围
    • [!]--destination-port,--dport port[:port]:匹配报文的目的端口,可以是端口范围

    3,icmp

    • [!]--icmp-type {type[/code]|typename}

      • echo-request:8
      • echo-reply:0
      # iptables -t filter -I INPUT -d 192.168.56.103 -p icmp --icmp-type 8 -j ACCEPT
      # iptables -t filter -I OUTPUT -s 192.168.56.103 -p icmp --icmp-type 0 -j ACCEPT
      [root@localhost ~]# iptables -vnL INPUT
      Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination
         14  1176 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.56.103       icmptype 8
      [root@localhost ~]# iptables -vnL OUTPUT
      Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination
         14  1176 ACCEPT     icmp --  *      *       192.168.56.103       0.0.0.0/0            icmptype 0
      

    显示使用:

    1, multiport:以离散或连续的方式定义多端口匹配条件,最多15个。

    • [!] --source-ports,--sports port[,port|,port:port]...
    • [!] --destination-ports,--dports port[,port|,port:port]...
    • [!] --ports port[,port|,port:port]...

    例子:可以进和出:22和80端口

    先启动httpd(80端口),nmb(149端口),smb(445端口)服务:systemctl start httpd nmb smb

    在/var/www/html/目录下,创建文件index.html,里面随便写点内容。然后用浏览器访问一下,发现无法访问,原因是没有允许80端口进来和出去。添加让80进来和出去的规则就可以用浏览器访问了。

    在另一台机器上使用smbclient -L 192.168.56.103访问本机的smb服务,发现无法访问,原因是没有允许445端口进来和出去。添加让445进来和出去的规则就可以用浏览器访问了。

    # iptables -t filter -A INPUT -d 192.168.56.103 -p tcp -m multiport --dports 22,80 -j ACCEPT
    # iptables -t filter -A OUTPUT -s 192.168.56.103 -p tcp -m multiport --sports 22,80 -j ACCEPT
    # iptables -vnL
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
      140 12192 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 22,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
        5   968 ACCEPT     tcp  --  *      *       192.168.56.103       0.0.0.0/0            multiport sports 22,80
    

    2,iprange:指定连续地址

    • [!] --src-range from[-to]
    • [!] --dst-range from[-to]

    例子:

    # iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -j ACCEPT
    

    3,time:指定包进来或者出去的时间区间

    • --timestart hh:mm[:ss]
    • --timestop hh:mm[:ss]
    • [!] --monthdays day[,day...]
    • [!] --weekdays day[,day...]
    • --kerneltz:使用内核配置的时区,而非默认的UTC

    例子:不使用--kerneltz就是UTC时间。

    # iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -m time --timestart 4:00:00 --timestop 14:00:00 --weekdays 1,2,3,4,5  -j ACCEPT
    # iptables -vnL
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
        6   432 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 22:23,80,445 source IP range 192.168.56.1-192.168.56.105 TIME from 04:00:00 to 14:00:00 on Mon,Tue,Wed,Thu,Fri UTC
    # iptables -t filter -R INPUT 1 -d 192.168.56.103 -p tcp -m multiport --dports 22:23,80,445 -m iprange --src-range 192.168.56.1-192.168.56.105 -m time --timestart 4:00:00 --timestop 14:00:00 --weekdays 1,2,3,4,5  --kerneltz -j ACCEPT
    Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
        6   432 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 22:23,80,445 source IP range 192.168.56.1-192.168.56.105 TIME from 04:00:00 to 14:00:00 on Mon,Tue,Wed,Thu,Fri
    

    4,string:匹配数据包里数据区域的关键字

    明文的数据包才能匹配,比如http;加密的是无法匹配的,比如ssh,https等。

    • --algo {bm|kmp}

    • [!] --string pattern

    • [!] --hex-string pattern

    • --from offset

      Set the offset from which it starts looking for any matching. If not passed, default is 0.

    • --to offset

    例子:文件/var/www/html/test.html里如果有“abc”字符的话,则在无法访问test.html。

    # iptables -t filter -R OUTPUT 1 -s 192.168.56.103  -m string --algo bm --string "abc" -j REJECT
    # iptables -vnL OUTPUT
    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
        6  2202 REJECT     all  --  *      *       192.168.56.103       0.0.0.0/0            STRING match  "abc" ALGO name bm TO 65535 reject-with icmp-port-unreachable
     3090  416K ACCEPT     tcp  --  *      *       192.168.56.103       0.0.0.0/0            multiport sports 22:23,80,445
      851  207K REJECT     all  --  *      enp0s3  0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    

    5,connlimit:允许同一个客户端ip,同时连进来的数量

    • --connlimit-upto n

      小于等于n

    • --connlimit-above n

      大于n

    例子:控制来自同一个客户端ip,连接到mysql的数量为2,超过2个就连不上mysql

    创建一个可以远程连接的用户test。

    mysql> CREATE USER 'test'@'192.168.56.%' IDENTIFED BY '1'
    

    远程登录mysql命令:mysql -utest -h192.168.56.103 -p1

    # iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --dport 3306 -j ACCEPT
    # iptables -t filter -I OUTPUT 2 -s 192.168.56.103 -p tcp --sport 3306 -j ACCEPT
    

    例子:同一个客户端ip过来的第一次握手超过2次,就拒绝。

    # iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --syn --dport 22 -m connlimit --connlimit-above 2 -j REJECT
    

    6,limit:限制流量

    • --limit-burst number

    • --limit rate[/second|/minute|/hour|/day]

      Maximum average matching rate: specified as a number

    例子:每分钟接收20个ping,从第6个开始计时,也就是说前5个不限速。

    从下面ping的结果可以看出来,从第7个开始,由于限速的原因,就有丢失的发生了。

    # iptables -t filter -R INPUT 1 -d 192.168.56.103 -p icmp --icmp-type 8 -m limit --limit 20/m --limit-burst 5 -j ACCEPT
    $ ping 192.168.56.103
    PING 192.168.56.103 (192.168.56.103) 56(84) bytes of data.
    64 bytes from 192.168.56.103: icmp_seq=1 ttl=64 time=0.476 ms
    64 bytes from 192.168.56.103: icmp_seq=2 ttl=64 time=0.521 ms
    64 bytes from 192.168.56.103: icmp_seq=3 ttl=64 time=1.03 ms
    64 bytes from 192.168.56.103: icmp_seq=4 ttl=64 time=0.998 ms
    64 bytes from 192.168.56.103: icmp_seq=5 ttl=64 time=0.211 ms
    64 bytes from 192.168.56.103: icmp_seq=6 ttl=64 time=1.01 ms
    64 bytes from 192.168.56.103: icmp_seq=7 ttl=64 time=0.919 ms
    64 bytes from 192.168.56.103: icmp_seq=10 ttl=64 time=0.446 ms
    64 bytes from 192.168.56.103: icmp_seq=13 ttl=64 time=0.888 ms
    64 bytes from 192.168.56.103: icmp_seq=16 ttl=64 time=0.331 ms
    64 bytes from 192.168.56.103: icmp_seq=19 ttl=64 time=0.370 ms
    64 bytes from 192.168.56.103: icmp_seq=22 ttl=64 time=0.901 ms
    

    7,state:是conntrack模块的子集,根据报文的状态,设置规则

    • conntrack模块把追踪到的报文,记录在内核使用的内存空间(把这个空间起名叫追踪表),这个空间的大小可以配置(/proc/sys/net/nf_conntrack_max),记录的内容记录还会保存在文件:/proc/net/nf_conntrack。由于要浪费内存和CPU所有,高并发的主机不建议开启此模块(conntrack),开启此功能后,分分钟被搞死。
    # cat /proc/net/nf_conntrack
    ipv4     2 unknown  2 487 src=192.168.56.103 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=192.168.56.103 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
    ipv4     2 unknown  2 494 src=192.168.122.1 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=192.168.122.1 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
    ipv4     2 unknown  2 486 src=10.0.3.15 dst=224.0.0.22 [UNREPLIED] src=224.0.0.22 dst=10.0.3.15 mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
    ipv4     2 tcp      6 299 ESTABLISHED src=192.168.56.1 dst=192.168.56.103 sport=53243 dport=22 src=192.168.56.103 dst=192.168.56.1 sport=22 dport=53243 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2
    
    • 配置追踪表里各种协议条目的老化时长的配置文件:/proc/sys/net/netfilter/*timeout*

      也就是过多久,把追踪表里的条目删除掉的意思。

    nf_conntrack_tcp_timeout_close
    nf_conntrack_tcp_timeout_close_wait
    nf_conntrack_tcp_timeout_established
    nf_conntrack_tcp_timeout_fin_wait
    nf_conntrack_tcp_timeout_last_ack
    
    • 查看内核是否装在了模块conntrack:modinfo conntrack

    • [!] --state state

      • INVALID:无法识别的连接
      • ESTABLISHED:已经建立的连接
      • NEW:新连接请求
      • RELATED:虽然是一个新的请求,但是已经关联某个已经存在的连接。
      • UNTRACKED:未追踪的连接。
    • 有了这些状态,可以根据状态,限制进出就更方便了。

      • 情形1:一台web server,它通过80端口,接收客户端的请求,然后再从80端口把响应发回个客户端。所以,web server只可能通过80端口发送ESTABLISHED状态的报文,不可以通过80,发送new状态的报文。

      • 情形2:一台ftp server,它通过21端口,接收客户端的请求,然后再从21端口把响应发回个客户端。但还有一种情况,进来的报文状态是RELATED。

      • 满足情形1和情形2的规则配置

        INPUT第一条:目标是我,报文状态是 ESTABLISHED,RELATED的全部放进来。

        注意:要先加载nf_conntrack_ftp模块,加载办法,往下面看。

        # iptables -t filter -I INPUT -d 192.168.56.103 -m state --state ESTABLISHED,RELATED -j ACCEPT
        

        INPUT第二条:目标是我,目的端口是21等,协议是tcp,报文状态是NEW的全部放进来

        # iptables -t filter -I INPUT -d 192.168.56.103 -p tcp -m multiport --dports 21:23,80,139,445,3306 -m state --state NEW -j ACCEPT
        

        OUT第一条:从我出去的,状态是ESTABLISHED的报文,全部放出去。

        # iptables -t filter -A OUTPUT -s 192.168.56.103 -m state --state  ESTABLISHED -j ACCEPT
        

        最后,上面意外的,都拒绝。注意,要放到最后。

        # iptables -t filter -A INPUT -d 192.168.56.103 -j REJECT
        # iptables -t filter -A OUTPUT -s 192.168.56.103 -j REJECT
        

        配置结果:

        Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
         pkts bytes target     prot opt in     out     source               destination
          315 23904 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.56.103       state ESTABLISHED,RELATED
            0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 21:23,80,139,445,3306 state NEW
            0     0 REJECT     all  --  *      *       0.0.0.0/0            192.168.56.103       reject-with icmp-port-unreachable
        
        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
           93  9832 ACCEPT     all  --  *      *       192.168.56.103       0.0.0.0/0            state ESTABLISHED
            0     0 REJECT     all  --  *      *       192.168.56.103       0.0.0.0/0            reject-with icmp-port-unreachable
        
    • 使用lsmod,查看内核都加载了哪些模块,发现没有ftp的模块,所以就无法判断fpt的RELATED的状态。

      # lsmod | grep conn
      nf_conntrack_ipv4      15053  3
      nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
      xt_conntrack           12760  3
      nf_conntrack          133095  2 xt_conntrack,nf_conntrack_ipv4
      libcrc32c              12644  2 xfs,nf_conntrack
      

      查看nf_conntrack_ftp模块:modinfo

      # modinfo nf_conntrack_ftp
      filename:       /lib/modules/3.10.0-957.el7.x86_64/kernel/net/netfilter/nf_conntrack_ftp.ko.xz
      alias:          nfct-helper-ftp
      alias:          ip_conntrack_ftp
      description:    ftp connection tracking helper
      author:         Rusty Russell <rusty@rustcorp.com.au>
      license:        GPL
      retpoline:      Y
      rhelversion:    7.6
      srcversion:     83D9304C9B64D8FBC064040
      depends:        nf_conntrack
      intree:         Y
      vermagic:       3.10.0-957.el7.x86_64 SMP mod_unload modversions
      signer:         CentOS Linux kernel signing key
      sig_key:        B7:0D:CF:0D:F2:D9:B7:F2:91:59:24:82:49:FD:6F:E8:7B:78:14:27
      sig_hashalgo:   sha256
      parm:           ports:array of ushort
      parm:           loose:bool
      

      状态nf_conntrack_ftp模块modprobe

      # modprobe nf_conntrack_ftp
      # lsmod | grep ftp
      nf_conntrack_ftp       18638  0
      

      内核加载了nf_conntrack_ftp后,就可以添加RELATED规则了。

    处理动作

    1,内嵌处理动作:ACCEPT,DROP

    2,扩展处理动作:

    • REJECT: This is used to send back an error packet in response to the matched packet: otherwise it is equivalent to DROP so it is a terminating TARGET, ending rule traversal. This target is only valid in the INPUT, FORWARD and OUTPUT chains,and user-defined chains which are only called from those chains

      --reject-with type:The type given can be icmp-net-unreachable, icmp-host-unreachable, icmp-port-unreachable, icmp-proto-unreach‐able, icmp-net-prohibited, icmp-host-prohibited, or icmp-admin-prohibited (*), which return the appropriate ICMP error message (icmp-port-unreachable is the default).

    • LOG:匹配到LOG规则后,处理动作是把信息写入到文件。然后,并不退出当前链,继续匹配当前链的下一条规则。

      --log-level

      --log-prefix

      log写入到文件/var/log/messages

      例子:把新进来的ssh连接的信息,写入log文件。

      # iptables -t filter -I INPUT 2 -d 192.168.56.103 -p tcp --dport 22 -m state --state NEW -j LOG
      

      log的内容:

      Jan 26 10:07:47 localhost kernel: IN=enp0s3 OUT= MAC=08:00:27:10:c2:53:0a:00:27:00:00:16:08:00 SRC=192.168.56.1 DST=192.168.56.103 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=37589 DF PROTO=TCP SPT=56366 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
      

      为了方便用查找log,添加识别前缀:

      # iptables -t filter -R INPUT 2 -d 192.168.56.103 -p tcp --dport 22 -m state --state NEW -j LOG --log-prefix "mylog: "
      # iptables -vnL
      Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination
        620 51584 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.56.103       state RELATED,ESTABLISHED
          0     0 LOG        tcp  --  *      *       0.0.0.0/0            192.168.56.103       tcp dpt:22 state NEW LOG flags 0 level 4 prefix "mylog: "
      
      

      有前缀的log内容:

      Jan 26 10:14:33 localhost kernel: mylog: IN=enp0s3 OUT= MAC=08:00:27:10:c2:53:0a:00:27:00:00:16:08:00 SRC=192.168.56.1 DST=192.168.56.103 LEN=52 TOS=0x00 PREC=0x00 TTL=128 ID=37882 DF PROTO=TCP SPT=56431 DPT=22 WINDOW=64240 RES=0x00 SYN URGP=0
      
    • RETURN:在自定义链里使用,返回调用此自定义链的链

    3,自定义链

    • 添加一个自定义链

      # iptables -t filter -N in_ping_rules
      
    • 在自定义链上添加规则

      # iptables -t filter -A in_ping_rules -d 192.168.56.103 -p icmp --icmp-type 8 -j ACCEPT
      # iptables -t filter -A in_ping_rules -d 192.168.56.103 -p icmp --icmp-type 8 -s 192.168.56.200 -j REJECT
      icmptype 8 reject-with icmp-port-unreachable
      # iptables -vnL in_ping_rules
      Chain in_ping_rules (0 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.56.103       icmptype 8
          0     0 REJECT     icmp --  *      *       192.168.56.200       192.168.56.103       icmptype 8 reject-with icmp-port-unreachable
      
    • 把自定义链挂到INPUT链上后,references变成1,说明有一个链,使用了此自定义链。

      当匹配到自定义链时,自定义链里的规则没有被匹配上的时候,匹配调用此自定义链的链的,下一条规则。

      # iptables -t filter -I INPUT 3 -j in_ping_rules
      # iptables -vnL
      Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination
       1509  121K ACCEPT     all  --  *      *       0.0.0.0/0            192.168.56.103       state RELATED,ESTABLISHED
          1    52 LOG        tcp  --  *      *       0.0.0.0/0            192.168.56.103       tcp dpt:22 state NEW LOG flags 0 level 4 prefix "mylog: "
          0     0 in_ping_rules  all  --  *      *       0.0.0.0/0            0.0.0.0/0
          3   156 ACCEPT     tcp  --  *      *       0.0.0.0/0            192.168.56.103       multiport dports 21:23,80,139,445,3306 state NEW
      
      Chain in_ping_rules (1 references)
       pkts bytes target     prot opt in     out     source               destination
          0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            192.168.56.103       icmptype 8
          0     0 REJECT     icmp --  *      *       192.168.56.200       192.168.56.103       icmptype 8 reject-with icmp-port-unreachable
      
      
    • 当references不为0的时候,删除自定义链

      # iptables -X in_ping_rules
      iptables: Too many links.
      
    • 当references为0,但自定义链的的规则不为空的时候,删除自定义链

      # iptables -X in_ping_rules
      iptables: Directory not empty.
      
    • 清空自定义链里的规则后,删除自定义链,就可以删除了

      # iptables -F in_ping_rules
      # iptables -X in_ping_rules
      # echo $?
      0
      

    CentOS6和7通用的保存,加载iptables规则

    上面的介绍的命令,都是立即送到kernel,所以是立即生效的,但是当机器重启了,就都失效了。

    下面的保存和重载命令,在CentOS6和7里都可以使用。

    • 保存当前kernel里的iptable规则到文件:

      # iptables-save > /etc/sysconfig/iptables-config-yymmdd-xx
      
    • 把文件里保存的iptables规则,导入到kernel,替换到当前kernel里的规则。

      # iptables-restore < /etc/sysconfig/iptables-config-yymmdd-xx
      

      -n,--noflush:在原有规则后面添加文件里保存的规则

      -t,--test:仅测试,不实际导入到内核。

    • 注意:手动加载的内核模块(nf_conntrack_ftp)的操作,是无法保存到文件的。解决方案是,把加载模块到内核的操作和把文件里保存的规则导入到内核的操作,写到一个脚本里,开机自动执行此脚本即可。

    CentOS6专用的保存,加载iptables规则。

    • 保存:service iptables save

      把内核里的规则,保存到文件:/etc/sysconfig/iptables

    • 加载规则:service iptables restart

      把文件:/etc/sysconfig/iptables里的规则,加载到内存。

    • 配置文件:/etc/sysconfig/iptables-config

    规则优化的简单思路:

    1,使用自定义链管理特定应用的相关规则,模块化管理规则

    2,优先放行双方向状态为ESTABLISHED的报文

    3,服务于不同协议的规则,流量大的放前面

    4,服务于同一个协议的规则,匹配条件严格的放前面

    5,建议使用白名单策略

    forwar表

    查看linux 内核是否打开了核心转发功能,如果值为0,没有打开;值为1,打开了转发功能。

    # cat /proc/sys/net/ipv4/ip_forward
    1
    

    关闭/打开核心转发功能:

    关闭:sysctl -w net.ipv4.ip_forward=0

    打开:sysctl -w net.ipv4.ip_forward=1

    # sysctl -w net.ipv4.ip_forward=0
    net.ipv4.ip_forward = 0
    [root@localhost ~]# cat /proc/sys/net/ipv4/ip_forward
    0
    

    抓包工具:

    抓指定接口,指定协议的包。

    • 抓icmp协议数据包:tcpdump -i enp0s3 -nn icmp

      enp0s3:接口

    • 抓tcp协议,80端口的数据包tcpdump -i enp0s3 -nn tcp port 80

    例子:从pc1,经由中间的主机,远程连接pc2上的mysql和ssh

    步骤1:按图配置ip地址

    步骤2:配置pc1的路由表

    # route add -net 192.168.56.0/24 gw 172.16.0.1
    

    步骤3:配置pc2的路由表

    # route add -net 172.16.0.0/16 gw 192.168.56.103
    

    步骤4:打开中间主机的转发功能

    sysctl -w net.ipv4.ip_forward=1
    

    到此为止,pc1和pc2就可以互相ping通了。

    步骤5:配置中间主机的FORWARD

    # iptables -vnL
    Chain INPUT (policy ACCEPT 172 packets, 13369 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
      111 19378 ACCEPT     tcp  --  *      *       192.168.56.105       172.16.0.0/16        multiport sports 22,3306
      153 13966 ACCEPT     tcp  --  *      *       172.16.0.0/16        192.168.56.0/24      multiport dports 22,3306
       24  1512 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    
    Chain OUTPUT (policy ACCEPT 119 packets, 21448 bytes)
     pkts bytes target     prot opt in     out     source               destination
    

    到此为止,pc1就可以访问pc2的ssh和mysql服务了,但是又不能ping通了,因为ping的规则在FORWARD里没有写,所以,上面的FORWARD配置不是很好,挺麻烦。优化成下面的样子:用NEW和ESTABLISHED状态就能搞定了。注意NEW只允许pc1主动访问pc2,但是不允许pc2主动访问pc1。如果向让pc2也可以主动访问pc1,就再加一条NEW。

    # iptables -vnL
    Chain INPUT (policy ACCEPT 6 packets, 432 bytes)
     pkts bytes target     prot opt in     out     source               destination
    
    Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination
       89 12098 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state ESTABLISHED
        8   576 ACCEPT     all  --  *      *       0.0.0.0/0            192.168.56.0/24      state NEW
      202 16968 REJECT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            reject-with icmp-port-unreachable
    
    # c/c++ 学习互助QQ群:877684253 ![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg) # 本人微信:xiaoshitou5854
  • 相关阅读:
    响应式开发: 宽高等比例缩放
    node服务成长之路
    node压力测试
    前端开发工具
    sequelize问题集锦
    webpack引入handlebars报错'You must pass a string or Handlebars AST to Handlebars.compile'
    夏夜无题
    jmeter在windows环境下系统参数设置
    服务端性能优化指南
    修车备忘
  • 原文地址:https://www.cnblogs.com/xiaoshiwang/p/12235297.html
Copyright © 2020-2023  润新知