Linux防火墙iptables介绍

时间:2022-03-03 12:30:13

介绍
网络防火墙是通过一个或多个允许或拒绝的规则来过滤网络流量的网络设备或软件。网络防火墙还可以执行更复杂的任务,例如网络地址转换,带宽调整,
提供加密隧道以及更多与网络流量相关的任务。而我们的任务就是需要去定义到底防火墙如何工作,这就是防火墙的策略,规则,
以达到让它对出入网络的IP、数据进行检测。

linux的防火墙由netfilter和iptables组成。用户空间的iptables制定防火墙规则,内核空间的netfilter实现防火墙功能。

netfilter(内核空间)位于Linux内核中的包过滤防火墙功能体系,称为Linux防火墙的“内核态”。
iptables(用户空间)位于/sbin/iptables,是用来管理防火墙的命令的工具,为防火墙体系提供过滤规则/策略,
决定如何过滤或处理到达防火墙主机的数据包,称为Linux防火墙的“用户态”。

Linux系统的防火墙功能是由内核实现的,包过滤防火墙工作在TCP/IP的网络层。用户空间的iptables制定相应的规则策略控制内核空间的netfilter处理相应的数据访问控制。
iptables用表, 链 ,规则,来实现数据包的过滤规则策略,这个三者的关系可以理解为,链是规则的集合,表是链的集合,而规则是实现具体的策略。例如:开放那些端口或关闭那些端口。iptables自定义主要的表有filter,nat,mangle表。主要的链有INPUT,OUTPUT,FORWARD链。这三个链分别过滤输入主机的数据包,主机输出的数据包,和本机转发的数据包(NAT应用时)

iptables执行规则时,是从规则表中从上至下的顺序依次匹配的,如果没遇到匹配的规则,就一条一条往下执行,如果遇到匹配的规则后,那么就执行本规则,后面的任何规则都不会在去匹配,执行后根据本规则的动作(accept,reject,log,drop等),决定下一步执行的情况。如果事先打开了某个端口服务,而后又想关闭的话,需要把写的关闭规则写到开启的前面。

这里只介绍对单机防火墙的filter表中INPUT,OUTPUT,FORWARD三个链:

一、iptables命令
iptables(选项)(参数)

选项

-t:指定要操纵的表;     #这里只介绍filter,iptables如果不指定-t参数,默认就会自动匹配filter
-A:向规则链中添加一条规则,该规则增加在原规则的后面,例如原来有3条规则使用-A选择就可以添加第4条规则;
-I:  向规则链中插入一条规则,如果没有指定此规则的顺序,默认是插入变成第一条规则;如果要添加为第3条规则,
        就在-I后面的规则链后面添加3这数字,例如在INPUT链中添加第3条规则:iptables -I INPUT 3 后面添加相应的参数
-D:从规则链中删除一条规则;
-R:替换规则链中的一条规则;
-L:显示规则链中已有的规则;
-F:清楚规则链中已有的规则;
-Z:清空规则链中的数据包计算器和字节计数器,它是计算同一数据包出现次数;
-X:删除用户自定义的链
-N:创建新的用户自定义规则链;
-n:   地址和端口以数字的形式输出:
-P(大写的p):定义规则链中的默认规则;
-p:指定要匹配的数据包协议类型;
-h:显示帮助信息;
-v:显示规则链中更多的信息,比如网络接口等;
-s:指定要匹配的数据包的源ip地址或网段;
-d:指定要匹配的数据包的目的ip地址或网段;
-j: 后面接操作策略,主要的策略有 接受(ACCEPT)、丢弃(DROP)、拒绝(REJECT)、日志记录(LOG)
-i: 网络接口,指定数据包进入本机的网络接口,不能用到OUTPUT链中。
-o:网络接口,指定数据包要离开本机所使用的网络接口,不能用到INPUT链中。
--sport:限制来源的端口号码,端口号码也可以是联系的,例如:2000:3000代表端口2000到3000的所以端口
--dport:限制目标的端口号码,端口号码也可以是联系的,例如:2000:3000代表端口2000到3000的所以端口

iptables命令选项输入顺序:
#iptables  [A/I/D/R 规则链名] [-i/o 网络接口] [-p 协议名] [-s 源IP/源子网] [-d 目标IP/目标子网] [--sport 源端口] [--dport 目标端口] [-j 策略]

上面的命令如果不指定[-i/o 网络接口]则对主机的所有接口生效,不指定[-s 源IP/源子网] [-d 目标IP/目标子网]则对代任何网络(0.0.0.0)生效,
使用[--sport 源端口] [--dport 目标端口]需要加上-p tcp或-p udp才会生效。

二、查看防火墙的设置
=====================================================================================================
Chain INPUT (policy ACCEPT 15 packets, 2135 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  439 45100 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:23

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

Chain OUTPUT (policy ACCEPT 89 packets, 16596 bytes)
 pkts bytes target     prot opt in     out     source               destination         
root@debian:~#
=====================================================================================================

上面的输出中每一个Chain就是一个链,上面有三个链INPUT,FORWARD,OUTPUT每个链括号中的policy就是默认的策略,
每一個 iptables 规则都伴随着一组记量器, 当封包符合 iptables 內的某一个规则时, 便会将包大小与数量累加到该规则所属的計量器。
下面的pkts、bytes、target、prot、opt、in、out、source、destination代表的分别是
pkts: packets, 被本规则所匹配到的报文的个数;
bytes: 被本规则所匹配到的所有报文的大小之和,会执行单位换算;
target:代表进行的操作,ACCEPT是放行,DROP是丢弃,REJECT是拒绝
prot:代表使用的数据包协议,主要有tcp、udp、icmp三种数据包协议
opt:额外的选项说明
in: 数据包的流入接口
out: 数据包的流出接口
source:规则中针对那个来源IP进行限制
destination:规则中针对那个目的IP进行限制

三、举例

1、清除所有iptables规则

root@debian:~# iptables -F
root@debian:~# iptables -X
root@debian:~# iptables -Z

2、自定义默认策略
root@debian:~# iptables -P INPUT DROP                  #进入主机的数据包默认全部丢弃,需要放行的数据包通过策略再进行放行,这样主机比较安全
root@debian:~# iptables -P OUTPUT ACCEPT          #从主机出去的数据包默认当热要放行了,但是如果主机当作代理服务之类的要考虑是否所以数据包允许通过
root@debian:~# iptables -P FORWARD DROP          #禁止主机进行NAT,如果主机当作NAT要进行相应的策略配置

3、开放指定的端口,当默认INPUT链为DROP
root@debian:~# iptables -A INPUT -p tcp --dport 22 -j ACCEPT                #允许ssh服务的22端口通过
root@debian:~# iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT            #如果把OUTPUT默认规则设置成DROP的就要写上这一条
root@debian:~# iptables -I INPUT  -p tcp --dport 22 -j ACCEPT               #插入第3条规则允许ssh服务的22端口通过
root@debian:~# iptables -A INPUT -p tcp --dport 20 -j ACCEPT                 #允许FTP服务的20端口通过
root@debian:~# iptables -A INPUT -p tcp --dport 21 -j ACCEPT                 #允许FTP服务的21端口通过
root@debian:~# iptables -A INPUT -j DROP                                                #禁止其他未允许的规则访问
root@debian:~# iptables -A FORWARD -j DROP                                        #禁止其他未允许的规则访问
root@debian:~# iptables -A OUTPUT -j ACCEPT                                        #允许所有本机向外的访问

root@debian:~# iptables -A INPUT -p tcp --sport 2222 -j ACCEPT         #这个比较特殊,是允许访问的主机应用通过2222端口发起的就允许通过,一般INPUT配
                                                                                                                    #合--sport很少用,主要是INPUT配合--dport使用,OUTPUT配合--sport使用。
4、开放指定IP或网段,当默认INPUT链为DROP
root@debian:~# iptables -I INPUT -s 127.0.0.1  -j ACCEPT                     #允许本地回环接口(即运行本机访问本机)
root@debian:~# iptables -I INPUT -s 192.168.2.100 -j ACCEPT              #允许单个IP通过的命令
root@debian:~# iptables -I INPUT -s 10.0.0.0/8 -j ACCEPT                     #允许整个网段即从10.0.0.1到10.255.255.254通过的命令
root@debian:~# iptables -I INPUT -s 192.168.2.0/24 -j ACCEPT             #允许整个网段即从192.168.2.1到192.168.2.254通过的命令
root@debian:~# iptables -I outPUT -d 192.168.2.0/24 -j ACCEPT            #如果把OUTPUT默认规则设置成DROP就要加上这一条才能允许整个网段通过

root@debian:~# iptables -I INPUT -d 192.168.2.100 -j ACCEPT              #如果被访问的服务器地址是192.168.2.100则这条命令会允许所有访问,
                                                                                                                     #一般INPUT 配合-d很少有,主要是INPUT配合-s使用,OUTPUT配合-d使用。
5、开放指定网络接口,当默认INPUT链为DROP,多用于有多个网卡的时候
root@debian:~# iptables -A INPUT -i lo -j ACCEPT                                #允许本地回环接口(即运行本机访问本机),只是这个是通过接口来实现  
root@debian:~# iptables -A OUTPUT -o lo -j ACCEPT                           #如果把OUTPUT默认规则设置成DROP的就要写上这一条
root@debian:~# iptables -A INPUT -i enp0s3 -j ACCEPT                       #允许从网卡enp0s3口进入的数据包通过
root@debian:~# iptables -A OUTPUT -o enp0s3 -j ACCEPT                  #允许从网卡enp0s3口出去的数据包通过

6、允许icmp包通过,也就是允许ping,
root@debian:~# iptables -A INPUT -p icmp -j ACCEPT  (INPUT设置成DROP的话)
root@debian:~# iptables -A OUTPUT -p icmp -j ACCEPT (OUTPUT设置成DROP的话)

7、允许从网卡enp0s3口进入的192.168.0.106地址的主机访问ssh
root@debian:~# iptables -I INPUT -i enp0s3 -s 192.168.0.106 -p tcp --dport 22 -j ACCEPT

查看刚才的配置
=========================================================================================================
root@debian:~# iptables -L -vn
Chain INPUT (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  119 14508 ACCEPT     tcp  --  enp0s3 *       192.168.0.106        0.0.0.0/0            tcp dpt:22
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:20

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

Chain OUTPUT (policy ACCEPT 5 packets, 1044 bytes)
 pkts bytes target     prot opt in     out     source               destination         
root@debian:~#
=========================================================================================================

通过上面的显示可以很清楚的看到Chain INPUT中的第一条规则是刚才插入的,因为添加了网口和IP地址的选项所以相对下面的规则,in下面多了enp0s3网卡接口
source下面多了192.168.0.106 IP地址,没有指定的选项就是全都允许了。

8、从规则链中删除一条规则
root@debian:~# iptables -D INPUT -p tcp --dport 22 -j ACCEPT           #删除ssh服务的22端口通过
root@debian:~# iptables -D INPUT  n                            #按规则序号删除,n代表INPUT链中从上让下数的第n条规则,也可用到OUTPUT和FORWARD链中

四、iptables扩展模块state
当我们为了安全把防火墙的INPUT链的默认规则设置成DROP,这样任何数据包都不能进入我们的主机,这样就会有问题,当我们访问网页时会无法显示页面的,
因为访问网页是双向的,你发出去的请求数据会返回相应的应答数据包,但是防火墙拒绝了任何数据包,所以网页无法显示。你可以开放相应的端口,
但是这只是其中的一个应用,如果要访问的应用很多你就会疯掉,需要开发多少个端口,应用对应的端口又是什么,头都大了,怎么办那?

可以用扩展模块state来实现,从字面上理解,state可以翻译为状态,但是我们可以用另外一个词来形容 <连接追踪>,那么连接的是什么,你可能下意识的想到tcp链接,对于state模块而言的连接并不能与tcp的连接等同,在TCP/IP协议中,UDP和ICMP是没有所谓的连接的,但是对于state模块来说,tcp、udp、icmp报文,都是有连接状态的,我们可以这样认为,对于state模块而言,只要两台机器在你来我往的通信,就算建立起了连接,而数据包在这个所谓的链接中是什么状态那?

在state中封包的4种链接状态分别为:

NEW
ESTABLISHED
RELATED
INVALID

这里我简单讲一下这四种链接状态。

NEW
当你在使用UDP、TCP、ICMP等协议时,发出的第一个包的状态就是“NEW”

ESTABLISHED
我们可以把NEW状态包后面的包的状态理解为ESTABLISHED,表示连接以建立。如下图:

Linux防火墙iptables介绍

RELATED
这里我大致讲一下,当你执行Linux下执行traceroute(Windows下对应的命令为tracert)命令时,这个traceroute会发出一个封包,该封包的TTL(生存时间,Time To Live)位1,当这个包遇到路由器的时候它的TTL会减少1,这时TTL = 0,然后这个包会被丢弃,丢弃这个包的路由器会返回一个ICMP Type 11的封包给你,并告诉你那个发出的数据包已尽死。而这个ICMP Type 11的链接状态就是“RELATED”。

INVALID
状态为INVALID的包就是状态不明的包,也就是不属于前面3中状态的包,这类包一般会被视为恶意包而被丢弃。

通过下面的命令允许ESTABLISHED和RELATED状态的数据包通过:
root@debian:~# iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

通过上面的命令就可以正常的访问浏览器了。

五、iptables-save命令

iptables-save命令用于将linux内核中的iptables的规则导出到标准输出设备商,通常,使用shell中I/O重定向功能将其输出保存到指定文件中。

iptables-save(选项)

选项

-c:指定要保存的iptables表时,保存当权的数据包计算器和字节计数器的值;
-t:指定要保存的表的名称。

实例:保持当前主机iptables的规则到文件/etc/local/iptables/rules.v4.1.save(这个文件的路径和名字可以自定义)
============================================================================
root@debian:~# iptables-save > /etc/local/iptables/rules.v4.1.save

root@debian:~# cat /etc/local/iptables/rules.v4.1.save
# Generated by iptables-save v1.6.0 on Wed Sep 26 22:23:57 2018
*filter
:INPUT DROP [17:2067]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [44:7568]
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
# Completed on Wed Sep 26 22:23:57 2018
root@debian:~#
============================================================================
通过上面的命令可以看到保存的的表为filter,三个链对应的默认策略,以及自定义的规则。

六、iptables-restore命令
iptables-restore命令用来还原iptables-save命令所备份的iptables配置。

iptables-restor(选项)

选项

-c:指定在还原iptables表时候,还原当前的数据包计数器和字节计数器的值;
-t:指定要还原表的名称。

实例
root@debian:~# iptables-restore   <  /etc/local/iptables/rules.v4.1.save

/etc/local/iptables/rules.v4.1.save是iptables-save命令所备份的文件。