iptables学习记录(命令篇)

iptables学习记录(命令篇):
1.查询命令
iptables -t filter --line-number -vnL INPUT
-t选项:iptables的查看四张表中的一张,默认是filter表,另外还有nat表、mangle表、raw表;
INPUT为iptables某个chain链,总共链有五种:PREROUTING、INPUT、FORWARDING、OUTPUT、POSTROUTING
2.清除命令
iptables -t filter -F INPUT  //清除filter表的INPUT链

3.添加规则
iptables -t filter -I INPUT -s 172.16.4.248 -j DROP --line-number
-I:insert 
-s:source源
-j:jump跳转。跳转到规则匹配上的行为,即DROP
--line-number:打印出该规则对应的条目num,如下:
[root@localhost mcptt_1]# iptables -t filter -nvL INPUT --line-number
Chain INPUT (policy ACCEPT 5081 packets, 730K bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       86  7224 DROP       all  --  *      *       172.16.4.248         0.0.0.0/0

从172.16.4.248ping172.16.6.231,ping不通报文被丢弃。

再增加一条规则:
iptables -t filter -I INPUT -s 172.16.4.248 -j ACCEPTiptables -t filter -I INPUT -s 172.16.4.248 -j ACCEPT
[root@localhost mcptt_1]# iptables -t filter -nvL INPUT --line-number
Chain INPUT (policy ACCEPT 547 packets, 76514 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     all  --  *      *       172.16.4.248         0.0.0.0/0           
2       86  7224 DROP       all  --  *      *       172.16.4.248         0.0.0.0/0 

发现对同一个过滤规则执行了不同的动作,后增加的顺序会插入到之前增加的排列到第一条。即num=1;
此时发现在172.16.4.248上可以ping通172.16.6.231,说明相同的规则不同的执行动作,num排列在前面的先匹配到并执行动作,排列在后面的规则对应的动作执行无效。

4.修改规则
A.-I选项
iptables -t filter -I INPUT 2 -s 172.16.4.248 -j REJECT
-I INPUT 2:数字2表示对num为2的规则作修改并重新插入,这次修改后,num=2的命令规则立即变成num=1,排列在第一列优先匹配并执行。
            -I INPUT 2,注意:如果使用-I INPUT 1,只会重新插入一条记录,而原有num=1的记录变成num=2。
DROP:报文直接丢弃
ACCEPT:报文放行
REJECT:报文拒绝并回应
B.-R选项(replace)
  使用-R选项只能修改执行的动作,而且都要把num号和匹配规则写全了,不能默认。
  iptables -t filter -R INPUT 1 -s 172.16.4.248 -j DROP
  
5.删除规则
A.根据num来删除
iptables -t filter -D INPUT 6
-D:删除num=6的条目,filter表中INPUT链第6个条目

B.根据匹配项来删除
iptables -t filter -D INPUT -s 172.16.4.248 -j REJECT

C.删除所有
iptables -t filter -F INPUT

6.修改默认行为
iptables -t filter -I INPUT -j ACCEPT
修改表filter 的INPUT链默认行为为ACCEPT

7.多个规则用","隔开
iptables -t filter -I INPUT 2 -i eth0 -s 172.16.4.248,172.16.5.246 -d 172.16.6.231 -p tcp -j REJECT
-i:表示入以太网卡,因为-I是判断从哪个网卡流入匹配项的,所以只能使用在PREROUTING\INPUT\FORWARDING状态,不能使用在OUTPUT/POSTROUTING状态,个人理解:因为OUTPUT和POSTROUTING阶段入口处理流程已经结束了,所以没有知道入网口。
    请查阅iptables数据流图
-O:表示出以太网卡,因为在PREROUTING\INPUT\FORWARD阶段处理的是入数据,还不知道出口数据流程,譬如目的地址下一条查找之类的,下一跳数据封装等都没有进行,所以没法处理出以太网卡匹配。
总结:FORWARD阶段都可以使用-I  -O 入出以太网卡匹配,是因为FORWARD阶段即处理了入口数据又替换封装了出口数据过程。

8.扩展属性:端口号过滤
  iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p tcp -m tcp --dport 22 --sport 5059 -j ACCEPT
  端口号过滤:必须制定协议属性,如:-p tcp
              -m tcp:-m表示是tcp的扩展属性
              --sport
              --dport:表示端口匹配规则
 -p tcp和-m tcp并不冲突,-p tcp表示协议类型为tcp,-m tcp表示扩展模块的名称为tcp,该tcp模块中的端口号为22和5059过滤规则。
 问题:
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323 -j DROP
 A.如果删除-p tcp该匹配会生效吗?
 iptables -t filter -I INPUT -m tcp --dport 2323 -j DROP
 删除-p tcp后该命令执行提示格式错误!
 B.如何删除-m tcp端口号能生效吗?
iptables -t filter -I INPUT -p tcp --dport 2323 -j DROP 
删除-m tcp后命令执行成功,且能成功匹配到规则且DROP生效。该-m tcp命令且不是多余的吗?(遗留问题)

8.1指定多个连续端口
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323:2400 -j DROP
 2323:2400指定端口范围
 iptables -t filter -I INPUT -p tcp -m tcp --dport 2323: -j DROP
2323: 表示2323端口以上的范围
 iptables -t filter -I INPUT -p tcp -m tcp --dport :2323 -j DROP
 :2323 表示0到2323端口的范围
 
8.2指定多个离散不连续端口
iptables -t filter -I INPUT -p tcp -m multiport --dport 1000,2000:2323 -j DROP
1000,2000:2323 指定1000端口号以及2000:2323范围内的端口

8.3 ip range扩展模块
iptables -t filter -I INPUT -p tcp -m iprange --src-range 172.16.4.240-172.16.5.246 --dst-range 172.16.4.240-172.16.5.246 -m multiport --dport 1000,2000:2323 -j DROP
-m iprange:多个IP匹配范围
--src-range:源IP匹配范围
--dst-range:目的IP匹配范围

8.4 string扩展匹配报文内容字符串
iptables -t filter -I INPUT -m string --algo bm --string "hello world" -j DROP
-m string:扩展属性为字符串
--algo bm:选择算法,算法内容为bm
--string "hello world":表示匹配字符串内容为"hello world"

8.5 time扩展模块
ptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --timestart 02:00:00 --timestop 22:00:00 -j DROP
在测试机器上发现不生效,172.16.5.246自己ping自己还是可以ping通,后来发现linux本身的系统时间不是24小时格式的,修改命令如下:
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --timestart 02:00:00 --timestop 09:00:00 -j DROP,命令生效.
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --weekdays 5 -j DROP
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --monthdays 8,9,10,11 -j DROP
iptables -t filter -I INPUT -s 172.16.5.246 -d 172.16.5.246 -m time --datestart 2019-11-5 --datestop 2019-11-10 -j DROP

8.6 connlimit扩展模块
iptables -t filter -I INPUT -s 172.16.4.239 -d 172.16.5.246 -p tcp --dport 22 -m connlimit --connlimit-above 4 -j DROP
-m commlimit:扩展模块限制连接数
--connlimit-above 4:上限是4个连接数
//但该测试命令链接上限并没有生效,待进一步查明原因
//该命令表示每个客户端ssh时查看匹配是否达到上限,之所以没生效是secureCRT的原因,我们改下命令:
iptables -t filter -I INPUT -s 172.16.4.239 -d 172.16.5.246 -p tcp --dport 22 -m connlimit --connlimit-above 0 -j DROP
//命令限制为0个,已存在的多少个链接无法匹配,但后面新增的链接无法ssh,即使使用secureCRT软件都不行,命令生效!
 之前存在的链接在保活时间到以后会给目的主机发送沟通报文,由于匹配到规则连接数最大上限是0,所以secureCRT在发保活报文时保活报文被丢弃,已有的链接超时失效。

8.7 limit扩展模块
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute -j ACCEPT//每6秒钟放行一次
[root@localhost ~]# iptables -t filter --line-number -vnL INPUT                             
Chain INPUT (policy ACCEPT 40 packets, 6402 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        0     0 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 10/min burst 5

首先发现ping包似乎没生效,因为该规则是起了一个定时器每6秒钟到就匹配报文一次,那么6秒内定时器未超时即不会匹配该规则,那么其余的规则都是默认规则,默认规则即是放行ACCEPT,所以感觉是没生效,
其实应该是每到6秒规则生效了,只不过每次生效同样是放行5个令牌桶,肉眼分辨不出来。如果修改成默认行为为DROP,即能分辨出来。命令修改成:
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j REJECT //指定特殊源和目的地址的icmp默认行为为REJECT
在测试ping包符合预期。
查看命令:
[root@localhost ~]# iptables -t filter --line-number -vnL INPUT
Chain INPUT (policy ACCEPT 45 packets, 4636 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       25  2100 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246         limit: avg 10/min burst 5
2      175 14700 REJECT     icmp --  *      *       172.16.4.248         172.16.5.246         reject-with icmp-port-unreachable

同样的规则为什么执行完了1之后又执行2了呢,我们之前讲过的,同样的匹配条件不同的执行动作只会执行排在前面的,排在后面的不会被执行。
其实上面表面上看的是1和2的匹配条件都执行了,其实是执行了其中一个。1中只有6秒定时器到的时候才执行的,所以执行1的时候其实2没执行,所以报文才能行出去。
而条目2,是在1的6秒定时器执行的,因为6秒定时器未到,1其实是不匹配报文的。

关于burst 5(限速令牌桶):
这个是限速产生的默认值令牌桶,该桶里默认5个通行令牌。
由于是隔了6秒钟,定时器一到,就有5个报文,每个报文拿了一个令牌,总共5个令牌拿光了其他报文就无法通行,所以每次定时器到6秒时正好桶里有5个令牌,所以只能通过5个报文。
但真正在网络,并不一定是5个报文通过,因为令牌被通行的报文取走,只有该通行报文释放令牌后才能被其他报文获取。
修改下burst令牌个数:
iptables -t filter -I INPUT -p icmp -m limit --limit 10/minute --limit-burst 1 -j ACCEPT//修改成桶里只有一个通行令牌

8.8 "--tcp-flags" 匹配tcp头部flag字段
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH(前六个标识tcp头部中的所有flag) SYN(该字段表示需要匹配的头部flag)-j REJECT 
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags SYN,ACK,FIN,RST,URG,PSH(前六个标识tcp头部中的所有flag) SYN,ACK(该字段表示需要匹配的头部flag为SYN,ACK)-j REJECT 
  还可以写成:
  iptables -t filter -I INPUT -m tcp --dport 22 --tcp-flags ALL(前六个标识tcp头部中的所有flag) SYN,ACK(该字段表示需要匹配的头部flag为SYN,ACK)-j REJECT 
  还可以写成:
  iptables -t filter -I INPUT -m tcp --dport 22 --syn SYN,ACK(该字段表示需要匹配的头部flag为SYN,ACK)-j REJECT 
  
8.9 UDP扩展匹配
 iptables -t filter -I INPUT -p udp -m udp --dport 5000:6000 -j DROP
 
8.10 ICMP扩展匹配
   iptables -t filter -I INPUT -s 172.16.4.248 -p icmp -m icmp --icmp-type 8/0 -j DROP
   --icmp-type 8/0:表示扩展属性为icmp,8/0表示icmp类型为8的请求消息,0表示请求消息的code码为0
   
8.11 根据报文状态来扩展匹配
172.16.5.246上配置:
iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -t filter -I INPUT -m state --state NEW,INVALID,UNTRACKED -j DROP
根据ping包结果,172.16.4.248 ping向5.246无法ping通,但5.246ping向4.248可以ping通。因为5.246发出去的报文再次收到回应报文,有过第一次发包,报文为RELATED状态,再次收到就是ESTABLISHED状态。
而4.248ping向5.246之所以ping不通,是因为4.248ping的第一个包在5.246上就找不到任何状态,即为NEW状态,而该状态被设置为DROP。
我们在5.246上修改下命令:
iptables -t filter -I INPUT -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT
iptables -t filter -I INPUT -m state --state INVALID,UNTRACKED -j DROP
修改命令后,左右报文都可以ping通。

NEW状态:可以理解为第一个包,记录NEW状态;
ESTABLISHED状态:可以理解为NEW状态下收到的第二个包,或本地回应NEW状态的第一个报文之后达到ESTABLISHED状态;
RELATED状态:譬如FTP的数据控制通道(即命令通道)和数据转发通道(传输通道),即可看做RELATED状态。
INVALID状态:一个报文没有办法被识别
UNTRACKED状态:表示该报文未被追踪,该状态时正常无法找到相关链接。


8.12 扩展属性自定义链
自定义链一定是通过原有链中缺省行为来调用执行的(譬如原有INPUT\FORWARDING\OUTPUT链)
譬如自定义一个链名称为ZHUWEI_TEST
iptables -t filter -N ZHUWEI_TEST //在filter表中创建一个ZHUWEI_TEST链,名称为ZHUWEI_TEST
iptables -t filter -I ZHUWEI_TEST -s 172.16.4.248 -d 172.16.5.246 -j DROP //在自定义链ZHUWEI_TEST中增加匹配规则和行为
//此时从4.248ping5.246还是可以ping通,发现虽然定义了自定义链ZHUWEI_TEST和链中的匹配规则和行为,但如何让报文走到自定义链中呢。
  需要把ZHUWEI_TEST自定义链作为执行的行为放入到缺省链中来调用。如下:

iptables -t filter -I INPUT -j ZHUWEI_TEST //即把ZHUWEI_TEST作为行为放入到INPUT链中作为行为来调用(此时把ZHUWEI_TEST看做和ACCEPT\REJECT\DROP同等平行的东西)
再次从4.248 ping 5.246发现ping不通,规则生效。
理解为:
报文过来发现filter表中INPUT链没有任何符合的匹配规则,
该报文走缺省行为执行动作,在走缺省行为时发现缺省行为中还挂着ZHUWEI_TEST链,该报文继续匹配ZHUWEI_TEST链中的规则,匹配上后走DROP.
若ZHUWEI_TEST中的规则也匹配不上该报文,该报文继续执行INPUT中的缺省动作ACCEPT。
报文匹配规则如下:(以filter表INPUT链为例)INPUT链中非自定义链规则匹配--->缺省行为中的自定义链匹配---->缺省行为

其他相关命令:
iptables -t filter -E ZHUWEI_TEST ZHUWEI_TEST_RENAME //自定义链重命名
删除三步走:iptables -t filter -D INPUT 1//删除自定义链在INPUT中的引用,方式雷同其他直接匹配规则
            iptables -t filter -F ZHUWEI_TEST_RENAME //删除自定义链中所有匹配项
            iptables -t filter -X ZHUWEI_TEST_RENAME //删除自定义链

其他思考:自定义链既然和其他正常的匹配规则一样存放在INPUT链中,那是否排列在INPUT表的最前面就优先匹配呢,动手实验一下:
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j ACCEPT//增加一条和ZHUWEI_TEST完全一样的匹配规则,只是执行结果不一致。
[root@localhost ~]# iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j ACCEPT
[root@localhost ~]# iptables -t filter --line-number -nvL 
Chain INPUT (policy ACCEPT 40 packets, 6356 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1        2   168 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246        
2     9282 1300K ZHUWEI_TEST_RENAME  all  --  *      *       0.0.0.0/0            0.0.0.0/0  

此时发现报文可以ping通,这个不能说明问题,我们把顺序调整一下。
[root@localhost ~]# iptables -t filter -D INPUT 2
[root@localhost ~]# iptables -t filter -I INPUT -j ZHUWEI_TEST_RENAME
[root@localhost ~]# iptables -t filter --line-number -nvL 
Chain INPUT (policy ACCEPT 28 packets, 4428 bytes)
num   pkts bytes target     prot opt in     out     source               destination         
1       30  4596 ZHUWEI_TEST_RENAME  all  --  *      *       0.0.0.0/0            0.0.0.0/0     //自定义链排在第一位,并没有优先匹配      
2      183 15372 ACCEPT     icmp --  *      *       172.16.4.248         172.16.5.246        

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

Chain OUTPUT (policy ACCEPT 19 packets, 3966 bytes)
num   pkts bytes target     prot opt in     out     source               destination         

Chain ZHUWEI (0 references)
num   pkts bytes target     prot opt in     out     source               destination         

Chain ZHUWEI_TEST_RENAME (1 references)
num   pkts bytes target     prot opt in     out     source               destination  
此时报文仍然可以ping通,说明自定义链确实是在其他所有非定义链规则没有匹配项目之后才去考虑匹配的。再次思考下,假如有多个自定义链,这些自定义链之中的规则是不是遵从顺序优先级呢
动手实验一下:再次增加一个完全匹配的自定义链,行为为REJECT,且在自定义链中顺序优先级高,理论上应该先匹配到。(!!!经过实验不完全是这样,需要看代码确认)

综合:
(以filter表INPUT链为例)INPUT链中非自定义链规则匹配(按照num从1--->6--->...的顺序优先级为高--->次高--->...--->低进行匹配)--->缺省行为中的自定义链匹配(按照num从1--->6--->...的顺序优先级为高--->次高--->...--->低进行匹配)---->缺省行为


8.13黑白名单
缺省行为为ACCEPT,然后匹配规则里增加DROP/REJECT的行为为黑名单
iptables -t filter -P INPUT ACCEPT
缺省行为为DROP/REJECT,然后匹配规则里增加ACCEPT的行为为白名单
iptables -t filter -P INPUT DROP/REJECT
黑白名单综合应用:
iptables -t filter -P INPUT ACCEPT
iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -j ACCEPT
iptables -t filter A INPUT -j REJECT/DROP //在原有通行报文的基础上拒绝/丢弃其他所有报文,即在白名单的基础上应用了黑名单


8.14 iptables作为防火墙使用
防火墙的作用是过滤和转发功能,过滤做在filter表,FORWARD阶段中存在filter表又具备转发功能,防火墙坐在这个阶段比较合适。
linux默认是关闭转发功能的,需要先打开转发(临时生效):
echo 1 > /proc/sys/net/ipv4/ip_forward
sysctl -w net.ipv4.ip_forward=1
永久生效:
vim /etc/sysctl.conf  
net.ipv4.ip_forward = 1

8.15 iptables动作日志记录
自定义日志文件:
vim /etc/rsyslog.conf 
kern.warning /var/log/iptables.log
重启log服务

iptables -t filter -I INPUT -s 172.16.4.248 -d 172.16.5.246 -p icmp -j LOG


9.取反操作
iptables -t filter -I INPUT 2 -s !172.16.4.248 -d 172.16.6.231 -p tcp -j REJECT
!:表示非172.16.4.248源地址发往172.16.6.231上的tcp协议报文采用拒绝且回应的方式,
  注意:规则只定义了非172.16.4.248,但172.16.4.248发往172.16.6.231的报文依然能够通过,
        因为匹配时并没有找到源172.16.4.248发往172.16.5.246的匹配规则,所以只能走默认放行的规则。假如表filter的INPUT链默认规则是放行的话。

        
10.匹配规则之常用动作
    ACCEPT\DROP\REJECT\LOG\SNAT\DNAT\MASQUERADE\REDIRECT
    //公网访问局域网的MYSQL数据库服务器
    公网区域PC1(eth1:10.42.188.2)---------(公网ETH1:10.42.205.221)PC2(局域网ETH2:172.16.4.250)-----------(ETH1:172.16.4.248)PC3(局域网MYSQL服务器)
    PC2上起iptables功能即充当防火墙
    
    
    iptables -t nat -I PREROUTING -d 10.42.205.221 -p tcp --dport 3306 -j DNAT --to-destination 172.16.4.248:3306
    //公网访问局域网的数据目的地址和端口号转换成MYSQL服务器地址和端口号,因为是目的报文的目的地址要替换所以要做在报文刚进来的PREROUTING阶段
    iptables -t nat -I POSTROUTING -s 172.16.4.0/24 -j SNAT --to-source 10.42.205.221
    //即回应报文需要修改原地址为防火墙地址,所以要坐在POSTROUTING即出口最后一关卡阶段(也可以坐在OUTPUT阶段,各位自己试验)
    
    
    若上诉组网中,PC2局域网采用拨号上网的话,PC2的ETH1公网地址会经常发生变化,这样使用SNAT或DNAT就很不方便,由此引入MASQUERADE动作
    iptables -t nat -I POSTROUTING -s 172.16.4.0/24 -o ETH1 -j MASQUERADE  //表示每次匹配上以后都会取ETH1上可用的公网IP地址做替换,除了有这种动态IP场景,否则没必要使用MASQUERADE
    
    
    //使用REDIRECT进行端口重映射,只能坐在PREROUTING\OUTPUT阶段
    iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080 //将80端口重新映射成8080端口
    
    
    
        
11.保存配置
service iptables save
文件保存在/etc/sysconfig/iptables文件中,centos7版本中默认使用firewall,需要yum install -y iptables-services

12.总结篇之常用套路

 A.顺序的重要性,放在前面的先匹配,全完一致的规则也是前面的匹配到执行对应的动作,后面完全一样的规则匹配不到。但前面是-j LOG除外。
 B.在没有强行顺序要求的前提下,尽量是匹配报文流量大的放前面,这样能够节约性能。譬如每小时匹配到2000的报文放前面,每小时匹配到1000的报文规则在后面。
 

 

 

 

参考资料:来源于互联网

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章