学习本文前先了解下iptables那一章,这里很多概念都简略了......
Firewalld 是 iptables 的前端控制器,用于实现持久的网络流量规则。它提供命令行和图形界面,在大多数 Linux 发行版的仓库中都有。与直接控制 iptables 相比,使用 FirewallD 有两个主要区别:
- FirewallD 使用区域和服务而不是链式规则。
- 它动态管理规则集,允许更新规则而不破坏现有会话和连接。
区域
“区域”是针对给定位置或场景可能具有的各种信任级别的预构建规则集。不同的区域允许不同的网络服务和入站流量类型,而拒绝其他任何流量。 首次启用 Firewalld后,public是默认区域。区域也可以用于不同的网络接口。未明确设置为特定区域的任何接口将添加到默认区域。
区域 | 默认规则策略 |
---|---|
trusted | 允许所有的数据包流入与流出 |
home | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、mdns、ipp-client、amba-client与dhcpv6-client服务相关,则允许流量 |
internal | 等同于home区域 |
work | 拒绝流入的流量,除非与流出的流量数相关;而如果流量与ssh、ipp-client与dhcpv6-client服务相关,则允许流量 |
public | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh、dhcpv6-client服务相关,则允许流量 |
external | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量 |
dmz | 拒绝流入的流量,除非与流出的流量相关;而如果流量与ssh服务相关,则允许流量 |
block | 拒绝流入的流量,除非与流出的流量相关 |
drop | 拒绝流入的流量,除非与流出的流量相关 |
规则状态
- 运行时(runtime):修改规则后立即生效,重启服务后恢复原状
- 持久配置(permanent): 修改后要重载(reload)才会生效
配置文件
- /etc/firewalld/{services,zones}/*.xml:优先级最高,permanent模式生效的策略会放到这里
- /lib/firewalld/{services,zones}/*.xml:优先级次之,是一些默认配置,可以当做模板使用
管理命令
firewalld ...参数
常用参数列表:
- --permanent --配置写入到配置文件,否则临时马上生效
- --reload --重载配置文件,永久生效
- --zone= --指定区域
- --get-default-zones --获取默认区域
- --set-default-zone= --设置默认区域
- --get-zones --获取所有可用的区域
- --get-active-zones --获取当前激活(活跃)的区域
- --add-source= --添加地址,可以是主机或网段,遵循当前区域的target
- --remove-source --移除地址,可以是主机或网段,遵循当前区域的target
- --add-service= --添加服务,遵循当前区域的target
- --remove-service= --移除服务,遵循当前区域的target
- --list-services --显示指定区域内允许访问的所有服务
- --add-port= --添加端口,遵循当前区域的target
- --remove-port= --移除端口,遵循当前区域的target
- --list-ports 显示指定区域内允许访问的所有端口号
- --add-interface= --zone= --添加网卡到指定区域
- --change-interface= --new-zone-name --改变网卡到指定区域
- --list-all --列出激活使用的区域的配置
- --list-all-zones --列出所有区域的配置
- --get-zone-of-interface= --获取指定接口所在的区域
- --list-icmp-blocks --显示指定区域内拒绝访问的所有ICMP类型
- --add-icmp-block= --为指定区域设置拒绝访问的某项ICMP类型
- --remove-icmp-block= --移除指定区域内拒绝访问某项的ICMP类型
- 用的ICMP类型有
- echo-request:类型0,icmp请求报文
- echo-reply:类型8,icmp响应回复报文
- 用的ICMP类型有
- --list-protocols --列出在指定区域中允许通过的协议
- --add-protocol= --在指定区域中添加允许通过的协议
- --remove-protocol= --移除在指定区域中的某项协议
- --get-target --获取区域中的默认target
- --set-target= --设置区域的target
查看默认区域:
# firewall-cmd --get-default-zone
public
查看可使用区域:
# firewall-cmd --get-zones
block dmz drop external home internal public trusted work
修改默认区域:
# firewall-cmd --set-default-zone=work
success
# firewall-cmd --get-default-zone
work
在work区域放行http服务
# firewall-cmd --add-service=http --zone=work
success
# firewall-cmd --list-services --zone=work
dhcpv6-client http ssh
将来源于192.168.1.0的IP的数据包路由到public区域:
# firewall-cmd --add-source=192.168.1.0/24 --zone=public
success
#查看区域配置信息
# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources: 192.168.1.0/24
services: dhcpv6-client ssh
ports:
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
查看使用中的区域
# firewall-cmd --get-active-zones
work
interfaces: enp0s3
public
sources: 192.168.1.0/24
将接口绑定到public区域
#新增网卡绑定
#firewall-cmd --change-interface=enp0s8 --zone=work
success
#切换网卡绑定
# firewall-cmd --change-interface=enp0s3 --zone=public
success
# firewall-cmd --get-active-zones
work
interfaces: enp0s8
public
interfaces: enp0s3
sources: 192.168.1.0/24
查看网卡绑定区域:
# firewall-cmd --get-zone-of-interface=enp0s3
public
查看所有服务
# firewall-cmd --get-services
RH-Satellite-6 RH-Satellite-6-capsule 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-server
直接规则
firewalld提供了一个直接direct接口,允许传递原始 iptables 命令。 除非将直接规则显式插入到由firewalld管理的区域, 否则将首先解析直接规则,然后才会解析任何firewalld规则,即直接规则优先于firewalld规则。
一般情况下区域内规则的基本排序这样的:
- 为该区域设置的任何端口转发和伪装规则。
- 为该区域设置的任何记录规则。
- 为该区域设置的任何允许规则。
- 为该区域设置的任何拒绝规则。
firewall-cmd --direct 参数
参数:
- --direct:指定将要使用直接规则
- --get-all-chains:获取所有的链
- --get-chains:获取表中的链
- --add-chain:添加链到表中(自定义的)
- --remove-chain:移除表中的某条链
- --query-chain:返回链是否已被添加到表
- --get-all-rules:获取所有的策略规则
- --get-rules:获取指定表中指定链中的规则
- --add-rule:在指定表中的指定链添加规则
- --remove-rule:优先从指定表中的指定链删除规则条目
- --remove-rules:从表中删除规则条目
- --query-rule:返回是否优先的规则已被添加到链表中
- --passthrough:直接传递iptables的命令
- --get-all-passthroughs:获取所有直接传递的规则
- --get-passthroughs:获取跟踪直通规则
- --add-passthrough:添加一个直接规则
- --remove-passthrough :移除一个直接规则
- --query-passthrough:查询直接规则是否添加
利用直接规则实现SNAT:
#允许防火墙伪装IP
# firewall-cmd --zone=public --add-masquerade
# firewall-cmd --direct --passthrough ipv4 -t nat -I POSTROUTING -o enp0s3 -j MASQUERADE -s 172.25.0.9
或者
# firewall-cmd --direct --passthrough ipv4 -t nat -I POSTROUTING -o enp0s3 -j SNAT -s 172.25.0.9 --to-source 192.168.1.12
富规则
富规则比基本的firewalld语法实现更强的功能,不仅实现允许/拒绝,还可以实现日志syslog和auditd,也可以实现端口转发,伪装和限制速率。
firewall-cmd 参数
参数:
- --list-rich-rules:列出富规则
- --add-rich-rule=:使用富规则语言添加富规则
- --remove-rich-rule=:移除富规则
- --query-rich-rule=:查询某条富规则是否存在
- --list-rich-rules:列出指定区域中的所有富规则
- --list-all和--list-all-zones:列出存在的富规则
富规则语法结构:
rule
[source]
[destination]
[service|port|protocol|icmp-block|icmp-type|masquerade|forward-port|source-port]
[log]
[audit]
[accept|reject|drop|mark]
其中[]中的关键词称为元素,每个元素都有自己的选项,如下::
- Rule:
- rule [family="ipv4|ipv6"]
- Source:
- source [not] address="address[/mask]"|mac="mac-address"|ipset="ipset"
- Destination:
- destination [not] address="address[/mask]"
- Service:
- service name="service name"
- Port:
- port port="port value" protocol="tcp|udp"
- Protocol:
- protocol value="protocol value"
- ICMP-Block:
- icmp-block name="icmptype name"
- ICMP-Type:
- icmp-type name="icmptype name"
- Forward-Port:
- forward-port port="port value" protocol="tcp|udp" to-port="port value" to-addr="address"
- Source-Port:
- source-port port="port value" protocol="tcp|udp"
- Log:
- log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"]
- <log level>可以是emerg 、 alert 、 crit 、 error 、 warning 、 notice 、 info或debug之一。
- <rate/duration>可以是s(表示秒)、m(表示分钟)、h(表示小时)或d(表示天)之一。
- log [prefix="prefix text"] [level="log level"] [limit value="rate/duration"]
- Audit:
- audit [limit value="rate/duration"]
- Action:
- accept, reject, drop,mark.
- Limit:
- limit value="rate/duration"
批量添加端口:
# firewall-cmd --zone=public --add-rich-rule='rule family=ipv4 source address=192.168.1.0/24 port port=8080-8088 protocol=tcp accept'
success
# firewall-cmd --list-rich-rules
rule family="ipv4" source address="192.168.1.0/24" port port="8080-8088" protocol="tcp" accept
work区域允许ssh连接,并且每分钟最多记录三条notice等级的日志到syslog:
# firewall-cmd --zone=work --add-rich-rule='rule service name="ssh" log prefix="ssh" level="notice" limit value="3/m" accept'
拒绝192.168.1.12的dns服务连接,并每小时最多一条日志记录到audit系统,这条规则五分钟内有效:
# firewall-cmd --add-rich-rule='rule family=ipv4 source address="192.168.1.12" service name="dns" audit limit value="1/h" reject'
--timeout=300
伪装
firewalld支持伪装(伪装只能和ipv4一起用,ipv6不行),将报文中的来源或者目标地址进行伪装
检查是否允许伪装:
# firewall-cmd --query-masquerade
开启防火墙伪装
# firewall-cmd --add-masquerade
禁止防火墙伪装:
# firewall-cmd --remove-masquerade
将来自172.25.0.9的报文源IP伪装为本机IP,从enp0s3网卡接口流出处理后的报文
#直接规则写法
# firewall-cmd --direct --passthrough ipv4 -t nat -I POSTROUTING -o enp0s3 -j MASQUERADE -s 172.25.0.9
#富规则写法
# firewall-cmd --add-rich-rule='rule family=ipv4 source address=172.25.0.0/24 masquerade'
端口转发
将发往本机的特定端口的流量转发到本机或不同机器的另一个端口
firewall-cmd --permanent --zone=<ZONE> --add-forward-port=port=<PORTNUMBER>:proto=<PROTOCOL>[:toport=<PORTNUMBER>][:toaddr=]
转发2222端口的流量到172.25.0.9的22端口:
# firewall-cmd --add-masquerade 【测试此语法会自动更改配置,linux开启内核转发】
#常规写法
# firewall-cmd --add-forward-port=port=2222:proto=tcp:toport=22:toaddr=172.25.0.9
富规则写法
# firewall-cmd --add-rich-rule='rule family=ipv4 forward-port port=2222 protocol=tcp to-addr=172.25.0.9 to-port=22'
一键断网
#开启应急模式
# firewall-cmd --panic-on
#关闭应急模式
# firewall-cmd --panic-off
#查看是否处于应急模式
# firewall-cmd --query-panic
自定义区域和服务
自定义区域:参照/lib/firewalld/zones/public.xml文件,在/lib/firewalld/zones/下面新建.xml结尾的区域文件。
自定义服务:参照/usr/lib/firewalld/services/ssh.xml,在/usr/lib/firewalld/services/下面.xml结尾的服务文件。
最后记得重新reload
List of learning reference documents:
- https://www.cnblogs.com/meizy/p/firewalld.html