iptables详解

设置环境:

[root@miner_k ~]# cat /etc/redhat-release 
CentOS release 6.5 (Final)

启动防火墙

[root@miner_k ~]# service iptables start
iptables: Applying firewall rules:                         [  OK  ]
[root@miner_k ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]

防火墙的简介

Linux的防火墙主要是通过NetfilterTCPWrappers两个机制来管理的。防火墙是通过定义一些有顺序的规则,并管理进入和网络内的主机数据数据包的一种机制。更广义的来说,只要能够分析与过滤进出我们管理的网络的数据包的数据,就是防火墙

防火墙分为硬件防火墙软件防火墙,例如Netfilter和TCPWrappers都是软件防火墙

1.Netfilter(数据包过滤机制)
所谓为的数据包过滤,就是分析进入主机的网络数据包,将数据包的头部数据提取出来进行分析,以决定该连接为放行或抵挡的机制。
在Linux中内核内建了Netfilter这个机制,而Netfilter提供了iptables这个软件作为防火墙数据包过滤的命令。Netfilter是内核的过滤框架,iptables通过特定的语法格式书写一定的规则,Netfilter根据此规则来判断数据限制。

2.TCPWrappers(程序管理)
是通过服务器程序的外挂(tcpd)来处理的,与数据包的过滤不同,这种机制主要是分析谁对某程序进行访问,然后通过规则区分析该服务器程序谁能够连接、谁不能连接。由于主要是通过分析服务器的程序来管理,因此与启动的端口无关,只与程序的名称有关


tcp、ip报文首部信息简介

iptables详解_第1张图片

ip version: 版本
Hdr len : 首部长度 n * 4byte (一行是32bite)
type of server: 服务类型
total length : 报文的总长度 (总长度- 首部长度 = data长度)

封装的http的IP报文中有tcp首部和http首部,但是tcp、http首部在tcp报文中是属于数据部分

fragment ID: 段标识 如果主机的发送的报文的大小是1G,但是路由器的最大的传输的报文是500M,则需要将报文分段)

DF : (don‘t fragment 不能分片):如果是上述情况,路由器直接返回服务器不能分片
MF:(more fragment)

fragment offset:(片偏移量): 报文被分割为多个段,当接收到报文之后,需要重新组合,通过这个偏移量,如果分成两段,第一段的偏移量是0,代表开头,第二个偏移量是101表示第二段。

TTL:(time-to-live) 经过一个路由器(TTL-1)

protocol:tcp、ucp、icmp
HEAD checksum :客户端接收到首部之后查看首部是否发送了变化

iptables详解_第2张图片

source port number:源端口
destination port number:目标端口
sequence number:序列号(第一个是随机的,以后是+1)
acknowledge number:确认号(A-B,如果A发送给B的确认号是100,B接收到之后+1,将101发送给A)
head length :首部长度
reserve 保留位
URG :紧急指针 1代表有效的 0 代表无效 urgent pointer表示该字段的是否有效
ACK: 说明确认号是否有效
psh :推送,表示报文不能再缓存中使用,应该立即送给内核
rst:重置reset,连接发生抖动时需要重置
syn:同步
fin:断开连接
windows size:窗口大小
tcp checksum: 校验码


三次握手、四次挥手的客户端与服务器状态简介

iptables详解_第3张图片

iptables详解_第4张图片

iptables详解_第5张图片


iptables的设置规则

iptables [-t TABLE] COMMAND CHAIN [num] 匹配规则 -j 执行动作

COMMAND
管理规则:
-A :追加一条规则,添加在链接的尾部
-I CHAIN [num]:插入一条规则,插入对应链的第num条
-D CHAIN [num]:删除指定链的第num条规则
-R CHAIN [num] : 替换指定的链的对应的第num条规则

        管理链:
                -F  [chain]: flush 清空指定链的所有规则,如果省略CHAIN,则可以清空对应表中的所有规则
                -P  CHAIN :设定链的默认策略
                -N :自定义一个空链
                -X :删除一个自定义的空链
                -Z :清空指定链中的所有规程的计数器
                -E :重命名一条自定义的链

         查看链:
                -L :显示指定表中的规则
                    -n :以数据格式的形式显示主机地址和端口号
                    -v :详细显示 -vv -vvv
                    -x :显示计数器的精确值
                    --line-numbers:显示规则号码   

匹配规则:
通用匹配(自身可以检查的)
-s,–src :指定源地址
-d,–dst:指定目标地址
-p {tcp|udp|icmp}:指定协议

                -p tcp
                    --sport port[-port]:源端口
                    --dport port[-port]:目标端口
                    --tcp-flags mask comp:只检查mask指定的标志位,是逗号分隔的标志位列表;comp:此列表中出现的标志必须为1,comp中没有出现,但是mask中出现的为0
                            --tcp-flags SYN,FIN,ACK,RST  SYN,ACK     表示SYN=1,ACK=0,FIN=0,RST=0  ⇒  --syn   (第一次握手)
        -i  INTERFACE:指定报文流入的接口
                可用于定义标准的链:INPUT、PREROUTING、FORWORD
        -o INTERFACE:指定报文流出的端口
                可用于定义标准的链:OUTPUT、POSTROUTING、FORWORD    



    扩展匹配(使用模块)
            隐含扩展:不用明确指定那个模块进行扩展,因为使用-p {tcp|udp|icmp}
            -p tcp  --dport 80
            -p tcp -m tcp --dport 80
            隐含扩展和显示扩展的区别就是是否需要指定模块,隐含扩展,如tcp也可以加-m tcp,加载tcp模块。
            显示扩展:必须指定那个模块进行扩展,在iptables中使用-m选项可完成此功能

执行动作( TARGET)
ACCEPT:放行
DROP:丢弃
REJECT:拒绝


配置实例:

1.防火墙规则的查看以及清除

1. 防火墙规则的查看

iptables [-t tables] [-L] [-nv]
选项与参数:

-t :后面接 table ,例如 nat 或 filter ,若省略此項目,則使用預設的 filter
-L :列出目前的 table 的規則
-n :不进行IP和 HOSTNAME 的反查
-v :列出更多的资讯,包括通过该规则的封包总位元数、相关的网络接口等

[root@miner_k ~]# iptables -nL
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:22 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination 
[root@miner_k ~]# iptables -t nat -nL
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination  

各参数的代表的意义:
target:代表进行的动作, ACCEPT 是放行,而 REJECT 是拒绝,此外,尚有 DROP (丢弃) 的項目!
prot:代表使用的封包协定,主要有 tcp, udp 及 icmp 三重封包格式;
opt:额外的选项说明
source :代表此规则是针对『來源 IP』进行行限制
destination :代表此规则是针对『目標 IP』进行限制

2. iptables-save 查看规则

[root@miner_k ~]# iptables-save [-t table]
选项和参数:
-t :可以仅针对某些表格來输出出,例如仅针对 nat 或 filter 等等

[root@miner_k ~]# iptables-save
# Generated by iptables-save v1.4.7 on Fri Jul 22 15:51:52 2011
*filter                      <==星号开头的指的是表格,这里是 filter
:INPUT ACCEPT [0:0]          <==冒号开头是链,三条內建的链
:FORWARD ACCEPT [0:0]        <==三条內建链的策略都是 ACCEPT 
:OUTPUT ACCEPT [680:100461]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT <==针对INPUT规则
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT  <==这条很重要!针对本机內部接口开放
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A FORWARD -j REJECT --reject-with icmp-host-prohibited <==针对 FORWARD 的规则
COMMIT
3. 规则清除

iptables [-t tables] [-FXZ]
选项与参数:

-F :清除所有的已制定的规则;
-X :清除所有使用者 “自定义” 的 chain (因该说的是 tables );
-Z :将所有的 chain 的计数与流量統計都清零

实例:清除本机防火墙 (filter) 的所有規則

[root@miner_k ~]# iptables -F
[root@miner_k ~]# iptables -X
[root@miner_k ~]# iptables -Z
4.删除指定的规则

删除filter表中的INPUT链中的第2条规则

[root@miner_k ~]# iptables -D INPUT 2
5.替换指定的规则

将filter表中的INPUT链中的第二条规则修改

[root@miner_k ~]# iptables -R INPUT 2 -i eth0 -p tcp --dport 22 -j ACCEPT

2.设置默认策略

默认策略的设置可以分为默认允许(堵)或者拒绝(疏),如果默认允许需要拒绝某些端口或者协议的访问。默认拒绝,需要配置某些协议或者端口的允许访问。

[root@miner_k ~]# iptables [-t nat] -P [INPUT,OUTPUT,FORWARD][ACCEPT,DROP]
选项和参数:
-P :定义策略( Policy )。注意,这个P 是大写!
ACCEPT :该数据包可接受
DROP :该数据包直接丢弃,不会让 client 端知道为何被丢弃。

举例:将本机的 INPUT 设定为 DROP ,其他的设定为 ACCEPT

[root@miner_k ~]# iptables -P INPUT   DROP
[root@miner_k ~]# iptables -P OUTPUT  ACCEPT
[root@miner_k ~]# iptables -P FORWARD ACCEPT
[root@miner_k ~]# iptables-save
# Generated by iptables-save v1.4.7 on Fri Jul 22 15:56:34 2011
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

# 由于 INPUT 设定为 DROP 而又尚未有任何規則,所以上面的输出結果显示:
# 所有的数据包都无法进入你的主机!是不通的防火墙设定!(网络连接是双向的)

3.对数据包的IP、网络以及接口设备做规则设置

[root@miner_k ~]# iptables [-AI 链名] [-io 网络接口] [-p 协议]  [-s 来源IP/网段] [-d 目标IP/网段] -j [ACCEPT|DROP|REJECT|LOG]

选项和参数:
-AI 链名:针对某的链进行规则的 "插入""累加"
    -A :新增加一条规则,该规则增加在原本规则的最后面。例如原本已经有四条规则,
         使用 -A 就可以加上第五条规则!
    -I :插入一条规则。如果没有指定此规则的顺序,预设是插入变成第一条规则。
         例如原本有四条规则,使用 -I 则该规则变成第一条,而原本四条变成 2~5 号
    链 :有 INPUT, OUTPUT, FORWARD 等,此链名称又与 -io 有关,请看底下。

-io 网路介面:设定封包进出的介面规范
    -i :封包所进入的那个网路介面,例如 eth0, lo 等介面。需与 INPUT 链配合;
    -o :封包所传出的那个网路介面,需与 OUTPUT 链配合;

-p 协定:设定此规则适用于哪种封包格式
   主要的封包格式有: tcp, udp, icmp 及 all 。

-s 来源 IP/网域:设定此规则之封包的来源项目,可指定单纯的 IP 或包括网域,例如:
   IP  :192.168.0.100
   网域:192.168.0.0/24, 192.168.0.0/255.255.255.0 均可。
   若规范为『不许』时,则加上 ! 即可,例如:
   -s ! 192.168.100.0/24 表示不许 192.168.100.0/24 之封包来源;

-d 目标 IP/网域:同 -s ,只不过这裡指的是目标的 IP 或网域。

-j :后面接动作,主要的动作有接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)及记录(LOG
实例1:设定 lo 成为受信任的装置,亦即进出 lo 的封包都予以接受
[root@miner_k ~]# iptables -A INPUT -i lo -j ACCEPT
实例2:对117.78.20.0/24这个网段的所有数据包都允许
[root@miner_k ~]# iptables -A INPUT -i eth0 -s 117.78.20.0/24 -j ACCEPT
实例3:经数据包来自192.168.2.200这个 IP的数据包记录到内核日志中(/var/lgo/messages)
[root@miner_k ~]# iptables -A INPUT -s 192.168.2.200 -j LOG --prefix --firewall-
实例4:ping通本地回环网卡(INPUT、OUTPUT默认策略是DROP)
[root@miner_k ~]# iptables -A INPUT -s 127.0.0.1 -i lo -d 127.0.0.1 -j ACCEPT
[root@miner_k ~]# iptables -A OUTPUT -s 127.0.0.1 -o lo -d 127.0.0.1 -j ACCEPT

4. TCP、UDP的规则对比针对端口

[root@miner_k ~]# iptables [-AI 链] [-io 网络接口] [-p tcp,udp] \
[-s 来源IP/网段] [–sport 端口范围] \
[-d 目标IP/网段] [–dport 端口范围] -j [ACCEPT|DROP|REJECT]
选项与参数:
–sport 端口范围:限制来源的端口号码,端口号码可以是连续的,例如 1024:65535
–dport 端口范围:限制目标的端口号码。

实例1:想要连线进入本机 port 21 的封包都抵挡掉
[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp --dport 21 -j DROP
实例2:想连到我这部主机的网上邻居 (upd port 137,138 tcp port 139,445) 就放行
[root@miner_k ~]# iptables -A INPUT -i eth0 -p udp --dport 137:138 -j ACCEPT
[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp --dport 139 -j ACCEPT
[root@miner_k ~]#iptables -A INPUT -i eth0 -p tcp --dport 445 -j ACCEPT
实例3 :只要来自 192.168.1.0/24 的 1024:65535 端口的数据包,且想要连线到本机的 ssh port 就予以阻挡,可以这样做:
[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp -s 192.168.1.0/24  --sport 1024:65534 --dport ssh -j DROP
实例4:将来自任何地方来源 port 1:1023 的主动连线到本机端的 1:1023 连线丢弃
[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp --sport 1:1023 --dport 1:1023 --syn -j DROP
在 TCP 还有特殊的标记,最常见的就是那个主动连线的 SYN 标记。 我们在 iptables 里面还支持『 --syn 』的处理方式。

一般来说,client 端启用的 port 都是大于 1024 以上的端口,而 server 端则是启用小于 1023 以下的端口在监听的。所以我们可以让来自远端的小于 1023 以下的端口资料的主动连线都给他丢弃!
实例5:外网可以访问服务器的80端口

服务器的配置环境:公网IP地址映射到该服务器的eth0网卡对应的地址是192.168.6.181.

[root@miner_k ~]# iptables -I INPUT -d 192.168.6.181 -p tcp --dport 80 -j ACCEPT
或者
[root@miner_k ~]# iptables -I INPUT -i eth0 -p tcp --dport 80 -j ACCEPT

如果OUTPUT链的默认策略是DROP,还需要设置OUTPUT的策略

[root@miner_k ~]# iptables -I OUTPUT -o eth0 -p tcp --sport 80 -j ACCEPT
实例6:需要解析域名(INPUT、OUTPUT默认策略都是DROP)
[root@miner_k ~]# iptables -A -o eth0 -p udp --dport 53 -j ACCEPT
[root@miner_k ~]# iptables -A INPUT -i eth0 -p udp --sport 53 -j ACCEPT
实例7:该服务器最为DNS的域名解析服务器的设置(INPUT、OUTPUT默认策略都是DROP)只是设置UDP协议
作为DNS的服务器,被客户端访问
[root@miner_k ~]# iptables -A -o eth0 -p udp --sport 53 -j ACCEPT
[root@miner_k ~]# iptables -A INPUT -i eth0 -p udp --dport 53 -j ACCEPT

做客户端向根服务器发送请求
[root@miner_k ~]# iptables -A -o eth0 -p udp --dport 53 -j ACCEPT
[root@miner_k ~]# iptables -A INPUT -i eth0 -p udp --sport 53 -j ACCEPT

5. ICMP数据包规则的对比:针对是否响应ping来设计

ICMP 的类型相当的多,而且很多 ICMP 封包的类型都是为了要用来进行网路检测用的!所以最好不要将所有的 ICMP 封包都丢弃!如果不是做为路由器的主机时,通常我们会把 ICMP type 8 (echo request) 拿掉而已,让远端主机不知道我们是否存在,也不会接受 ping 的回应就是了。ICMP 封包格式的处理是这样的:

[root@miner_k ~]# iptables -A INPUT [-p icmp] [--icmp-type 類型] -j ACCEPT
选项与参数:
--icmp-type :后面必须要接 ICMP 的数据包类型,也可以使用代号,
              例如 8  代表 echo request 的意思。

实例:让 0,3,4,11,12,14,16,18 的 ICMP type 可以进入本机:
[root@miner_k ~]# vi somefile
#!/bin/bash
icmp_type="0 3 4 11 12 14 16 18"
for typeicmp in $icmp_type
do
   iptables -A INPUT -i eth0 -p icmp --icmp-type $typeicmp -j ACCEPT
done

[root@miner_k ~]# sh  somefile

ICMP 的全名是『 Internet Control Message Protocol, 网际网路讯息控制协定 』。
iptables详解_第6张图片

实例1:该服务器能ping通外网,但是外网的服务器ping不通该服务器(INPUT、OUTPUT默认策略都是DROP)
[root@miner_k ~]# iptables -A INPUT -i eth0 -p icmp --icmp-type 0 -j ACCEPT
[root@miner_k ~]# iptables -A OUTPUT -o eth0 -p icmp --icmp-type 8 -j ACCEPT

注意:测试时不要直接ping www.baidu.com在ping时会发现解析不了该域名,是由于解析被防火墙拒绝了。

6.加载模块

其实iptables的规则限制都是调用模块来限制的,从下面开启iptables和关闭防火墙中的命令,通过查看模块可以发现在开启时会自动加载iptables_filter、iptables_nat、nf_nat等模块。

[root@miner_k ~]# lsmod | grep ip
iptable_filter          2793  1 
iptable_nat             6158  0 
nf_nat                 22759  2 nf_nat_ftp,iptable_nat
nf_conntrack_ipv4       9506  7 iptable_nat,nf_nat
nf_defrag_ipv4          1483  1 nf_conntrack_ipv4
ip_tables              17831  2 iptable_filter,iptable_nat
ipt_REJECT              2351  1 
xt_iprange              2312  0 
xt_multiport            2700  0 

[root@miner_k ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter nat      [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]
[root@miner_k ~]# lsmod | grep ip
ipt_REJECT              2351  0 
xt_iprange              2312  0 
xt_multiport            2700  0 

使用模块nf_conntrack

[root@miner_k proc]# ls /proc/sys/net/netfilter/nf_
nf_conntrack_acct                        nf_conntrack_log_invalid                 nf_conntrack_tcp_timeout_max_retrans
nf_conntrack_buckets                     nf_conntrack_max                         nf_conntrack_tcp_timeout_syn_recv
nf_conntrack_checksum                    nf_conntrack_tcp_be_liberal              nf_conntrack_tcp_timeout_syn_sent
nf_conntrack_count                       nf_conntrack_tcp_loose                   nf_conntrack_tcp_timeout_time_wait
nf_conntrack_events                      nf_conntrack_tcp_max_retrans             nf_conntrack_tcp_timeout_unacknowledged
nf_conntrack_events_retry_timeout        nf_conntrack_tcp_timeout_close           nf_conntrack_udp_timeout
nf_conntrack_expect_max                  nf_conntrack_tcp_timeout_close_wait      nf_conntrack_udp_timeout_stream
nf_conntrack_generic_timeout             nf_conntrack_tcp_timeout_established     nf_log/
nf_conntrack_icmp_timeout                nf_conntrack_tcp_timeout_fin_wait        
nf_conntrack_icmpv6_timeout              nf_conntrack_tcp_timeout_last_ack    
实例1:使连接到服务器上的22端口的连接状态为NEW,ESTABLISHED的同意连接,出方向是ESTABLISHED的状态同意放行。
[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

[root@miner_k ~]# iptables -A OUTPUT -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
实例2:配置ftp+防火墙(ip_nat_ftp模块)
[root@miner_k ~]# vim /etc/sysconfig/iptables-config 
IPTABLES_MODULES="ip_nat_ftp"   #加载ip_nat_ftp模块

[root@miner_k ~]#service iptables reload

[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp -m tcp --dport 21 -m state --state NEW,RELATED,ESTABLISHED -j ACCEPT
[root@miner_k ~]# iptables -A INPUT -i eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT

[root@miner_k ~]# iptables-A OUTPUT -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
实例3:离散型多端口匹配(multiport模块)

需要将21,22,80这三个不连续的端口同时匹配。

[root@miner_k ~]# iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination         
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 state NEW 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:80 state NEW 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:21 state NEW 

multiport模块 参数以及规则:
[!] –source-ports,–sports port[,port|,port:port]… #源端口
[!] –destination-ports,–dports port[,port|,port:port]… #目标端口
[!] –ports port[,port|,port:port]… #源端口或者目标端口

解决方法:

[root@miner_k ~]# iptables -I INPUT -i eth0 -m multiport -p tcp --dports 21,22,80 -m state --state NEW -j ACCEPT
[root@miner_k ~]# iptables -D INPUT 3
[root@miner_k ~]# iptables -D INPUT 3
[root@miner_k ~]# iptables -D INPUT 3
实例4. 指定一段网络地址限制访问(iprange模块)

iprange模块
对应的参数
[!] –src-range from[-to]
Match source IP in the specified range.

[!] –dst-range from[-to]
Match destination IP in the specified range.

只允许192.168.112.11-192.168.112.45这一段IP地址远程登录

[root@miner_k ~]# iptables -A INPUT -i eth0 -p tcp -m iprange --src-range 192.168.112.11-192.168.112.45 --dport 22 -j ACCEPT
实例5. 限制连接数(connlimit模块)

connlimit模块的参数
[!] –connlimit-above n

每个客户端只允许两个telnet连接


[root@miner_k ~]#iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j REJECT   #待定
或者
[root@miner_k ~]#iptables -A INPUT -p tcp --syn --dport 23 -m connlimit --connlimit-above 2 -j ACCEPT
实例6. 用户bucket来限制速率(limit)

limit模块的参数
- -limit rate[/second|/minute|/hour|/day]
- -limit-burst number 同时处理的数目

[root@miner_k ~]# iptables -R INPUT -i eth0 -p icmp --icmp-type 8 -m limit --limit 1/minute --limit-burst 1 -j ACCEPT
实例7. 限定访问中包含字符串的内容(string模块)

string模块的参数
–algo {bm|kmp} 算法
Select the pattern matching strategy. (bm = Boyer-Moore, kmp = Knuth-Pratt-Morris)

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

   --to offset
          Set  the offset from which it starts looking for any matching. If not passed, default is the packet size.

   [!] --string pattern
          Matches the given pattern.

   [!] --hex-string pattern
          Matches the given pattern in hex notation.

显示访问含有“h7n9”的请求:
例如:请求www.miner_k.com/h7n9.html会被拒绝

[root@miner_k html]# iptables -I INPUT  -i eth0  -m string --algo kmg --string "h7n9" -j DROP

在返回的数据中包含”h7n9”的字符全部拒绝
虽然请求的是www.miner_k.com/test.html,但是该文件中包含“h7n9”字符串。

[root@miner_k html]# iptables -I OUTPUT  -o eth0  -m string --algo kmp --string "h7n9" -j DROP
实例8: 在规定的时间内后端服务器不能上网
[root@miner_k html]# iptables -A FORWARD -s 192.168.6.0/24 -m time --timestart 08:00 --timestop 14:00 -j DROP

6. 自定义链

[root@miner_k html]# iptables -N clean_in    #自定义名为clean_in的自定义链

[root@miner_k html]# iptables -A clean_in -d 255.255.255.255 -p icmp -j DROP
[root@miner_k html]# iptables -A clean_in -d 192.168.255.255 -p icmp -j DROP
[root@miner_k html]# iptables -A clean_in -i eth0 -p tcp ! --syn -m state --state NEW -j DROP 
[root@miner_k html]# iptables -A clean_in -d 192.168.6.181/24 -j RETURN   #返回到主链
[root@miner_k html]# iptables -I INPUT -j clean_in  #在INPUT链中添加自定义链

[root@miner_k html]# iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination         
clean_in   all  --  0.0.0.0/0            0.0.0.0/0           
DROP       all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:21 state NEW,RELATED,ESTABLISHED 
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22 state NEW,ESTABLISHED 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy DROP)
target     prot opt source               destination         
DROP       all  --  0.0.0.0/0            0.0.0.0/0           STRING match "h7n9" ALGO name kmp TO 65535 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0           

Chain clean_in (1 references)
target     prot opt source               destination         
DROP       icmp --  0.0.0.0/0            255.255.255.255     
DROP       icmp --  0.0.0.0/0            192.168.255.255     
DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp flags:!0x17/0x02 state NEW 
RETURN     all  --  0.0.0.0/0            192.168.6.0/24      

7. 防止DDOS攻击(recent模块)

[root@miner_k html]# iptables -I INPUT -i eth0 -p tcp --dport 22 -m connlimit --connlimit-above 3 -j DROP
[root@miner_k html]# iptables -I INPUT 2 -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
[root@miner_k html]# iptables -I INPUT 3 -i eth0 -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 300 --hitcount 3 --name SSH -j DROP

解释上面语句的意义:
第一条:只允许最大连接为3个
第2条:将最近的通过ssh连接的信息记录到内存中,并命名为SSH(保存位置:/proc/net/xt_recent/SSH)
第3条:如果达到3次,将拒绝登录。

内存中记录:

[root@miner_k proc]# cat /proc/net/xt_recent/SSH 
src=37.114.62.70 ttl: 32 last_seen: 4468958276 oldest_pkt: 8 4468940320, 4468944980, 4468951373, 4468951373, 4468952370, 4468952370, 4468958276, 4468958276
src=114.236.90.51 ttl: 105 last_seen: 4468908535 oldest_pkt: 2 4468869679, 4468908535
src=101.200.87.99 ttl: 42 last_seen: 4468889781 oldest_pkt: 1 4468889781

iptables规则的保存

如果使用iptables命令设置完iptables的规则之后需要保存iptables的规则,否则重新启动iptables服务之后是会将规则清空的。

  • 使用service服务保存iptables的规则
    (默认是保存到/etc/sysconfig/iptables的文件中)
[root@miner_k ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[  OK  ]
  • 使用iptables-save重定向保存
[root@miner_k ~]# iptables-save > /etc/sysconfig/iptables-20170613
  • 将保存的规则导入到iptables中
将指定的规则导入到iptables的规则中但是会清除以前的规则
[root@miner_k ~]# iptables-restore < /etc/sysconfig/iptables-20170613

不清空以前的规则:
[root@miner_k ~]# iptables-restore -n iptables/dns.rule

常见规则的存放

https://github.com/miner-k/iptables

加载netfilter-layer7模块

Netfilter模块暂时没有默认添加,需要手动编译内核和重新编译iptables。
涉及的网站信息:
clearfoundation:http://l7-filter.clearos.com/
l7-filter首页:http://l7-filter.sourceforge.net/

准备工作

下载Netfilter-layer7模块

[root@miner_k ~]# wget http://download.clearfoundation.com/l7-filter/netfilter-layer7-v2.22.tar.gz
[root@miner_k ~]# wget http://download.clearfoundation.com/l7-filter/l7-protocols-2009-05-28.tar.gz

下载iptables

[root@miner_k ~]# wget http://www.netfilter.org/projects/iptables/files/iptables-1.4.7.tar.bz2

下载Linux内核

[root@miner_k ~]# wget https://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.32.9.tar.gz

解压、编译内核

[root@miner_k ~]# tar xf linux-2.6.32.9.tar.gz -C /usr/src/

[root@miner_k ~]# tar xf netfilter-layer7-v2.22.tar.gz -C /usr/src/
[root@miner_k ~]# cd /usr/src/
[root@miner_k src]# ln -sv  linux-2.6.32.9/ linux

打补丁到内核中

[root@miner_k linux]# patch -p1 < ../netfilter-layer7-v2.22/kernel-2.6.25-2.6.28-layer7-2.22.patch 
patching file net/netfilter/Kconfig
Hunk #1 succeeded at 858 (offset 63 lines).
patching file net/netfilter/Makefile
Hunk #1 succeeded at 89 (offset 5 lines).
patching file net/netfilter/xt_layer7.c
patching file net/netfilter/regexp/regexp.c
patching file net/netfilter/regexp/regexp.h
patching file net/netfilter/regexp/regmagic.h
patching file net/netfilter/regexp/regsub.c
patching file net/netfilter/nf_conntrack_core.c
Hunk #1 succeeded at 201 with fuzz 1.
patching file net/netfilter/nf_conntrack_standalone.c
Hunk #1 succeeded at 171 with fuzz 2 (offset 6 lines).
patching file include/net/netfilter/nf_conntrack.h
Hunk #1 succeeded at 116 (offset -2 lines).
patching file include/linux/netfilter/xt_layer7.h

以原来的内核的配置文件为基础进行配置

[root@miner_k linux]# cp /boot/config-2.6.32-431.el6.x86_64 .config

安装开发环境:

[root@miner_k linux]# yum -y groupinstall "Development tools"
[root@miner_k linux]# yum -y install ncurses-devel
[root@miner_k linux]#make menuconfig

设置新内核的后缀名:
iptables详解_第7张图片

iptables详解_第8张图片

iptables详解_第9张图片

iptables详解_第10张图片

Networking support –>>Networking Options –>>Network packet filtering framework –>>Core Netfilter Configuration ,如图所示
iptables详解_第11张图片

[root@miner_k linux]# screen
[root@miner_k linux]# make
[root@miner_k linux]# make modules_install
[root@miner_k linux]# make install

修改启动项,默认为新增加的内核
[root@miner_k linux]# vim /boot/grub/grub.conf
iptables详解_第12张图片

[root@miner_k linux]#shutdown -r now

重新启动之后查看内核版本

[root@miner_k ~]# uname -r
2.6.32.9-layer7

重新安装iptables

将以前的iptables的启动脚本以及配置文件、规则保存。

[root@miner_k ~]# cp /etc/init.d/iptables .
[root@miner_k ~]# cp /etc/sysconfig/iptables-config .
[root@miner_k ~]# cp /etc/sysconfig/iptables iptables.rule

关闭rpm包安装的iptables

[root@miner_k ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]

[root@miner_k ~]# chkconfig iptables off

清除rpm包安装的iptables,安装源码的iptables

[root@miner_k ~]# rpm -e iptables-ipv6 iptables  --nodeps

[root@miner_k ~]# tar jxf iptables-1.4.7.tar.bz2 -C /usr/src/
[root@miner_k ~]# cd /usr/src/iptables-1.4.7/

将模块复制到iptables的扩展模块中

[root@miner_k iptables-1.4.7]# cp ../netfilter-layer7-v2.22/iptables-1.4.3forward-for-kernel-2.6.20forward/libxt_layer7.* ./extensions/


[root@miner_k iptables-1.4.7]# ./configure --prefix=/usr --with-ksource=/usr/src/linux
[root@miner_k iptables-1.4.7]# make
[root@miner_k iptables-1.4.7]# make install

使用以前的脚本文件,启动iptables

[root@miner_k ~]# which iptables
/usr/sbin/iptables
[root@miner_k ~]# vim iptables 
36 if [ ! -x /usr/sbin/$IPTABLES ]; then
 37     echo -n $"${IPTABLES}: /usr/sbin/$IPTABLES does not exist."; warning; echo
 38     exit 5
 39 fi
[root@miner_k ~]# cp iptables /etc/init.d/
[root@miner_k ~]# chkconfig --add iptables
[root@miner_k ~]# chkconfig --list | grep iptables
iptables        0:off   1:off   2:on    3:on    4:on    5:on    6:off

将规则和配置文件拷贝的指定的目录下

[root@miner_k ~]# cp iptables-config /etc/sysconfig/
[root@miner_k ~]# cp iptables.rule /etc/sysconfig/iptables

l7-protocols-2009-05-28.tar.gz就提供协议的特征码

[root@miner_k ~]# tar xf l7-protocols-2009-05-28.tar.gz
[root@miner_k ~]# cd l7-protocols-2009-05-28
[root@miner_k l7-protocols-2009-05-28]# make install
mkdir -p /etc/l7-protocols
cp -R * /etc/l7-protocols

l7支持的协议

[root@miner_k ~]# ls /etc/l7-protocols/protocols/
100bao.pat                dazhihui.pat              hotline.pat           ncp.pat             shoutcast.pat      tesla.pat
aim.pat                   dhcp.pat                  http.pat              netbios.pat         sip.pat            tftp.pat
aimwebcontent.pat         directconnect.pat         http-rtsp.pat         nntp.pat            skypeout.pat       thecircle.pat
applejuice.pat            dns.pat                   ident.pat             ntp.pat             skypetoskype.pat   tonghuashun.pat
ares.pat                  doom3.pat                 imap.pat              openft.pat          smb.pat            tor.pat
armagetron.pat            edonkey.pat               imesh.pat             pcanywhere.pat      smtp.pat           tsp.pat
battlefield1942.pat       fasttrack.pat             ipp.pat               poco.pat            snmp.pat           unknown.pat
battlefield2142.pat       finger.pat                irc.pat               pop3.pat            socks.pat          unset.pat
battlefield2.pat          freenet.pat               jabber.pat            pplive.pat          soribada.pat       uucp.pat
bgp.pat                   ftp.pat                   kugoo.pat             qq.pat              soulseek.pat       validcertssl.pat
biff.pat                  gkrellm.pat               live365.pat           quake1.pat          ssdp.pat           ventrilo.pat
bittorrent.pat            gnucleuslan.pat           liveforspeed.pat      quake-halflife.pat  ssh.pat            vnc.pat
chikka.pat                gnutella.pat              lpd.pat               radmin.pat          ssl.pat            whois.pat
cimd.pat                  goboogy.pat               mohaa.pat             rdp.pat             stun.pat           worldofwarcraft.pat
cisco.pat              gopher.pat                msn-filetransfer.pat  replaytv-ivs.pat    subspace.pat       x11.pat
citrix.pat                guildwars.pat             msnmessenger.pat      rlogin.pat          subversion.pat     xboxlive.pat
counterstrike-source.pat  h323.pat                  mute.pat              rtp.pat             teamfortress2.pat  xunlei.pat
cvs.pat                   halflife2-deathmatch.pat  napster.pat           rtsp.pat            teamspeak.pat      yahoo.pat
dayofdefeat-source.pat    hddtemp.pat               nbns.pat              runesofmagic.pat    telnet.pat         zmaap.pat

规则的书写格式

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

[root@miner_k ~]# service iptables start

测试:

测试一:
通过layer7模块允许本地http的访问

[root@miner_k ~]# yum -y install httpd
[root@miner_k ~]# echo web1 > /var/www/html/index.html
[root@miner_k ~]# service httpd restart
Stopping httpd:                                            [  OK  ]
Starting httpd: httpd: apr_sockaddr_info_get() failed for miner_k
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
                                                           [  OK  ]
[root@miner_k ~]# curl localhost
web1


[root@miner_k ~]#iptables -A INPUT -m layer7 --l7proto http -j ACCEPT

测试失败:
如果您尝试这样做,您将阻止所有TCP握手以及所有TCP连接。 此外,您将阻止第一个数据包上无法识别的所有UDP连接
最常见的错误是仅使用INPUT或OUTPUT链。 这些只能获取本地机器的流量,每个只有一个方向。 有关数据包如何遍历各个链的信息,请参阅Netfilter文档。

  • 测试二:
    在NAT上限制后端服务器访问外网的限制
[root@miner_k ~]#  iptables -A FORWARD -m layer7 --l7proto http -j DROP

你可能感兴趣的:(linux,……【iptables】)