admin管理员组

文章数量:1642347


一、firewalld基础知识

1.1、firewalld概述

firewalld即Dynamic Firewall Manager of Linux systems,Linux系统的动态防火墙管理器,是iptables的前端控制器,用于实现持久的网络流量规则。


1.2、firewalld和iptables的关系

1、firewalld与ipables都不是真正的防火墙,只是 用来定义防火墙规则功能的管理工具,将定义好的规则交由内核中的netfilter来实现真正的防火墙功能。

2、在RHEL7里有几种防火墙共存:firewalld、iptables、ebtables,默认是使用firewalld来管理netfilter子系统,不过底层调用的命令仍然是iptables等。


1.3、firewalld和iptables的区别

firewalld iptables
配置文件 /usr/lib/firewalld和/etc/firewalld /etc/sysconfig/iptables
对规则的修改 可动态修改规则,不丢失连接 修改规则后需全部刷新才生效,丢失连接
防火墙类型 动态防火墙 静态防火墙
使用方式 区域和服务 链式规则
默认规则 默认拒绝,需要设置才放行 默认允许,需要拒绝才去限制

1.4、firewalld网络区域

firewalld防火墙为了简化管理,将所有网络流量分为多个区域(zone)。然后根据数据包的源IP地址或传入的网络接口等条件将流量传入相应区域。每个区域都定义了自己打开或者关闭的端口和服务列表。

区域 默认规则策略
trusted(信任区域) 允许所有的传入流量
public(公共区域) 允许与ssh或dhcpv6-client预定义服务匹配的传入流量,其余均拒绝。是新添加网络接口的 默认区域
external(外部区域) 允许与ssh预定义服务匹配的传入流量其余均拒绝
home(家庭区域) 允许与ssh、mdns、samba-client或dhcpv6-client预定义服务匹配的传入流量,其他均拒绝
internal(内部区域) 默认值与home区域相同
work(工作区域) 允许与ssh、dhcpv6-client预定义服务匹配的传入流量,其他均拒绝
dmz(隔离区域也称非军事区域) 允许与ssh预定义服务匹配的传入流量,其他均拒绝
block(限制区域) 拒绝所有传入流量,但会给出回应
drop(丢弃区域) 丢弃所有传入流量,不给出回应

二、配置firewalld防火墙

2.1、Firewalld配置方法

1、使用firewall-cmd命令行工具
2、使用firewall-config图形工具
3、编写/etc/firewalld/中的配置文件


2.1、Firewalld配置模式

与Linux系统中其他的防火墙策略配置工具一样,使用firewalld配置的防火墙策略默认为运行时(Runtime)模式,又称为当前生效模式,而且会随着系统的重启而失效。

如果想让配置策略一直存在,就需要使用永久(Permanent)模式了,方法就是在用firewall-cmd命令正常设置防火墙策略时添加–permanent参数,这样配置的防火墙策略就可以永久生效了,但是,永久生效模式有一个“不近人情”的特点,就是使用它设置的策略只有在系统重启之后才能自动生效。如果想让配置的策略立即生效,需要手动执行firewall-cmd --reload命令

注意:使用永久(Permanent)模式,在不重启服务器的情况下可以使用firewall-cmd --reload 就可以立即生效。


三、firewalld命令参数

3.1、zone区域相关指令

firewall-cmd --get-zones                   	#显示总共可用的区域
firewall-cmd --get-default-zone            	#查询默认的区域名称
firewall-cmd --set-default-zone=<zone>     	#设置默认的区域,使其永久生效
firewall-cmd --get-active-zones            	#显示当前正在使用的区域与网卡名称
firewall-cmd --delete-zone=<zone>          	#删除指定域
firewall-cmd --new-zone=<zone> --permanent 	#创建指定域
firewall-cmd --zone=<zone> --list-all      	#查看指定域的详细信息
firewall-cmd --info-zone=<zone>            	#查看指定域的详细信息
firewall-cmd --list-all-zones              	#查看所有域的详细信息

3.2、services服务相关指令

firewall-cmd --new-service=<service> --permanent #创建service   
firewall-cmd --delete-service=<service> --permanent #删除service
firewall-cmd --info-service=<service> #查看指定服务的详细信息
firewall-cmd --service=<service> --set-description=<description> --permanent #设置指定服务的描述信息
firewall-cmd --service=<service> --get-description --permanent #查看指定服务的描述信息
firewall-cmd --service=<service> --set-short=<description> --permanent  #设置指定服务的描述信息
firewall-cmd --service=<service> --get-short --permanent #查看指定服务的描述信息
firewall-cmd --service=<service> --add-port=<portid>[-<portid>]/<protocol> --permanent #服务添加端口
firewall-cmd --service=<service> --remove-port=<portid>[-<portid>]/<protocol> --permanent #服务移除端口
firewall-cmd --service=<service> --query-port=<portid>[-<portid>]/<protocol> --permanent #查看服务指定端口
firewall-cmd --service=<service> --get-ports --permanent #查看服务所有端口
firewall-cmd --service=<service> --add-protocol=<protocol> --permanent #服务添加协议
firewall-cmd --service=<service> --remove-protocol=<protocol> --permanent #服务移除协议
firewall-cmd --service=<service> --query-protocol=<protocol> --permanent #查看服务指定协议
firewall-cmd --service=<service> --get-protocols --permanent #查看服务所有协议 
firewall-cmd --service=<service> --add-source-port=<portid>[-<portid>]/<protocol> --permanent #服务添加源端口
firewall-cmd --service=<service> --remove-source-port=<portid>[-<portid>]/<protocol> --permanent #服务移除源端口
firewall-cmd --service=<service> --query-source-port=<portid>[-<portid>]/<protocol> --permanent #服务查看指定源端口
firewall-cmd --service=<service> --get-source-ports --permanent #服务查看所有源端口
firewall-cmd --service=<service> --set-destination=<ipv>:<address>[/<mask>] --permanent #服务添加访问的目标ip
firewall-cmd --service=<service> --remove-destination=<ipv> --permanent #服务移除访问的目标ip
firewall-cmd --service=<service> --query-destination=<ipv>:<address>[/<mask>] --permanent #服务查看指定的目标ip
firewall-cmd --service=<service> --get-destinations --permanent #服务查看所有目标ip

3.3、port端口相关指令

firewall-cmd --list-ports        #查看默认区域所有端口 
firewall-cmd --add-port=<portid>[-<portid>]/<protocol>  --permanent     #设置默认区域允许该端口          
firewall-cmd --remove-port=<portid>[-<portid>]/<protocol>  --permanent  #移除默认区域允许该端口        
firewall-cmd --query-port=<portid>[-<portid>]/<protocol> --permanent    #查看默认区域指定端口

3.4、interface网卡相关指令

firewall-cmd --list-interfaces #查看默认区域网卡接口   
firewall-cmd --add-interface=<interface> --permanent #将某个网卡绑定到某个指定区域
firewall-cmd --change-interface=<interface> #将某个网卡与区域进行关联
firewall-cmd --query-interface=<interface>
firewall-cmd --remove-interface=<interface>

3.5、其它指令

firewall-cmd --list-all	#显示当前区域的网卡配置参数、资源、端口以及服务等信息
firewall-cmd --reload	#让“永久生效”的配置规则立即生效,并覆盖当前的配置规则

四、使用firewall-cmd命令行工具

4.1、区域管理

1、查看所有可用的区域
firewall-cmd --get-zones

2、查看默认区域
firewall-cmd --get-default-zone

3、查看当前活动区域
firewall-cmd --get-active-zones

4、查询指定区域配置信息
firewall-cmd --zone=public --list-all
5、查看指定区域配置文件路径
firewall-cmd --path-zone=public --permanent

6、新增区域
firewall-cmd --new-zone=test --permanent
firewall-cmd --new-zone-from-file=/etc/firewalld/zones/public.xml --name=test --permanent

7、删除区域
firewall-cmd --delete-zone=test --permanent

8、设置默认区域
firewall-cmd --set-default-zone=public 

4.2、服务管理

firewalld会优先使用/etc/firewalld/中的配置,如果不存在配置文件,则使用/usr/lib/firewalld/中的配置。

1、/etc/firewalld/:用户自定义配置文件,需要时可通过从/usr/lib/firewalld/ 中拷贝。
2、/usr/lib/firewalld/ :默认配置文件,不建议修改,若恢复至默认配置,可直接删除/etc/firewalld/ 中的配置。

当默认提供的服务不适用或者需要自定义某项服务的端口时,我们需要将service配置文件放置在/etc/firewalld/services/目录中。

service配置具有以下优点:

1、通过服务名字来管理规则更加人性化。
2、通过服务来组织端口分组的模式更加高效,如果一个服务使用了若干个网络端口,则服务的配置文件就相当于提供了到这些端口的规则管理的批量操作快捷方式。

service文件中的标签解释:

1、version:version是service节点的一个可选属性,用于表示service的版本。
2、short:short在zone、icmptype等配置文件中也存在,其作用是简介,主要是让我们对所配置的内容有所了解,类似于注释的作用。
3、description:作用跟short相同,不过描述信息更加详细。
4、port:服务所对应的端口,这项是service中非常重要的一个配置项,大部分service主要就是对port进行绑定的,当一个service绑定了指定端口之后,该端口接收到的连接就会当成这个service,然后到所对应的zone中去查询规则,从而判断是否可以放行。port节点有两可个配置的属性:port和protocol
5、port属性:port用来配置所使用的端口号,可以是单个端口也可以是一个端口段,比如port=100-105表示100到105之间的端口号,另外,port属性是个可选属性,可以不进行设置。
6、protocol属性:protocol属性用于指定所对应的协议,如果port属性不为空,那么protocol应该设置为tcp或者udp,如果port属性为空(没设置),那么protocol可以设置为/etc/protocols中所包含的任意协议。
7、destination:destination非常简单,它就表示目标地址,也就是根据目标地址来绑定服务,他有两个属性:ipv4和ipv6,分别用于绑定ipv4和ipv6的地址,可以使用单个地址也可以使用掩码。另外,在一个service中destination最多只能出现一次。

这里就以Nginx服务为例,如下所示我这边使用yum部署了nginx服务,因为firewalld的防火墙规则默认是拒绝的,启动firewalld防火墙无法访问nginx服务,现在对nginx服务进行配置防火墙规则,允许客户端用户可以访问nginx服务。

1、编辑配置nginx服务xml文件

[root@ecs-fa04-0002 ~]# cp /usr/lib/firewalld/services/mysql.xml /etc/firewalld/services/nginx.xml
[root@ecs-fa04-0002 ~]# vim /etc/firewalld/nginx.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Nginx</short>
  <description>Nginx Server</description>
  <port protocol="tcp" port="80"/>
  <port protocol="tcp" port="81"/>
</service>

2、配置前查看public区域内允许访问的服务

[root@ecs-fa04-0002 ~]# firewall-cmd --zone=public --list-services
ssh mdns dhcpv6-client cockpit

3、为public区域设置允许访问的Nginx服务

[root@ecs-fa04-0002 ~]# firewall-cmd --zone=public --add-service=nginx --permanent
success

4、重新加载配置

[root@ecs-fa04-0002 ~]# firewall-cmd --reload
success

5、配置后查看public区域内允许访问的服务

[root@ecs-fa04-0002 ~]# firewall-cmd --zone=public --list-services
ssh mdns dhcpv6-client cockpit nginx

6、移除Nginx服务防火墙规则

[root@ecs-fa04-0002 ~]# firewall-cmd --zone=public --remove-service=nginx --permanent
[root@ecs-fa04-0002 ~]# firewall-cmd --reload
# 经测试,移除服务,需重启firewalld才生效
[root@ecs-fa04-0002 ~]# systemctl restart firewalld
[root@ecs-fa04-0002 ~]# firewall-cmd --zone=public --list-services
ssh mdns dhcpv6-client cockpit

4.3、端口管理

在进行服务配置时,预定义的网络服务可以使用服务名配置,服务所涉及的端口就会自动打开。但是,对于非预定义的服务只能手动为指定的区域添加端口。

使用firewalld允许客户请求的服务器的80/tcp端口,仅临时生效,如添加–permanent重启后则永久生效。

1、临时添加允许放行单个端口

[root@snat zones]# firewall-cmd --add-port=80/tcp
success
[root@snat zones]# firewall-cmd --list-ports
80/tcp

2、临时添加放行多个端口

[root@snat zones]# firewall-cmd --add-port={80/tcp,8080/tcp}
success
[root@snat zones]# firewall-cmd --list-ports
80/tcp 8080/tcp

3、永久添加多个端口,需要添加–permanent,并且需要重载firewalld

[root@snat zones]# firewall-cmd --add-port={80/tcp,8080/tcp} --permanent
success
[root@snat zones]# firewall-cmd --reload
success
[root@snat zones]# firewall-cmd --list-ports
80/tcp 8080/tcp

4、移除临时添加的端口规则

[root@snat zones]# firewall-cmd --remove-port={80/tcp,8080/tcp}
success
[root@snat zones]# firewall-cmd --list-ports

5、移除永久添加的端口规则

[root@snat zones]# firewall-cmd --remove-port={80/tcp,8080/tcp} --permanent
success
[root@snat zones]# firewall-cmd --reload
success
[root@snat zones]# firewall-cmd --list-ports

4.4、富规则管理

firewalld中的富规则可以配置更细致、更详细的防火墙策略,它可以针对系统服务、端口号、源地址和目标地址等诸多信息进行更有针对性的策略配置, 优先级在所有的防火墙策略中也是最高的。

富规则相关命令

man firewall-cmd                #帮助手册
man firewalld.richlanguage      #获取富规则手册
    rule
        [source]
        [destination]
        service|port|protocol|icmp-block|masquerade|forward-port
        [log]
        [audit]
        [accept|reject|drop]

rule [family="ipv4|ipv6"]
source address="address[/mask]" [invert="True"]
service name="service name"
port port="port value" protocol="tcp|udp"
forward-port port="port value" protocol="tcp|udp" to-port="port value" to-addr="address"
accept | reject [type="reject type"] | drop

富规则相关命令
--add-rich-rule='<RULE>'        #在指定的区添加一条富规则
--remove-rich-rule='<RULE>'     #在指定的区删除一条富规则
--query-rich-rule='<RULE>'      #找到规则返回0 ,找不到返回1
--list-rich-rules               #列出指定区里的所有富规则

这里就以consul服务为例,因为firewalld的防火墙规则默认是拒绝的,启动firewalld防火墙使用客户端用户无法连接,现在对consul服务进行配置防火墙规则,允许客户端用户可以连接consul服务。

操作步骤如下:
1、添加防火墙规则前在192.168.1.48主机上访问consul服务端口

2、在192.168.1.34主机上添加防火墙规则(对指定ip开放指定端口)

firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8300" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8301" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8302" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8500" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8600" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8301" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8302" accept" 
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8600" accept" 
firewall-cmd --reload

进入/etc/firewalld/zones/public.xml文件查看配置的规则,如下图所示:

总结:也可以手动编辑public.xml文件进行规则添加。

3、查看配置结果,如下图所示:

4、添加防火墙规则后在192.168.1.48主机上访问consul服务端口

5、删除防火墙规则

firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8300" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8301" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8302" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8500" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="tcp" port="8600" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8301" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8302" accept" 
firewall-cmd --permanent --remove-rich-rule="rule family="ipv4" source address="192.168.1.48" port protocol="udp" port="8600" accept" 
firewall-cmd --reload

总结:也可以在public.xml文件中将之前添加的规则进行手动删除。


六、firewalld实现路由器功能

6.1、firewalld实现SNAT

实例:实现内部主机访问外部服务

步骤如下:

1、开启路由转发

#临时开启
[root@snat zones]# echo 1 > /proc/sys/net/ipv4/ip_forward

#永久开启
[root@snat zones]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@snat zones]# sysctl -p

2、firewalld防火墙开启masquerade, 实现地址转换

设置默认区域的SNAT的IP伪装
[root@snat zones]# firewall-cmd --add-masquerade --permanent
[root@snat zones]# firewall-cmd --reload
#################################下面部分不用执行#################################
查看默认区域的SNAT是否允许
[root@snat zones]# firewall-cmd --query-masquerade --permanent

删除默认区域的SNAT功能
[root@snat zones]# firewall-cmd --remove-masquerade --permanent

3、客户端将网关指向firewalld服务器,将所有网络请求交给firewalld

[root@web ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens33
GATEWAY=192.168.149.100

4、客户端主机192.168.149.101上测试访问http://192.168.1.48:80

[root@host-48 ~]# tail -1000f /var/log/nginx/access.log
192.168.1.34 - - [19/Nov/2021:15:14:41 +0800] "GET / HTTP/1.1" 200 6 "-" "curl/7.29.0" "-"
192.168.1.34 - - [19/Nov/2021:15:14:42 +0800] "GET / HTTP/1.1" 200 6 "-" "curl/7.29.0" "-"
192.168.1.34 - - [19/Nov/2021:15:14:42 +0800] "GET / HTTP/1.1" 200 6 "-" "curl/7.29.0" "-"

通过日志会发现,客户端是先伪装成了192.168.1.34这个ip后再访问的web服务器!


6.2、firewalld实现DNAT

端口转发:将发往本机的特定端口的流量转发到本机或不同机器的另一个端口,通常要配合地址伪装才能实现.

实例:实现外部主机访问内部服务

步骤如下:

1、开启路由转发

#临时开启
[root@snat zones]# echo 1 > /proc/sys/net/ipv4/ip_forward

#永久开启
[root@snat zones]# echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf
[root@snat zones]# sysctl -p

2、添加提供访问的端口

[root@snat zones]# firewall-cmd --add-port=8091/tcp --permanent
success

3、添加转发的端口和ip地址

格式:firewall-cmd --permanet --zone=<区域> --add-forward-port=port=源端口号:proto=<协议>:toport=<目标端口>:toaddr=<目标IP地址>

[root@snat zones]# firewall-cmd --permanent --add-forward-port=port=8091:proto=tcp:toport=80:toaddr=192.168.1.48
success

4、开启FirewallD的ip地址伪装

[root@snat zones]# firewall-cmd --add-masquerade --permanent

5、配置生效

[root@snat zones]# firewall-cmd --reload
success
[root@snat zones]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens33 ens38
  sources: 
  services: ssh dhcpv6-client
  ports: 8091/tcp
  protocols: 
  masquerade: yes
  forward-ports: port=8091:proto=tcp:toport=80:toaddr=192.168.1.48
  source-ports: 
  icmp-blocks: 
  rich rules: 

6、中转服务器上的8091端口实际是没有打开的

[root@snat zones]# ss -tnulp | grep 8091

7、客户端主机测试访问http://192.168.1.34:8091,实际访问的是192.168.1.48主机上的nginx 80端口服务,但是nginx日志记录的源ip地址为中转服务器的ip地址,这样就实现了地址伪装


总结:整理不易,如果对你有帮助,可否点赞关注一下?

更多详细内容请参考:Linux运维实战总结

本文标签: 防火墙教程Linuxfirewalld