firewalld防火墙使用
前言
现在的新闻里充斥着服务器被攻击和数据失窃事件。对于一个阅读过安全公告博客的人来说,通过访问错误配置的服务器,利用最新暴露的安全漏洞或通过窃取的密码来获得系统控制权,并不是件多困难的事情。在一个典型的 Linux 服务器上的任何互联网服务都可能存在漏洞,允许未经授权的系统访问。
因为在应用程序层面上强化系统以防范任何可能的威胁是不可能做到的事情,而防火墙可以通过限制对系统的访问提供了安全保证。防火墙基于源 IP、目标端口和协议来过滤入站包。因为这种方式中,仅有几个 IP/端口/协议的组合与系统交互,而其它的方式做不到过滤。
Linux 防火墙是通过 netfilter 来处理的,它是内核级别的框架。这十几年来,iptables 被作为 netfilter 的用户态抽象层(LCTT 译注: userland,一个基本的 UNIX 系统是由 kernel 和 userland 两部分构成,除 kernel 以外的称为 userland)。iptables 将包通过一系列的规则进行检查,如果包与特定的 IP/端口/协议的组合匹配,规则就会被应用到这个包上,以决定包是被通过、拒绝或丢弃。
Firewalld 是最新的 netfilter 用户态抽象层。遗憾的是,由于缺乏描述多区域配置的文档,它强大而灵活的功能被低估了。这篇文章提供了一个示例去改变这种情况。
firewalld 的设计目标
firewalld 的设计者认识到大多数的 iptables 使用案例仅涉及到几个单播源 IP,仅让每个符合白名单的服务通过,而其它的会被拒绝。
firewalld 可以通过定义的源 IP 和/或网络接口将入站流量分类到不同区域zone。每个区域基于指定的准则按自己配置去通过或拒绝包。
另外的改进是基于 iptables 进行语法简化。firewalld 通过使用服务名而不是它的端口和协议去指定服务,使它更易于使用,例如,是使用 samba 而不是使用 UDP 端口 137 和 138 和 TCP 端口 139 和 445。它进一步简化语法,消除了 iptables 中对语句顺序的依赖。
最后,firewalld 允许交互式修改 netfilter,允许防火墙独立于存储在 XML 中的永久配置而进行改变。因此,下面的的临时修改将在下次重新加载时被覆盖:
1 | firewall-cmd <some modification> |
而,以下的改变在重加载后会永久保存:
1 | firewall-cmd --permanent <some modification> |
firwalld 服务基本使用
指令 | 用户 |
---|---|
yum install firewalld | 安装或者更新 |
firewall-cmd –version | 查看版本 |
systemctl status firewalld | 查看状态 |
systemctl stop firewalld | 关闭防火墙,停止 firewall 服务 |
systemctl start firewalld | 开启防火墙,启动 firewall 服务 |
systemctl restart firewalld | 重启防火墙,重启 firewall 服务 |
systemctl is-enabled firewalld | 查看 firewall 服务是否开机启动 |
systemctl enable firewalld | 开机时自动启动 firewall 服务 |
systemctl disable firewalld | 开机时自动禁用 firewall 服务 |
firewalld-cmd 防护墙命令使用
上面所说的 firewall 可以看成整个防火墙服务,而 firewall-cmd 可以看成是其中的一个功能,可用来管理端口
查看 firewall-cmd 状态,即查看 firewall 防火墙程序是否正在运行: firewall-cmd –state
1
2
3[root@localhost ~]# firewall-cmd --state
running
[root@localhost ~]#查看已打开的所有端口,firewall-cmd –zone=public –list-ports
1
2
3[root@localhost ~]# firewall-cmd --zone=public --list-ports
80/tcp 8081/tcp
[root@localhost ~]#开启指定端口
开启一个端口:firewall-cmd –zone=public –add-port=80/tcp –permanent (–permanent 永久生效,没有此参数重启后失效)
重新加载 firewall,修改配置后,必须重新加载才能生效:firewall-cmd –reload
1
2
3
4
5
6
7[root@localhost ~]# firewall-cmd --zone=public --list-ports
80/tcp 8081/tcp
[root@localhost ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]#
关闭指定端口
关闭 9876 端口:firewall-cmd –zone=public –remove-port=9898/tcp –permanent(–permanent 表示永久生效,没有此参数重启后失效)
重新加载 firewall,修改配置后,必须重新加载才能生效:firewall-cmd –reload
1
2
3
4
5
6
7
8
9[root@localhost ~]# firewall-cmd --zone=public --list-ports
9876/tcp 8090/tcp 80/tcp 8080/tcp
[root@localhost ~]# firewall-cmd --zone=public --remove-port=9876/tcp --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]# firewall-cmd --zone=public --list-ports
8090/tcp 80/tcp 8080/tcp
[root@localhost ~]#
public.xml文件修改防火墙端口
firewall-cmd对端口的操作,如开放端口等信息,都放在在”/etc/firewall/zones/public.xml”中记录
所以直接修改此文件也是可以的
1
2
3
4[root@laosanxin ~]# ls -lrt /etc/firewalld/zones
总用量 8
-rw-r--r--. 1 root root 315 10月 15 2017 public.xml.old
-rw-r--r--. 1 root root 315 10月 15 2017 public.xml1
2
3
4
5
6
7
<zone>
<short>Public</short>
<description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
<service name="ssh"/>
<service name="dhcpv6-client"/>
</zone>
区域
在 firewalld 中最上层的组织是区域。如果一个包匹配区域相关联的网络接口或源 IP/掩码 ,它就是区域的一部分。可用的几个预定义区域:
1 | [root@localhost ~]# firewall-cmd --get-zones |
任何配置了一个网络接口和/或一个源的区域就是一个活动区域active zone。列出活动的区域:
1 | [root@localhost ~]# firewall-cmd --get-active-zones |
Interfaces (接口)是系统中的硬件和虚拟的网络适配器的名字,正如你在上面的示例中所看到的那样。所有的活动的接口都将被分配到区域,要么是默认的区域,要么是用户指定的一个区域。但是,一个接口不能被分配给多于一个的区域。
在缺省配置中,firewalld 设置所有接口为 public 区域,并且不对任何区域设置源。其结果是,public 区域是唯一的活动区域。
Sources (源)是入站 IP 地址的范围,它也可以被分配到区域。一个源(或重叠的源)不能被分配到多个区域。这样做的结果是产生一个未定义的行为,因为不清楚应该将哪些规则应用于该源。
因为指定一个源不是必需的,任何包都可以通过接口匹配而归属于一个区域,而不需要通过源匹配来归属一个区域。这表示通过使用优先级方式,优先到达多个指定的源区域,稍后将详细说明这种情况。首先,我们来检查 public 区域的配置:
1 | [root@localhost ~]# firewall-cmd --zone=public --list-all |
逐行说明如下:
public (active) 表示 public 区域是默认区域(当接口启动时会自动默认),并且它是活动的,因为,它至少有一个接口或源分配给它。
default 是目标区域,它决定了与该区域匹配而没有由上面设置中显式处理的包的动作。
interfaces: eno1 eno2 列出了这个区域上关联的接口。
sources: 列出了这个区域的源。现在这里什么都没有,但是,如果这里有内容,它们应该是这样的格式 xxx.xxx.xxx.xxx/xx。
services: dhcpv6-client ssh 列出了允许通过这个防火墙的服务。你可以通过运行 firewall-cmd –get-services 得到一个防火墙预定义服务的详细列表。
1
2[root@localhost ~]# firewall-cmd --get-services
RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git gre high-availability http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-serverports:列出了一个允许通过这个防火墙的目标端口。它是用于你需要去允许一个没有在 firewalld 中定义的服务的情况下
masquerade: no 表示这个区域是否允许 IP 伪装。如果允许,它将允许 IP 转发,它可以让你的计算机作为一个路由器。
forward-ports: 列出转发的端口。
rich rules: 在一个区域中优先处理的高级配置。
配置示例
允许https服务流量通过public区域,要求立即生效且永久有效:
1
2
3
4
5
6
7[root@localhost ~]# firewall-cmd --zone=public --add-service=https
success
[root@localhost ~]# firewall-cmd --zone=public --add-service=https --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]#不再允许http服务流量通过public区域,要求立即生效且永久生效:
1
2
3
4[root@localhost ~]# firewall-cmd --zone=public --remove-service=https --permanent
success
[root@localhost ~]# firewall-cmd --reload
success允许8080与8081端口流量通过public区域,立即生效且永久生效
1
2
3
4[root@localhost ~]# firewall-cmd --zone=public --add-port=9000-10000/tcp --permanent
success
[root@localhost ~]# firewall-cmd --reload
success查看模拟实验中的规则
1
2
3
4
5[root@localhost ~]# firewall-cmd --zone=public --list-ports
80/tcp 8081/tcp 9000-10000/tcp
[root@localhost ~]# firewall-cmd --zone=public --list-services
dhcpv6-client ssh
[root@localhost ~]#设置富规则,拒绝192.168.10.0/24网段的用户访问ssh服务:
1
firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="192.168.10.0/24" service name="ssh" reject"
将访问主机888端口的请求转发至22端口
1
2
3
4
5[root@localhost ~]# firewall-cmd --zone=public --add-forward-port=port=888:proto=tcp:toport=22:toaddr=10.18.23.13 --permanent
success
[root@localhost ~]# firewall-cmd --reload
success
[root@localhost ~]