学习 firewalld 来设置防火墙

/ 0评 / 0

为什么要学习 Firewalld 防火墙?

CentOS 7 安装完成并运行了一些服务后,照例使用 iptables 来设置防火墙,服务器只运行了 LNMP 和 ssh 这几个服务,随后更改了 ssh 的端口号,发现过一会儿就掉线了。无奈只得登录 solus 的后台用 VNC 查看原因,查看 fail2ban 的日志,没有发现自己被 ban 啊,即使把 fail2ban 卸载了还是不行,最后只得又把 ssh 的端口号改回 port 22 ,重启后又能连上了。至此我隐约觉得跟 iptables 有关,可是查看 iptables 的规则,我分明是把新端口号添加进去了的啊。
让人百思不得其解。
无意中用

systemctl restart iptables

命令重启的时候报了个错给我

Job for iptables.service failed because the control process exited with error code. See "systemctl status iptables.service" and "journalctl -xe" for details.

我才知道从 CentOS 7 开始,虽然 iptables 没有被删除,但基本上这玩意已经不再承担原来的角色了。新的防火墙命令由 firewalld 担任。
好不容易把 iptables 的用法稍稍熟悉了一点,结果才发现是个无用的技能,必须要学新命令了。

Linux 防火墙是通过 netfilter 来处理的,它是内核级别的框架。这十几年来,iptables 被作为 netfilter 的用户态抽象层(LCTT 译注: userland,一个基本的 UNIX 系统是由 kernel 和 userland 两部分构成,除 kernel 以外的称为 userland)。iptables 将包通过一系列的规则进行检查,如果包与特定的 IP/端口/协议的组合匹配,规则就会被应用到这个包上,以决定包是被通过、拒绝或丢弃。
Firewalld 是最新的 netfilter 用户态抽象层。遗憾的是,由于缺乏描述多区域配置的文档,它强大而灵活的功能被低估了。
firewalld 的设计者认识到大多数的 iptables 使用案例仅涉及到几个单播源 IP,仅让每个符合白名单的服务通过,而其它的会被拒绝。这种模式的好处是,firewalld 可以通过定义的源 IP 和/或网络接口将入站流量分类到不同区域zone。每个区域基于指定的准则按自己配置去通过或拒绝包。
另外的改进是基于 iptables 进行语法简化。firewalld 通过使用服务名而不是它的端口和协议去指定服务,使它更易于使用,例如,是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它进一步简化语法,消除了 iptables 中对语句顺序的依赖。

这段话里提到了 iptables 的语法过于复杂,没错是这样的,正是因为 iptables 过于复杂,所以我多年来一直都用过就忘,哈哈哈。

查看防火墙状态

先查看一下当前的防火墙配置情况,反馈如下:

#firewall-cmd --list-all
public (default, active)
interfaces: eno1 eno2
sources:
services: dhcpv6-client ssh http
ports:
masquerade: no
forward-ports:
icmp-blocks:
rich rules:

现在开始根据需要进行设置。

删除一条规则

先删掉我系统默认开启而我又用不着的 dhcpv6-client 规则。

firewall-cmd --permanent --zone=public --remove-service=dhcpv6-client

--permanent表示这是一条永久规则
--zone=public表示命令生效的区域
--remove-service=dhcpv6-client表示在防火墙中白名单里移除这一规则

新开放一个端口

前面说了,我把 ssh 的端口号改了,改了之后登不上去的原因就在这里,虽然修改了/etc/sysconfig/iptables并在里面增加了 ssh 的新端口号,但是由于 CentOS 7 承担防火墙功能的前端已经变成了 firewalld 了,我并没有在 firewalld 里面开放相应的端口,所以才导致了我用新端口无法 ssh 到服务器,但继续使用 port 22 还是可以连接的。
知道了原因,那么就开放一个新的端口就好了。

firewall-cmd --permanent --zone=public --add-port=12345/tcp
firewall-cmd --reload #新的规则添加后要用该命令重新加载

再次查看防火墙规则,结果如下:

public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: ssh http
ports: 12345/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:

可以看到跟上一个结果所不同的地方在于 services 里的 dhcpv6-client 已经消失,同时 ports 里多了一条 12345/tcp 规则。

使更改生效

一切就绪,用命令使其生效。
systemctl restart firewalld
现在随便找一个提供端口扫描服务的网站来扫你的网站,把netstat -atunp里开放的端口都填进去扫描便知结果。
由于我更改了 ssh 的默认端口,并且在防火墙里也把新端口开放了,那么防火墙里为 ssh 服务默认开放的端口我也不再需要了,可以删除。

firewall-cmd --permanent --zone=public --remove-service=ssh
firewall-cmd --reload
systemctl restart firewalld

参考文献:
Linux 中国:理解多区域配置中的 firewalld

Leave a Reply

Your email address will not be published. Required fields are marked *