Linux的防火墙体系主要工作在网络层,针对TCP/IP数据包实施过滤和限制。属于典型的包过滤防火墙。linux系统的防火墙体系基于内核编码实现,具有非常稳定的性能和极高的效率,因此获得广泛的应用。
在很多安全技术资料中,netfilter和iptables都用来指linux防火墙,区别如下:
iptables的作用是为包过滤机制的实现提供规则,通过各种不同的规则,告诉netfilter对来自某些源,前往某些目的或具有某些协议特征的数据包应该如何处理,为了更加方便的组织和管理防火墙规则,iptables采用了表和链的分层结构
其中,每个规则表相当于内核空间的一个容器,根据规则集的不同用途划分为默认的四个表,在每个表容器内又包括不同的规则链,根据处理数据包的不同时机划分为五种链
iptables管理着4个不同的规则表:
表名称 | 规则含义 |
---|---|
filter | 根据具体的规则要求决定如何处理一个数据包 |
nat | 用来修改数据包的ip地址,端口号等信息 |
mangle | 用来修改数据包的服务类型、生命周期,或者设置mark标记实现流量整形等高级应用 |
raw | 主要用来决定是否对数据包进行状态跟踪 |
应用最多的是filter和nat。
在处理各种数据包时,根据防火墙规则的不同介入时机,iptables默认划分为五种不同的规则链:
链名称 | 规则含义 |
---|---|
INPUT | 当收到访问防火墙本机地址的数据包时,应用此链中的规则 |
OUTPUT | 当防火墙本机向外发送数据包时,应用此链中的规则 |
FORWARD | 当接收到需要通过防火墙中转发送给其他地址的数据包时,应用此链中的规则 |
PREROUTING | 在对数据包做路由选择之前,应用此链中的规则 |
POSTROUTING | 在对数据包做路由选择之后,应用此链中的规则 |
每个规则表中对应哪些规则链,如图所示:
当一个数据包到达防火墙以后,会优先选择哪一个表、哪一个链中的规则呢?
规则表应用顺序:raw→mangle→nat→filter
规则链的应用顺序取决于数据的流向:
入站数据流向:PREROUTING→路由选择→INPUT→应用程序
转发数据流向:PREROUTING→路由选择→FORWARD→POSTROUTING
出站数据流向:OUTPUT→路由选择→POSTROUTING
规则链内部的处理规则:
按第一条规则……第二条规则的顺序进行匹配处理,遵循“匹配即停止”的原则,
一旦找到一条匹配规则将不再检查后续的其他规则,如果一直找不到匹配的规则,就按默认规则处理。
语法格式:
iptables 【-t 表名】 管理选项{【链名】【匹配条件】 【-j 控制类型】
【-t 表名】如果不指定表名,默认是filter表
管理选项 | 含义 | 示例用法 |
---|---|---|
-A | 在指定链末尾追加一条 | iptables -A INPUT |
-I | 在指定链中插入一条新的,未指定序号默认作为第一条 | iptables -I INPUT |
-R | 修改、替换某一条规则 | iptables -t nat -R INPUT |
-D | 删除 | iptables -t nat -D INPUT |
-L | 查看 | iptables -L -t nat |
-F | 清除所有规则 | iptables -F |
-P | 指定默认规则 | iptables -P |
-n | 以数字形式显示 | iptables -L -n’,iptables -nL |
-n --line-number | 规则带编号 | iptables -L -n --line-number -t nat |
控制选项 | 含义 |
---|---|
ACCEPT | 允许数据包通过 |
REJECT | 拒绝数据包通过,必要时会给数据包发送端一个响应信息 |
DROP | 直接丢弃数据包,不给任何回应 |
LOG | 在/var/log/messages文件中记录日志信息,然后将数据包给下一条规则,它本身不处理数据包 |
例1:给filter表添加第一条规则,允许所有数据包访问本机
[root@firewall ~]# iptables -I INPUT -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
例2:给filter表追加一条规则,允许来自192.168.100.0网段的数据包访问本机
[root@firewall ~]# iptables -t filter -A INPUT -s 192.168.100.0/24 -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- anywhere anywhere
ACCEPT all -- 192.168.100.0/24 anywhere
注意:iptables后面必须先指定表名然后才是链名
例3:删除filter表中INPUT链中的第一条规则
[root@firewall ~]# iptables -D INPUT 1
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
all -- anywhere anywhere
例4:查看链中的条目
[root@firewall ~]# iptables -L -n --line-number
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
2 all -- 0.0.0.0/0 0.0.0.0/0
例5:清空filter表中所有规则
[root@firewall ~]# iptables -F
[root@firewall ~]#
[root@firewall ~]# 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
例6:设置filter表中OUTPUT链的默认规则
[root@firewall ~]# iptables -P OUTPUT ACCEPT
注意:-F清空链时,默认策略不受影响,默认策略也不参与链内规则的顺序编排
iptables编写协议匹配的规则时用-p指定协议名,如tcp、udp、icmp和all
例1:不允许任何主机ping本主机
[root@firewall ~]# iptables -I INPUT -p icmp -j REJECT
[root@firewall ~]# iptables -n -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT icmp -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
例2:拒绝除icmp之外的其他连接,!表示取反
[root@firewall ~]# iptables -I INPUT !-p icmp -j REJECT
iptables编写地址匹配的规则时用 -s:表示源地址,-d:表示目标地址
例1:不允许192.168.100.200这个主机ping本主机
[root@firewall ~]# iptables -I INPUT -s 192.168.100.200 -p icmp -j REJECT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT icmp -- 192.168.100.200 anywhere reject-with icmp-port-unreachable
注意:这里-s和-p两个条件前后顺序无所谓
例2:禁止192.168.100.0网段的所有主机的所有连接
[root@firewall ~]# iptables -I INPUT -s 192.168.100.0/24 -j DROP
iptables编写地址匹配的规则时用 -i 进站接口名和 -o 出站接口名的形式
例1:丢弃来自192.168.100.0网段并且从ens33接口进入的数据包
[root@firewall ~]# iptables -A INPUT -i ens33 -s 192.168.100.0/24 -j DROP
编写端口匹配规则时使用“–port 源端口”或“–dport 目标端口”的形式,针对的协议为tcp或udp,单个端口号或者以冒号分隔的端口范围都是可以的,但是不连续的端口不可以用冒号表示
例1:开放ssh连接
[root@firewall ~]# iptables -I INPUT -p tcp -dport 22 -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
all -- anywhere anywhere
编写icmp类型匹配规则时使用“–icmp-type ICMP类型”的形式,针对的协议是icmp
例1:允许本机ping别的主机但是不允许别的主机ping本机
[root@firewall ~]# iptables -A INPUT -p icmp --icmp-type 8 -j DROP
[root@firewall ~]#
[root@firewall ~]#
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpt:ssh
all -- anywhere anywhere
DROP icmp -- anywhere anywhere icmp echo-request
icmp类型:
Echo-Request:代码为8
Echo-Reply:代码为0
Destination-Unreachable:代码为3
这种匹配方式要求有额外的内核模块提供支持,必须手动以“-m 模块名称”的形式调用相应的模块
编写多端口匹配时使用“-m multiport --dports 端口列表” “-m multiport --sports 端口列表” 的形式
例1:允许开放25,80,110,143端口,以便访问邮件和网站服务
[root@firewall ~]# iptables -A INPUT -p tcp -m multiport --dport 25,80,110,143 -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere multiport dports smtp,http,pop3,imap
注意:这里–dport和–dports都可以
例2:开放ftp访问,冒号表示端口的范围从20-21端口
[root@firewall ~]# iptables -I INPUT -p tcp --dport 20:21 -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere tcp dpts:ftp-data:ftp
例3:开放ftp访问的另一种方法,写成多端口模式,端口之间用逗号分隔
[root@firewall ~]# iptables -A INPUT -p tcp -m multiport --dport 20,21 -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere multiport dports smtp,http,pop3,imap
ACCEPT tcp -- anywhere anywhere multiport dports ftp-data,ftp
编写ip地址范围匹配时使用“-m iprange --src-range IP范围” “-m iprange --dst-range IP范围” 的形式
例1:不允许192.168.100.110-192.168.100.150范围的主机经过防火墙转发数据包
[root@firewall ~]# iptables -A FORWARD -p tcp -m iprange --src-range 192.168.100.110-192.168.100.150 -j REJECT
[root@firewall ~]#
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
REJECT tcp -- anywhere anywhere source IP range 192.168.100.110-192.168.100.150 reject-with icmp-port-unreachable
编写mac地址匹配规则时使用“-m mac --mac-source MAC地址”
例1:不允许mac地址为00:0c:29:52:c0:ae的任何访问
[root@firewall ~]# iptables -A INPUT -m mac --mac-source 00:0c:29:52:c0:ae -j DROP
[root@firewall ~]#
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
DROP all -- anywhere anywhere MAC 00:0C:29:52:C0:AE
这里我们修改一下规则,虽然拒绝访问但是会给一个主机无法到达的回应:
[root@firewall ~]# iptables -R INPUT 1 -m mac --mac-source 00:0c:29:52:c0:ae -j REJECT
[root@firewall ~]#
[root@firewall ~]#
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
REJECT all -- anywhere anywhere MAC 00:0C:29:52:C0:AE reject-with icmp-port-unreachable
注意:-R修改某一条规则的时候,链名后面要加规则的数字,指定具体哪一条规则,并且把过滤的规则也要写上,哪怕只是修改控制类型也不能直接-j REJECT,否则它会视为拒绝所有!
编写iptables规则时使用“-m state --state 连接状态”的形式
常用的连接状态:
NEW:与任何连接无关的
ESTABLISHED:响应请求或者已经建立连接的
RELATED:与已有连接有相关性的,比如ftp数据连接
例1:允许响应请求的连接放行
[root@firewall ~]# iptables -I INPUT -p tcp -m state --state ESTABLISHED -j ACCEPT
[root@firewall ~]# iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT tcp -- anywhere anywhere state ESTABLISHED
内网web服务器:192.168.100.200(CentOS7.6系统)
内网出口防火墙:192.168.100.200,12.0.0.1(CentOS7.6系统两块网卡分别做内网和外网的网关)
外网web服务器:12.0.0.2(CentOS7.6系统)
1、内网web服务器经过防火墙nat地址转换之后可以访问外网服务器的web服务
2、外网web服务器经过防火墙nat地址转换之后可以访问内网服务器的web服务
关闭所有主机的Firewalld服务,安装iptables-server,开启iptables防火墙,清空所有规则,内网和外网web服务器安装httpd服务并开启
要让内网服务器可以访问外网,第一步需要开启防火墙这台服务器的路由转发功能,相当于把这台linux服务器当做是一个路由器来使用,第二步需要在防火墙的出接口做nat地址转换,将内网的ip转换成出接口的ip地址,这样,访问外网网页的时候其实外网服务器并不感知内网ip
开启防火墙服务器的路由转发功能:
配置防火墙规则(SNAT):
[root@firewall ~]# iptables -t nat -A POSTROUTING -s 192.168.100.0/24 -o ens36 -j SNAT --to-source 12.0.0.1
apache的访问日志路径:/var/log/httpd/access_log
apache的错误日志路径:/var/log/httpd/error_log
再配置一条外网经过防火墙的规则(DNAT):
[root@firewall ~]# iptables -t nat -A PREROUTING -d 12.0.0.1 -i ens36 -j DNAT --to-destination 192.168.100.200