本文基于Linux上CentOS 7版本配合iptables、iptables-services、firewalld等服务进行演示
一.防火墙概念以及Netfilter机制介绍
1.概念
2.防火墙两大类型
3.Netfilter功能
二..iptables原理
1.iptables介绍
2.主要工作流程介绍:
3.链介绍
4.表介绍
5.表链关系
6.综上所述,iptables的流量流动流程图示为:
7.iptables规则命令参数介绍
8.iptables上处理的动作/策略
9.iptables简单配置演示
10.iptables例题演示
三.firewalld(区域)简介
1.简介
2.firewalld的常见区域及对应的策略
3.firewall-cmd命令参数介绍
4.firewall-cmd简单配置演示
5.firewalld例题演示
6.firewalld富规则介绍
防火墙是计算机中基于预定安全规则来监视和控制传入和传出网络流量的网络安全系统(位于内部网和外部网之间的屏障),计算机流入流出的所有网络通信均要经过防火墙。防火墙会对流入和流出的通信流量进行扫描,阻断部分不法攻击,同时也可以用于生活、工作和学习中对某些网站或服务的特定访问需求。
硬件防火墙:带有特别设计的硬件及芯片,部分功能由硬件实现,实际上是硬件配合软件共同工作,主要以提供数据包数据的过滤机制为主,会将不必要功能取消掉,这种防火墙性能高、成本高。
软件防火墙:保护系统网络安全的一套软件,性能比硬件防火墙低、成本低,类似于Windows上的Windows Defender就属于软件防火墙,Linux系统也提供了软件防火墙——Netfilter(数据包过滤机制)
(1)主要分析OSI协议内的第2、3、4(数据链路层、网络层、传输层)层的数据包,将数据包的头部数据提取出来分析,决定该为连接放行或阻断
(2)拒绝Internet的数据包进入你Linux主机的(若干)端口
(3)拒绝(若干)IP地址/MAC地址发送的数据包进入
(4)阻断带有特殊标志的数据包进入,最常拒绝的是带有SYN主动连接标志的连接
(5)数据包过滤、数据包处理、地址伪装、透明代理、动态网络地址转换、基于用户及媒体访问控制地址的过滤和基于状态的过滤、包速率限制、数据包内容修改
iptables是一个应用层的应用程序主要针对IPv4地址,IPv6使用的是ip6tables,通过Netfilter放出的接口来存放对应的内核空间中的Netfilter的配置表进行修改,这个表由表tables、链chains、规则rules组成,一个链下一般会有若干个规则,从上到下读取规则,一旦匹配成功就结束
Linux系统内存分用户空间和内核空间,内核空间直接调用系统资源运行内核代码,用户空间的陈程序不能直接调用系统资源,需要配合内核提供的接口使用
(1)某服务器内包含服务器网卡、系统中的用户空间和内核空间,计算机通过网卡向系统内核空间流入流量进入作路由选择前的prerouting链
(2)内核空间判断出流量目标是否为防火墙本机,是则进行流量入站给到input链,不是则进入forward链转发此流量数据包给路由选择后的postrouting链,再通过网卡流出去给其他服务器
(3)如果进入input链,则此数据包会继续进入用户空间使用服务/程序
(4)若是用户空间内服务/程序需要流出流量数据包,从系统内核空间将包传给内核空间给到output输出链,再给到路由选择后的postrouting链,最后通过网卡流出访问其他服务器。
(1)INPUT链:接收到防火墙本机地址的数据包流入时,应用其下规则。主要应用在主机防火墙中,针对服务器本机进出作数据的安全控制
(2)OUTPUT链:防火墙流出流量时,应用其下规则。主要应用在主机防火墙中,针对服务器本机进出作数据的安全控制
(3)FORWARD链:接收到需要通过防火墙转发需求时,应用其下规则。一般应用在网络防火墙中或者防火墙服务器作为网关使用时的情况
(4)PREROUTING链:在对数据包作路由选择前,应用其下规则。一般应用在网络防火墙中或者防火墙服务器作为网关使用时的情况
(5)POSTROUTING链:在对数据包作路由选择后,应用其下规则。一般应用在网络防火墙中或者防火墙服务器作为网关使用时的情况
多条具有相同功能的规则组合在一起称表
(1)filter表:主要用于对数据包过滤,根据具体的规则决定是否放行该数据包(如DROP、ACCEPT、REJECT、LOG),所谓的防火墙其实基本上是指这张表上的过滤规则,对应内核模块iptables_filter
(2)nat表:实现网络地址转换功能,主要用于修改数据包的IP地址、端口号等信息(网络地址转换,如SNAT、DNAT、MASQUERADE、REDIRECT)。属于一个流的包(因为包的大小限制导致数据可能会被分成多个数据包)只会经过这个表一次,如果第一个包被允许做NAT或Masqueraded,那么余下的包都会自动地被做相同的操作,不会再通过这个表。对应内核模块iptables_nat
(3)mangle表:拆解报文,做出修改,并重新封装,主要用于修改数据包的TOS(Type Of Service,服务类型)、TTL(Time To Live,生存周期)指以及为数据包设置Mark标记,以实现Qos(Quality Of Service,服务质量)调整以及策略路由等应用,由于需要相应的路由设备支持,因此应用并不广泛。对应内核模块iptables_mangle
(4)raw表:主要用于决定数据包是否被状态跟踪机制处理,在匹配数据包时,raw表的规则要优先于其他表,对应内核模块iptables_raw
(1)五条链下的表都不一定相同,并且有一定的匹配顺序:从上至下为raw——mangle——nat——filter
(2)表对应的能应用的链
raw:prerouting、output
mangle:prerouting、input、forward、output、postrouting
nat:prerouting、CentOS 7上input、output、postrouting
filter:input、forward、output
参数 | 实现功能 |
-t |
指定表进行操作,raw、nat、filter、mangle中的一个,默认filter |
-p |
指定需要匹配的数据包协议类型 |
-s | 指定一个或者一组地址作为源地址,按此规则进行过滤。当后面没有mask 时,address 是一个地址,当 mask 指定时,可以表示一组范围内的地址(网段),格式为:-s ip/(mask) |
-d |
指定一个或者一组地址作为目标地址,按此规则进行过滤,格式为:-d ip/(mask) |
-i | 指定数据包来自哪个网络接口,只对 INPUT、FORWARD、PREROUTING 三个链起作用。若没有指定此选项, 表示任何一个网络接口都可以,也可以用"!" 表示非某接口(除了这个接口),格式为:-i 接口名称 |
-o | 指定数据包流出的网络接口,只对 OUTPUT,FORWARD,POSTROUTING 三个链起作用,格式同-i |
-L | 列出链上面的所有规则,如果没有指定链,则表示列出表上所有链的所有规则 |
-A | 在指定链的末尾插入(追加)指定的规则,这条规则会被放到最后,最后才会被执行,格式为:-A 链名 规则 |
-I | 在链中的指定位置的前面插入一条或多条规则,格式为:-I 链名 规则号 规则 |
-D | 在指定的链中删除一个或多个指定规则,格式为:-D 链名 规则/规则号 |
-R | 修改/替换第几条规则 |
-P | 为指定的链设置策略,只有内置的链才允许有策略,用户自定义的是不允许的,格式为:-P 链名 策略 |
-F | 清空指定链上面的所有规则,如果没有指定链,清空该表上所有链的所有规则,谨慎使用 |
-N | 创建新链并指定名称,格式为:-N 链名 |
-X | 删除指定的链,这个链必须没有被其它任何规则引用,而且这条上必须没有任何规则。如果没有指定链名,则会删除该表中所有非内置的链,格式为:-X 链名 |
-E | 重命名指定的链,不改变内容,格式为:-E 旧链名 新链名 |
-Z | 把指定链计数器清零,不指定链就表示将表中的所有链上的所有计数器清零,格式为:-Z 链名 |
-j | 满足某条件时该执行什么样的策略,策略可以是内置的目标,比如 ACCEPT,也可以是用户自定义的链 |
-h | 显示帮助信息 |
(1)ACCEPT:允许数据包通过
(2)DROP:直接丢弃数据包,不回应任何信息,客户端只有当该链接超时后才会有反应
(3)REJECT:拒绝数据包,会给客户端发送一个数据包被丢弃的响应的信息
(4)SNAT:源地址转换,在进入路由层面的route之后,出本地的网络栈之前,改写源地址,目标地址不变,并在本机建立NAT表项,当数据返回时,根据NAT表将目的地址数据改写为数据发送出去时候的源地址,并发送给主机,用于解决私网用户用同一个公网IP上网的问题
(5)MASQUERADE:是SNAT的一种特殊形式,适用于动态的、临时会变的IP
(6)DNAT:目标地址转换,解决私网服务端,接收公网请求的问题。和SNAT相反,IP包经过route之前,重新修改目标地址,源地址不变,在本机建立NAT表项,当数据返回时,根据NAT表将源地址修改为数据发送过来时的目标地址,并发给远程主机。可以隐藏后端服务器的真实地址
(7)REDIRECT:在本机上作端口映射
(8)LOG:在/var/log/messages文件中记录日志信息,然后将数据包传递给下一条规则。除去最后一个LOG,前3条规则匹配数据包后,该数据包不会再往下继续匹配了,需要注意编写顺序
(1)安装iptables和启动工具iptables-services并启动iptables
注意:要使用iptables需要先关闭firewalld(可参考专栏相关文章)
[root@sulibao ~]# yum install -y iptables
[root@sulibao ~]# yum install -y iptables-services
[root@sulibao ~]# systemctl start iptables
(2)查看当前所有链的所有规则
iptables -vnL 这里的n是指以数字形式列出,主要是为了查看地址等,v表示详细信息
同时还可以加上--line-numbers显示出规则号
Chain INPUT 表示INPUT链上的规则
policy ACCEPT表示默认策略是允许,表示不设置策略时默认按什么策略处理,一般默认是允许我们设置规则就设置拒绝。反之同理
pkts表示包的数量
bytes表示流经的数据包的字节数
target表示动作/策略
prot表示协议
opt表示选项
in表示从哪个网卡流入
out表示从哪个网卡流出
source表示源地址,ip/网段、主机名、域名
destination表示目标地址,ip/网段、主机名、域名
dpt:80表示目标端口
spt:xx就表示源端口
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
32 4464 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
(3)当iptables服务开启后可以到浏览器查看之前稳重中搭建的web服务内容是否还能访问到,即httpd服务是否还能用,可以看到此时http服务无法使用,需要允许该服务产生的流量进入
(4)为httpd服务添加一条规则使其能够访问网站内容
[root@sulibao ~]# iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
//这里是新添加一条规则在最前面,即使默认策略是ACCEPT我也可以将策略指定为ACCEPT
//如果这里使用-A在末尾进行追加规则,那么可能会因为前面的规则匹配上停止匹配而失效
[root@sulibao ~]# iptables -vnL --line-numbers
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
2 1744 118K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
3 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
4 1 60 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
5 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22
6 757 59027 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
再去看网站就已经可以访问了
开启iptables防火墙,实现以下功能,可以正常使用ssh服务、dns服务、httpd服务、chrony服务、nfs服务
[root@sulibao ~]# iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT
[root@sulibao ~]# iptables -t filter -I INPUT -p tcp --dport 22 -j ACCEPT
[root@sulibao ~]# iptables -t filter -I INPUT -p tcp --dport 53 -j ACCEPT
[root@sulibao ~]# iptables -t filter -I INPUT -p udp --dport 323 -j ACCEPT
[root@sulibao ~]# iptables -t filter -I INPUT -p udp -m multiport --dports 2049,111 -j ACCEPT
[root@sulibao ~]# iptables -vnL --line-number
Chain INPUT (policy DROP 0 packets, 0 bytes)
num pkts bytes target prot opt in out source destination
1 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 multiport dports 2049,111
2 0 0 ACCEPT udp -- * * 0.0.0.0/0 0.0.0.0/0 udp dpt:323
3 0 0 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:53
4 680 46806 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:22
5 36 5302 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:80
6 343 23884 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
7 0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0
8 0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
9 79 5851 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
firewalld 所提供的模式相对于iptables可以叫做动态防火墙,它可以解决iptables重载会重新加载全部防火墙策略和文件这一问题,只需要将变更部分保存并更新即可,同时具备对 IPv4 和 IPv6 防火墙设置的支持。firewalld支持动态更新技术并加入了区域的概念(区域:firewalld预先准备了几套防火墙策略集合,用户可以选择不同的集合,从而实现防火墙策略之间的快速切换)
这些区域文件放置在/usr/lib/firewalld/zones/下
[root@sulibao ~]# cd /usr/lib/firewalld/zones/
[root@sulibao zones]# ll
total 36
-rw-r--r-- 1 root root 299 Apr 28 2021 block.xml
-rw-r--r-- 1 root root 293 Apr 28 2021 dmz.xml
-rw-r--r-- 1 root root 291 Apr 28 2021 drop.xml
-rw-r--r-- 1 root root 304 Apr 28 2021 external.xml
-rw-r--r-- 1 root root 369 Apr 28 2021 home.xml
-rw-r--r-- 1 root root 384 Apr 28 2021 internal.xml
-rw-r--r-- 1 root root 315 Apr 28 2021 public.xml
-rw-r--r-- 1 root root 162 Apr 28 2021 trusted.xml
-rw-r--r-- 1 root root 311 Apr 28 2021 work.xml
区域 | 策略 |
block阻塞区域 | 拒绝流入的(除了与流出流量有关)流量 |
work工作区域 | 拒绝流入的(除了与流出流量有关)流量 |
home家庭区域 | 拒绝流入的(除了与流出流量有关)流量 |
public公共区域 | 不信任网络中的任何计算机,只允许接收传入的网络连接 |
dmz隔离区域/非军事区域 | 是内外网络之间增加的一层网络,起缓冲作用,只接受传入的网络连接 |
trusted信任区域 | 允许所有数据包传入 |
drop丢弃区域 | 拒绝流入的(除了与流出流量有关)流量 |
internal内部区域 | 拒绝流入的(除了与流出流量有关)流量 |
external外部区域 | 拒绝流入的(除了与流出流量有关)流量,但允许与ssh服务相关的流量 |
firewall-cmd --xx-
参数 | 功能 |
--get-default-zone | 查询当前默认的区域名称 |
--set-default-zone=区域名称 | 设置默认的区域并使其永久生效 |
--get-zones | 显示可用的区域 |
--get-services | 显示命令支持的服务 |
--get-active-zones | 显示当前正在使用的区域与网卡名称 |
--add-interface=网卡名称 | 将源自该网卡的所有流量都导向某个指定区域 |
--change-interface=网卡名称 | 将某个网卡和区域进行关联 |
--remove-source= | 不将来自此IP或子网的流量导向某个指定区域 |
--add-source= | 将来自此IP或子网的流量导向指定的区域 |
--list-all | 显示当前区域的网卡配置参数、资源、端口以及服务等信息 |
--list-all-zones | 显示所有区域的网卡配置参数、资源、端口以及服务等信息 |
add-service=服务名 | 设置默认区域允许该服务的流量 |
--add-port=端口号/协议 | 设置默认区域允许该端口的流量 |
--remove-service=服务名 | 设置默认区域不允许该服务的流量 |
--remove-port=端口号/协议 | 设置默认区域不允许该端口的流量 |
--reload | 让“永久生效”的配置规则立即生效,并覆盖当前的配置规则 |
--panic-on | 开启应急状况模式,所有与规则都拒绝 |
--panic-off | 关闭应急状况模式 |
--query-panic | 查询紧急状态模式 |
--version | 查看版本 |
--help | 查看帮助 |
--state | 显示状态 |
--permanent |
实现永久生效 |
(1)首先关闭iptables,下载firewalld服务并开启
[root@sulibao ~]# systemctl stop iptables
[root@sulibao ~]# yum install -y firewalld
[root@sulibao ~]# systemctl start firewalld
(2)firewalld服务开启后仍然是可以先试试能不能访问到web网站内容,如图示不能访问需要为httpd服务设置允许流量通过,firewall-cmd --add-service=http
[root@sulibao ~]# firewall-cmd --permanent --add-service=http
success
此处若不生效可以先重载试试
开启firewalld防火墙,实现以下功能:可以正常使用ssh服务、dns服务、httpd服务、chrony服务、nfs服务,并且访问第一台虚拟机的web服务的80端口转发到第二台机器的8080端口
(1)允许ssh服务、dns服务、httpd服务、chrony服务、nfs服务服务
firewall-cmd --add-service=http --permanent
[root@sulibao ~]# firewall-cmd --add-service=ssh --permanent
success
firewall-cmd --add-service=dns --permanent
[root@sulibao ~]# firewall-cmd --add-service=dns --permanent
success
firewall-cmd --add-service=http --permanent
[root@sulibao ~]# firewall-cmd --add-service=http --permanent
success
firewall-cmd --add-service=ntp --permanent
[root@sulibao ~]# firewall-cmd --add-service=ntp --permanent
success
firewall-cmd --add-service=nfs --permanent
firewall-cmd --add-service=rpc-bind --permanent
firewall-cmd --add-service=mountd --permanent
[root@sulibao ~]# firewall-cmd --add-service=nfs --permanent
success
[root@sulibao ~]# firewall-cmd --add-service=rpc-bind --permanent
success
[root@sulibao ~]# firewall-cmd --add-service=mountd --permanent
success
(2)第一台虚拟机的web服务的80端口转发到第二台机器的8080端口
前提先开启ip伪装
[root@sulibao ~]# firewall-cmd --add-masquerade --permanent
success
//也可以修改/proc/sys/net/ipv4/ip_forward内的0为1,保存退出
[root@sulibao ~]# vim /proc/sys/net/ipv4/ip_forward
再进行配置
firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.xx.xx --permanent
[root@sulibao ~]# firewall-cmd --zone=public --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.xx.xx --permanent
success
//端口转发
[root@sulibao ~]# firewall-cmd --zone=public --list-forward-ports
port=80:proto=tcp:toport=8080:toaddr=192.168.xx.xx
//查看端口转发列表
[root@sulibao ~]# firewall-cmd --remove-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.xx.xx --permanent
success
//移除端口转发
此处若转发失败可以先检查你的第二台虚拟机是否下载并httpd服务,防火墙是否关闭等
富规则可以定义更复杂的规则
(1)富规则帮助文档firewalld.richlanguage,提供具体格式参考
[root@sulibao ~]# man firewalld.richlanguage
rule
[source]
[destination]
service|port|protocol|icmp-block|icmp-type|masquerade|forward-port|source-port
[log]
[audit]
[accept|reject|drop|mark]
......
(2)以上文的端口转发例题来演示
[root@sulibao ~]# firewall-cmd --add-rich-rule 'rule family="ipv4" forward-port port="80" protocol="tcp" to-port="8080" to-addr="192.168.2.136"'
//
--add-rich-rule为固定命令
rule family指定ipv4或ipv6
forward port表示端口转发,port指定进行转发的端口
protocol指定协议
to-port指定目标地址的端口
to-addr指定目标地址