预备知识
firewalld 是新一 Linux 代防火墙工具,它提供了支持网络 / 防火墙区域 (zone) 定义网络链接以及接口安全等级的动态防火墙管理工具。它也支持允许服务或者应用程序直接添加防火墙规则的接口。在 Linux 历史上已经使用过的防火墙工具包括:ipfwadm、ipchains、iptables
在RHEL7/CentOS7.x 版本上,firewalld已经替代iptables成为默认的防火墙软件,firewalld是centos7的一大特性,最大的好处有两个:
第一个:
在后台, firewalld 和 iptables 服务都通过相同的接口来与内核中的 netfilter 框架相交流,这不足为奇,即它们都通过 iptables 命令来与 netfilter 交互。然而,与 iptables 服务相反, firewalld支持动态更新,不用重启服务,随时添加规则,随时生效,这个过程不需要重新装载netfilter内核模块,但是要求所有的规则都通过firewalld守护进程来实现,以确保守护进程内的防火墙状态和内核中的防火墙状态一致;守护进程firewalld,应用程序、守护进程和用户可以通过D-BUS请求一个防火墙特性,特性可以是预定义的防火墙功能,例如:服务、端口和协议的组合、端口/数据报转发、伪装、ICMP拦截或自定义的规则。原有的静态防火墙规则还可以继续使用,但是不能和firewalld同时存在,需要使用这两者中的任何一个时,停止另外一个的使用。
第二个:
加入了区域(zone)的概念
区域定义了网络连接的可信等级,这是一个一对多的关系,意味着一次连接可以仅仅是一个区域的一部分,一个区域可以用于很多连接。
比较 system-config-firewall 以及 iptables 的 firewalld:
firewalld 和 iptables service 之间最本质的不同是:
iptables service 在 /etc/sysconfig/iptables 中储存配置,而 firewalld 将配置储存在 /usr/lib/firewalld/ 和 /etc/firewalld/ 中的各种 XML 文件里。要注意,当 firewalld 在Red Hat Enterprise Linux上安装失败时, /etc/sysconfig/iptables 文件就不存在。
使用 iptables service,每一个单独更改意味着清除所有旧有的规则和从 /etc/sysconfig/iptables里读取所有新的规则,然而使用 firewalld 却不会再创建任何新的规则;仅仅运行规则中的不同之处。因此,firewalld 可以在运行时间内,改变设置而不丢失现行连接。
对网络区的理解:
由firewalld 提供的区域按照从不信任到信任的顺序排序:
drop(丢弃)
任何接收的网络数据包都被丢弃,没有任何回复。仅能有发送出去的网络连接。
block(限制)
任何接收的网络连接都被 IPv4 的 icmp-host-prohibited 信息和 IPv6 的 icmp6-adm-prohibited 信息所拒绝。
public(公共)
在公共区域内使用,不能相信网络内的其他计算机不会对您的计算机造成危害,只能接收经过选取的连接。
external(外部)
特别是为路由器启用了伪装功能的外部网。您不能信任来自网络的其他计算,不能相信它们不会对您的计算机造成危害,只能接收经过选择的连接。
dmz(非军事区)
用于您的非军事区内的电脑,此区域内可公开访问,可以有限地进入您的内部网络,仅仅接收经过选择的连接。
work(工作)
用于工作区。您可以基本相信网络内的其他电脑不会危害您的电脑。仅仅接收经过选择的连接。
home(家庭)
用于家庭网络。您可以基本信任网络内的其他计算机不会危害您的计算机。仅仅接收经过选择的连接。
internal(内部)
用于内部网络。您可以基本上信任网络内的其他计算机不会威胁您的计算机。仅仅接受经过选择的连接。
trusted(信任)
可接受所有的网络连接。
安装时,firewalld 里的默认区域被设定为公共区域。
firewalld home page:http://www.firewalld.org
参考文档:
RHEL7 安全性指南4.5. 使用防火墙 https://access.redhat.com/documentation/zh-CN/Red_Hat_Enterprise_Linux/7/html/Security_Guide/sec-Using_Firewalls.html
实验目的
1)firewalld 的基本操作
2)用firewall-cmd 配置防火墙
3) 高级配置
实验环境
操作系统:Centos7
IP随机
所用软件:firewalld
PS:更多相关课程,《Linux防火墙》http://hetianlab.com/expc.do?w=exp_ass&ec=8b3a16a6-3eb7-4035-a94b-26baa0d05d51
实验步骤一
firewalld 的基本操作
1、启动firewalld
systemctl start firewalld
查看版本:firewall-cmd --version
2、检查防火墙是否运行
如果 firewalld 在运行,输入以下命令检查:
另外,检查 firewall-cmd 是否可以连接后台程序:
3、列出支持的区域列表
PS:firewalld 的缺省区域是 public。
4、区域相关设置
查看当前的区域
firewall-cmd --get-active-zones
更改区域为家庭区域:
使用firewall-cmd --set-default-zone设置区域(立即生效)
找出当前分配了接口(例如 eth0)的区域
使用 firewall-cmd --get-zone-of-interface
找出分配给一个区域(例如home区域)的所有接口
列出一个区域的所有设置,比如public:
5、应急模式:(只做说明,请勿实际操作)
阻止所有网络链接:
firewall-cmd --panic-on
恢复链接:
firewall-cmd --panic-off
查看是否启用应急模式:
如果启用,会显示 yes,如果未启用,屏幕会显示 no。
实验步骤二
1、重新加载防火墙:
重新加载防火墙,并不中断用户连接,即不丢失状态信息
重新加载防火墙并中断用户连接,即丢弃状态信息:
禁止在实验室环境使用。通常在防火墙出现严重问题时,这个命令才会被使用。比如,防火墙规则是正确的,但却出现状态信息问题和无法建立连接。
2、打开防火墙里的端口
列出某个区域所有开放的端口:
firewall-cmd --zone=zone --list-ports
要将一个端口加入一个区域,例如,允许 TCP流量通过端口 80 进入dmz分区,输入以下命令:
firewall-cmd --zone=dmz --add-port=80/tcp
如果是端口范围可以使用以下命令:
firewall-cmd --zone=zone --add-port=port-port/[udp|tcp]
比如允许public区域 3000 到 3020 的udp端口
3、服务管理设置
列出支持的服务(不一定启用):
firewall-cmd --get-service
列出某个区域中启用的服务
firewall-cmd --zone=zone --list-services
要把一个服务加入到区域,例如允许 SMTP 接入public区域,可以使用如下命令
firewall-cmd --zone=public --add-service=smtp
从区域移除服务
firewall-cmd --zone=zone --remove-service=servicename
4、IP伪装功能
启用区域中的IP伪装功能,私有网络地址被隐藏并映射到一个公有IP,常用于路由。
使用如下命令检查区域是否启用ip伪装功能
firewall-cmd --zone=zone --query-masquerade
如果可用,屏幕会显示 yes,不可用显示no
允许伪装IP,可以使用如下命令:
firewall-cmd --zone=zone --add-masquerade
禁用伪装IP则使用:firewall-cmd --zone=zone --remove-masquerade
5、ICMP阻塞功能
阻止一个或多个 ICMP 类型。要获得被支持的 ICMP 类型列表,输入以下命令:
firewall-cmd --get-icmptypes
启用区域的ICMP阻塞功能
firewall-cmd --zone=zone --add-icmp-block=<icmptype>
禁用区域的ICMP阻塞功能
firewall-cmd --zone=zone --remove-icmp-block=<icmptype>
查询区域的ICMP阻塞状态
firewall-cmd --zone=zone --query-icmp-block=<icmptype>
例如,阻塞public区域的响应应答报文:
firewall-cmd --zone=public --add-icmp-block=echo-reply
6、配置端口转发
可以配置端口映射到另外一个端口,端口映射到另外一个地址上的相同端口,端口映射到另外一台主机上的不同端口,命令格式如下:
firewall-cmd --zone=zone --add-forward-port=port=<port>-[<port>]:proto=<protocol> {:toport=<port>-[<port>] | :toaddr=<address> | :toport=<port>-[<port>]:toaddr=<address>}
在配置端口转发之前需要将IP伪装打开
实例:
firewall-cmd --zone=external --add-masquerade
将本机的80端口转发到8080端口
firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toport=8080
本来要送到 80 端口的程序包现在被转发到 8080 端口。源目的端口用 port 选项指定。这个选项可以是一个端口,或者一组端口范围并加上协议。如果指定协议的话,这个协议必须是 tcp 或 udp。这个新的本地端口,即流量被转发过去的端口或者端口范围,需用 toport 选项指定
映射到另外一个地址上的相同端口(以下地址为演示所用,实验室环境不存在):
firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toaddr=192.168.99.100
端口映射到另外一台主机上的不同端口(以下地址为演示所用,实验室环境不存在):
firewall-cmd --zone=external /
--add-forward-port=port=80:proto=tcp:toport=8080:toaddr=192.168.99.100
禁用端口转发或者映射:
命令格式如下:
firewall-cmd --zone=zone --remove-forward-port=port=<port>-[<port>]:proto=<protocol> {:toport=<port>-[<port>] | :toaddr=<address> | :toport=<port>-[<port>]:toaddr=<address>}
移除本机80到8080端口的转发:
firewall-cmd --zone=external --remove-forward-port=port=80:proto=tcp:toport=8080
移除本机80端口到主机192.168.99.100的80端口的映射
firewall-cmd --zone=external --remove-forward-port=port=80:proto=tcp:toaddr=192.168.99.100
查询区域内的端口转发可以使用如下命令:
firewall-cmd --zone=zone --query-forward-port
7、设置永久保留
上面所有的配置都是临时性的配置,当重启/载服务或重启系统后,配置将不再保留。就像这样:
如果需要将设置永久保留,则需要使用--permanent 选项,当然永久选项不直接影响运行时的状态,只有在增加 --permanent 选项并重新加载防火墙,永久选项才会生效
用法:将--permanent设置为第一个参数,即可将临时性的设置为永久性生效的配置
比如这条配置:firewall-cmd --zone=external --add-forward-port=port=80:proto=tcp:toaddr=192.168.99.100
只需要加一个 “--permanent”参数即可设置为永久
firewall-cmd --permanent --zone=external --add-forward-port=port=80:proto=tcp:toaddr=192.168.99.100
其他,比如服务配置,icmp阻塞等配置,都可以将--permanent设置为第一个参数,即可使这个设置永久保留
实验步骤三
firewalld高级配置
1、用 XML 文件配置防火墙
firewalld 的配置设定存储在/etc/firewalld/ 目录下的 XML 文件里。切勿编辑 /usr/lib/firewalld/ 目录下的文件,因为它们是为默认设定准备的.
三个操作手册对 XML 文件进行了解说:
firewalld.icmptype(5) 操作手册 — 描述了 ICMP 过滤的 XML 配置文件。
https://twoerner.fedorapeople.org/firewalld/doc/firewalld.icmptype.html
firewalld.service(5) 操作手册 — 描述了 firewalld service 的 XML 配置文件。
https://twoerner.fedorapeople.org/firewalld/doc/firewalld.service.html
firewalld.zone(5) 操作手册 — 描述了配置 firewalld 区域的 XML 配置文件。
https://twoerner.fedorapeople.org/firewalld/doc/firewalld.zones.html
我们来看一下XML文件的结构,以ssh服务为例:
可以看出每一个服务定义都需要一个简短的名字、描述和端口网络用于指定需要使用的协议、端口和模块名
以这个结构,我们来自定义一个服务配置
进入 /etc/firewalld/services目录
假设我们有一个ELK的服务,那么配置文件如下:
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>ELK</short>
<description>Elasticsearch + Logstash + Kibana</description>
<port port="9200" protocol="tcp"/>
</service>
接着我们使用firewall-cmd --reload生效,然后使用 firewall-cmd --get-services 查看服务列表,就能看到我们自定义的服务了
接着我们就可以添加服务到区域了。
2、firewalld直接接口(firewall-cmd --direct 命令)
可以使用 --direct 选项在运行时间里增加或者移除链,命令立刻生效,但重载后失效。传递的参数 <args> 与 iptables, ip6tables 以及 ebtables 一致。如果不熟悉 iptables ,使用直接接口非常危险,可能无意间导致防火墙被入侵。
增加一个自定义规则到 “INPUT” 链里:
firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -m tcp -p tcp --dport 666 -j ACCEPT
列出INPUT链中的规则:
firewall-cmd --direct --get-rules ipv4 filter INPUT
移除规则使用:firewall-cmd --direct --remove-rule命令,比如移除刚刚我们自定义的规则:
firewall-cmd --direct --remove-rule ipv4 filter INPUT 0 -m tcp -p tcp --dport 666 -j ACCEPT
请查阅 firewall-cmd(1) 操作说明获取更多信息
https://twoerner.fedorapeople.org/firewalld/doc/firewall-cmd.html
3、使用“Rich Language” 配置复杂防火墙规则
通过 “rich language” 语法,可以用比直接接口方式更易理解的方法建立复杂防火墙规则。此外,还能使用 –permanent参数永久保留设置。这种语言使用关键词值,是 iptables 工具的抽象表示。还可以用来配置分区,也仍然支持现行的配置方式,具有极强的灵活性。
Firewalld Rich Language 文档:
https://fedoraproject.org/wiki/Features/FirewalldRichLanguage/zh-cn
语法如下:
增加一项规则:firewall-cmd [--zone=zone] --add-rich-rule='rule'
移除一项规则:firewall-cmd [--zone=zone] --remove-rich-rule='rule'
检查一项规则是否存在:firewall-cmd [--zone=zone] --query-rich-rule='rule'
只允许从 192.168.99.100 到 web 服务器(80 号端口)的连接而阻塞 192.168.99.0/24 网络中的其它来源,该如何设置呢?
可以这样:
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="192.168.99.100/24" service name="http" accept'
firewall-cmd --add-rich-rule 'rule family="ipv4" source address="192.168.99.0/24" service name="http" drop'
如果要永久生效可以添加 --permanent参数
Rich Language”多规则结构:
rule [family="<rule family>"]
[ source address="<address>" [invert="True"] ]
[ destination address="<address>" [invert="True"] ]
[ <element> ]
[ log [prefix="<prefix text>"] [level="<log level>"] [limit value="rate/duration"] ]
[ audit ]
[ accept|reject|drop ]
source
源地址
destination
目标地址
service
服务名称是 firewalld 提供的其中一种服务。命令为以下形式:
service name=service_name
port
可以是一个具体的端口,也可以是端口范围,例如,5060-5062。协议可以指定为 tcp 或 udp。命令为以下形式:
port port=number_or_range protocol=protocol
protocol
协议值可以是一个协议 ID 数字,或者一个协议名。预知可用协议,请查阅 /etc/protocols。命令为以下形式:
protocol value=protocol_name_or_ID
icmp-block
用这个命令阻绝一个或多个 ICMP 类型。 ICMP 类型是 firewalld 支持的 ICMP 类型之一。要获得被支持的 ICMP 类型列表,输入以下命令:
firewall-cmd --get-icmptypes
命令为以下形式:
icmp-block name=icmptype_name
masquerade
打开规则里的 IP 伪装。
forward-port
从一个带有指定为 tcp 或 udp 协议的本地端口转发数据包到另一个本地端口,或另一台机器,或另一台机器上的另一个端口。 port 和 to-port 可以是一个单独的端口数字,或一个端口范围。而目的地址是一个简单的 IP 地址。这个命令为以下形式:
forward-port port=number_or_range protocol=protocol /
to-port=number_or_range to-addr=address
log
写入日志,等级可以是 emerg 、 alert 、 crit 、 error 、warning 、 notice、 info 或者 debug 中的一个。语法如下:
log [prefix=prefix text] [level=log level] limit value=rate/duration
日志等级用正的自然数 [1, ..] 表达,持续时间的单位为 s 、 m 、 h 、 d 。 s 表示秒, m 表示分钟, h 表示小时, d 表示天。最大限定值是 1/d ,意为每天最多有一条日志。
audit
审核为发送到 auditd 服务。审核类型可以是 ACCEPT 、 REJECT 或 DROP 中的一种,但不能在 audit 命令后指定,因为审核类型将会从规则动作中自动收集。审核不包含自身参数,但可以选择性地增加限制。审核的使用是可选择的。
accept|reject|drop
规则动作
accept | reject [type=reject type] | drop
选择 accept 所有新的连接请求都会被允许。选择 reject ,连接将被拒绝,连接来源将接到一个拒绝信息。选择 drop , 所有数据包会被丢弃,并且不会向来源地发送任何信息。
多规则登录命令使用示例1:
允许IPv4 和 IPv6 连接 FTP,并使用审核每分钟登录一次
rule service name="ftp" log limit value="1/m" audit accept
多规则登录命令使用示例2:
同意来自 192.168.0.0/24 网络的IP地址使用ipv4访问本机的http,并且每一分钟写入一次系统日志
rule family="ipv4" source address="192.168.0.0/24" service name="http" log prefix="http" level="info" limit value="1/m" accept