Loading

Firewalld深入理解

Firewalld深入理解

目录

1. 介绍

防火墙是保护机器不受来自外部的。不需要的网络数据的一种方式。它允许用户通过定义一组防火墙规则来控制主机上的入站网络流量。这些规则用于对进入的流量进行排序,并可以阻断或允许流量。

2. 开始使用firewalld

2.1. 使用 firewalld、nftables 或者 iptables 时

以下是使用防火墙工具之一的概述:

  • firewalld:在简单防火墙用例中firewalld工具,该工具非常容易使用,并涵盖这些场景的典型用例。
  • nftables:使用nftables实用程序设置复杂和性能的关键防火墙,比如为整个网络设置。
  • iptables:Red Hat Enterprise Linux 8中的IPtables工具程序使用nf_tables内核API而不是legacy后端。nf_tablesAPI提供向后兼容性,使用iptables命令的脚本仍然可用于Red Hat Enterprise Linux 8,对于新的防火墙脚本,红帽建议使用nftables
PS: 要避免不同的防火墙服务相互影响,在 RHEL 主机中只有一个服务,并禁用其他服务。

2.2. Zones

firewalld 可以用来根据用户决定放置在哪个网络中的借口和流量级别的信任级别将网络划分为不同的区。一个链接只能是一个区的一部分,但一个区可以被用来进行很多网络连接。

NetworkManager通知接口区的firewalld。你可以为接口分配区:

  • Networkmanager
  • firewall-config工具
  • firewalld-cmd命令行工具
  • RHEL web控制台

后面三个只能编辑正确的Networkmanager配置文件。如果你使用web控制台firewall-cmd或firewall-config更改接口区域,则请求会转发到NetworkManager且不由firewalld处理。

预定义区域存储在/usr/lib/firewalld/zones/目录中,并可立即应用与任意可用的网络接口。只有在修改后,这些文件才会复制到/etc/firewalld/zones/目录中。预定义区的默认设置如下:

  • Block

    任何传入的网络连接都会拒绝,并会拒绝IPv4的icmp-host-prohibited(用于IPv6)和 icmp6-adm-prohibited。只用从系统启动的网络连接才能进行。

  • dmz

    对于你的非企业化区里的计算机来说,这些计算机可以被公开访问,且有限访问你的内部网络。只接受所选的入站连接。

  • drop

    所有传入的网络数据包都会丢失,没有任何通知。只有外发网络连接是可行的。

  • external

    适用于启用了伪装的外部网络,特别是路由器。再不信任网络中的其他计算机不会损害自身的计算机。只接受所选的入站连接。

  • home

    用于家用,因为你可以信任其他计算机。只接受所选的入站连接。

  • internal

    当你主要信任网络中的其他计算机时, 供内部网络使用。只接受所选的入站连接。

  • public

    可用于你不信任网络中其他计算机的公共区域。只接受所选的入站连接。

  • trusted

    所有网络连接否被接受。

  • work

    可用于你主要信任网络中其他计算机的工作。只接受所选的入站连接。

这些区中的一个被设置为default区。当接口连接添加到NetworkManager时,它们会被分配给默认区。安装时,firewalld的默认区设置为public区。默认区可以被修改。

PS: 为了避免网络安全问题,在查看默认区配置并根据你的需要和风险禁用任何不必要的服务。

2.2.3 预定义的服务

可以提前准备好配置文件,在启动了服务时,会自动载入防火墙规则,可以让服务节省用户时间,因为它们可以完成一些任务,比如打开端口、定义协议、启用数据包转发等等。而不必在另外的步骤中设置所有任务。

可以编辑 /etc/firewalld/services/ 目录中的 XML 文件。如果用户没有添加或更改服务,则在 /etc/firewalld/services/ 中没有找到对应的 XML 文件。如果要添加或更改服务,/usr/lib/firewalld/services/ 目录中的文件可作为模板使用。

3. 查看当前状态和设置firewalld

3.1. 查看当前状态firewalld

防火墙服务firewalld被默认安装在系统中。使用firewalldCLI界面检查该服务是否正在运行。

流程

  1. 查看服务的状态:

    # firewall-cmd --state
    
    1. 有关服务状态的更多信息,可以使用 systemctl status 子命令:
    ● firewalld.service - firewalld - dynamic firewall daemon
       Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
       Active: active (running) since Fri 2021-11-19 17:31:05 CST; 8s ago
         Docs: man:firewalld(1)
     Main PID: 86532 (firewalld)
        Tasks: 2
       Memory: 28.5M
       CGroup: /system.slice/firewalld.service
               └─86532 /usr/bin/python2 -Es /usr/sbin/firewalld --nofork --nopid
    

其他资源

在尝试编辑设置前,了解firewalld是如何设置的以及哪些规则被强制实施非常重要。要现实防火墙设置,已root用户身份使用 firewall-cmd --list-all。

3.2. 使用CLI查看firewalld设置

使用CLI客户端可能会对当前防火墙设置有不同的视图。--list-all 选项显示 firewalld 设置的完整概述。

firewalld使用zone管理流量。如果 --zone 选项没有指定区,改命令将在分配给活跃网络接口和连接的默认区里有效。

流程

  • 要列出默认区的所有相关信息:

    [root@deploy-150-64 ~]# firewall-cmd --list-all
    public
      target: default
      icmp-block-inversion: no
      interfaces:
      sources:
      services: dhcpv6-client ssh
      ports:
      protocols:
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:
      rich rules:
    
  • 要置顶显示设置的区域,在firewall-cmd --list-all 命令中添加 --zone=*zone-name* 参数,例如:

    [root@deploy-150-64 ~]# firewall-cmd --list-all --zone=home
    home
      target: default
      icmp-block-inversion: no
      interfaces:
      sources:
      services: dhcpv6-client mdns samba-client ssh
      ports:
      protocols:
      masquerade: no
      forward-ports:
      source-ports:
      icmp-blocks:
      rich rules:
    
  • 要查看特定信息(如服务或端口)的设置,请使用特定选项。请查看firewalld 手册页或使用命令帮助获得选项列表:

    firewall-cmd --help
    
  • 查看当前区中允许哪些服务:

    [root@deploy-150-64 ~]# firewall-cmd --list-services
    dhcpv6-client ssh
    

4. 使用firewalld

4.1. 使用CLI禁用紧急时间的所有流量

在紧急情况下,如系统攻击,可以禁用所有网络流量并关闭攻击者。

流程

  1. 要立即禁用网络流量,请切换panic模式:

    [root@deploy-150-64 ~]# firewall-cmd  --panic-on
    success
    

    注意:启用 panic 模式可停止所有网络流量。因此,他应只在对服务器有web控制终端时才使用

  2. 关闭panic 模式会使防火墙恢复到其永久设置。要关闭 panic 模式,请输入:

    [root@deploy-150-64 ~]# firewall-cmd --panic-off
    

验证

  • 要查看是否打开或关闭panic模式,使用:

    [root@deploy-150-64 ~]# firewall-cmd --query-panic
    

4.2. 使用CLI控制预定义服务的流量

控制流量的最简单方法是在firewalld中添加预定义服务。这会打开所有必须的端口并根据服务定义文件修改其他设置。

流程

  1. 检查该服务是否还未被允许:

    [root@deploy-150-64 ~]# firewall-cmd --list-services
    dhcpv6-client ssh
    
    1. 列出所有预定义的服务:
    [root@deploy-150-64 ~]# 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
    
    1. 在允许的服务中添加服务:
    # firewall-cmd --add-service=<service-name>
    
    1. 使新设置持久:
    # firewall-cmd --runtime-to-permanent
    

4.3 使用GUI,使用预定义服务控制流量

这个步骤描述了如何使用图形用户界面控制预定义服务的网络流量。

流程

  1. 启用或禁用预定义或自定义服务:
    1. 启动 firewall-config 工具并选择要配置的服务的网络区。
    2. 选择 Services 标签。
    3. 选择您要信任的每种服务类型的复选框,或者清除要阻断服务的复选框。
  2. 编辑服务:
    1. 启动 firewall-config 工具。
    2. 从标记的 Configuration 菜单中选择 Permanent。其它图标和菜单按钮会出现在服务窗口底部。
    3. 选择您要配置的服务。

注意:在 Runtime 模式中无法更改服务设置。

4.4. 添加新服务

可使用图形化的 firewall-config 工具 firewall-cmdfirewall-offline-cmd添加和删除服务。或者,您可以编辑 /etc/firewalld/services/ 中的 XML 文件。如果用户没有添加或更改服务,则在 /etc/firewalld/services/ 中没有找到对应的 XML 文件。如果要添加或更改服务,/usr/lib/firewalld/services/ 文件可作为模板使用。

注意:服务名称必须是字母数字,以及 _(下划线)和 -(横线)字符。

5. 使用CLI控制端口

端口是可让操作系统接收和区分网络流量并将其转发到系统服务的逻辑设备。他们通常由监听端口的守护进程处理,它会等待到达这个端口的任何流量。

5.1 打开端口

通过打开端口,系统可从外部访问,这代表了安全风险,通常,让端口保持关闭,且只在某些服务需要时打开。

流程

要获得当前区的打开端口列表:

  1. 列出所有允许的端口:

    [root@deploy-150-64 ~]# firewall-cmd --list-ports
    
  2. 在允许的端口中添加一个端口,以便为入站流量打开这个端口:

    [root@deploy-150-64 ~]# firewall-cmd --add-port=port-number/port-type
    

    端口类型可以是tcp、udp、sctp或dccp。这个类型必须与网络通信的类型匹配。

    1. 使新设置具有持久性:
    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

5.2 关闭端口

当不再需要开放端口时,在 firewalld中闭该端口。强烈建议您尽快关闭所有不必要的端口,因为端口处于打开状态会存在安全隐患。

流程

要关闭某个端口,请将其从允许的端口列表中删除:

  1. 列出所有允许的端口:

    [root@deploy-150-64 ~]# firewall-cmd --list-ports
    

    警告

    这个命令只为您提供已打开作为端口的端口列表。您将无法看到作为服务打开的任何打开端口。因此,您应该考虑使用 --list-all 选项而不是使用 --list-ports

  2. 从允许的端口中删除端口,以便对传入的流量关闭:

    [root@deploy-150-64 ~]# firewall-cmd --remove-port=port-number/port-type
    
  3. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

6. 使用firewalld区

zones代表一种更透明管理传入流量的概念。这些区域连接到联网接口或者分配一系列源地址。你可以独立为每个区管理防火墙规则,这样就可以定义复杂的防火墙设置并将其应用到流量。

6.1 列出区域

这个步骤描述了如何使用命令行列出区。

流程

  1. 查看系统中有那些可用区:

    [root@deploy-150-64 ~]# firewall-cmd --get-zones
    `firewall-cmd --get-zones` 命令显示系统中所有可用的区域,但不显示具体区的详情。
    

    firewall-cmd --get-zones 命令显示系统中所有可用的区域,但不显示具体区的详情。

    1. 查看所有区的详细信息:
    # firewall-cmd --list-all-zones
    
    1. 查看特定区的详细信息:
    # firewall-cmd --zone=zone-name --list-all
    

6.2 更改特定区的firewalld设置

使用CLI和Controlling端口控制预定义服务的流量,如何在当前工作区范围内添加或修改端口。有时,需要在不同区内设定规则。

流程

  • 要在不同的区中工作,使用 --zone=zone-name 选项。列如,允许在区public中使用SSH服务:

    [root@deploy-150-64 ~]# firewall-cmd --add-service=ssh --zone=public
    

6.3 更改默认区

系统管理员在其配置文件中为网络接口分配区域,如果接口没有被分配到指定区,他将被分配给默认区,每次重启firewalld服务后,都会重新加载默认区让其生效。

流程

设置默认区:

  1. 显示当前的默认区:

    [root@deploy-150-64 ~]# firewall-cmd --get-default-zone
    public
    
    1. 设置新的默认区:
    [root@deploy-150-64 ~]# firewall-cmd --set-default-zone new-zone-name
    

    注意:在此流程后,设置一个永久设置。

6.4 将网络接口分配给区

可以为不同区定义不同的规则集,然后通过更改所使用接口的区来快速改变设置,使用多个接口,可以为每个具体区设置一个区来区分通过他们的网络流量。

流程

要将区分配给特定的接口:

  1. 列出runing状态的区以及给它们的接口:

    [root@deploy-150-64 ~]# firewall-cmd --get-active-zones
    
    1. 为不同的区分配接口:
    [root@deploy-150-64 ~]# firewall-cmd --zone=zone_name --change-interface=interface_name --permanent
    

6.5 使用nmcli为连接分配区域

这个步骤描述了如何使用 nmcli 工具在 NetworkManager 连接中添加 firewalld 区。

流程

  1. NetworkManager 连接配置集分配区域:

    [root@deploy-150-64 ~]# nmcli connection modify profile connection.zone zone_name
    
  2. 重新加载连接:

    [root@deploy-150-64 ~]# nmcli connection up profile
    

6.6. 在ifcfg文件手动将区分配给网络连接

当连接网络管理器(NetworkManager)管理时,必须了解他使用的区域,为每个网络连接指定区域,根据计算机可移植设备的位置提供各种防火墙设置的灵活性。可以为不同的位置指定区域和设置

流程

  • 要为连接设置区,编辑/etc/sysconfig/network-scripts/ifcfg-{connection_name}文件并添加为这个链接分配区的行:

    ZONE=zone_name
    

6.7. 创建一个新区

要使用自定义区,床架您一个新的区并使用它想预定义区一样,新区需要--permanent 选项,否则命令无法正常工作。

流程

  1. 创建一个新区:

    [root@deploy-150-64 ~]# firewall-cmd --new-zone=zone-name
    

    注意:重启firewalld 才会生效

  2. 检查是否在您的永久设置中添加了新的区:

    [root@deploy-150-64 ~]# firewall-cmd --get-zones
    
  3. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

6.8. 区配置文件

区也可以通过区配置文件的方式进行创建,如果你想创建新区,但想不同区重复使用进行设置,这种方法就很便捷。

firewalld 区配置文件包含区的信息。这些区描述、服务、端口、协议、icmp-blocks、masquerade、forward-ports 和丰富的语言规则采用 XML 文件格式。文件名必须是 *zone-name*.xml,其中 zone-name 的长度限制为 17 个字符。区配置文件位于 /usr/lib/firewalld/zones//etc/firewalld/zones/ 目录中。

以下示例显示了允许一个服务(SSH)和一个端口范围的配置,适用于 TCPUDP 协议:

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>My Zone</short>
  <description>Here you can describe the characteristic features of the zone.</description>
  <service name="ssh"/>
  <port protocol="udp" port="1025-65535"/>
  <port protocol="tcp" port="1025-65535"/>
</zone>

要更改那个区的设置,请添加或者删除相关的部分来添加端口、转发端口、服务等等。

6.9. 使用区目标设定传入流量的默认行为

对于每个区,你可以设置传入流量的默认行为,这种行为可以通过设置区目标来定义。有四个选项 - defaultACCEPTREJECTDROP。通过将目标设置为ACCEPT,会接收除特定规则禁用外的所有传入的数据包。如果将目标设置为REJECTDROP,那你将会除去特定规则的数据包全部禁用。拒绝数据包时,会通知源机器,但丢弃数据包不会发送任何信息。

流程

为区设置目标:

  1. 列出特定区的信息以查看默认目标:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --list-all
    
  2. 在区中设置一个新目标:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --zone=zone-name --set-target=<default|ACCEPT|REJECT|DROP>
    

7. 根据源使用区管理传入流量

7.1 根据源使用区管理传入流量

你可以使用区管理对传入的流量进行管理。可让你对进入的流量进行排序,并将其路由到不同的区,以允许或禁止该流量可访问的服务。

7.2 添加源

要将传入的流量路由到特定源,请将那个源添加到那个区。源可以是一个使用CIDR格式的IP地址或IP掩码。

注意:如果你天剑多个带有重复网络范围的区域,则根据区名称排序,且只考虑第一个区。

  • 在当前区中设置源:

    [root@deploy-150-64 ~]# firewall-cmd --add-source=<source>
    
  • 要为特定区设置源 IP 地址:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --add-source=<source>
    

流程

  1. 列出所有可用区:

    [root@deploy-150-64 ~]# firewall-cmd --get-zones
    
  2. 将源 IP 添加到持久性模式的信任区中:

    [root@deploy-150-64 ~]# firewall-cmd --zone=trusted --add-source=192.168.2.15
    
  3. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

7.3. 删除源

从区中删除源会关闭来自它的网络流量。

流程

  1. 列出所需区的允许源:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --list-sources
    
  2. 从区永久删除源:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --remove-source=<source>
    
  3. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

7.4. 添加源端口

要启用原始端口对流量排序,使用--add-source-port 选项指定源端口。还可以将此选项与 --add-source 选项合并,将流量限制为特定IP地址或IP范围

流程

  • 添加源端口:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --add-source-port=<port-name>/<tcp|udp|sctp|dccp>
    

7.5. 删除源端口

通过删除源端口,您可以根据原始端口禁用对流量排序。

流程

  • 要删除源端口:

    [root@deploy-150-64 ~]# firewall-cmd --zone=zone-name --remove-source-port=<port-name>/<tcp|udp|sctp|dccp>
    

7.6. 使用区和源来允许一个服务只适用于一个特定的域

要允许特定网络的流量在机器上使用服务,请使用区和源。以下流程只允许来自 192.0.2.0/24 网络的 HTTP 流量,同时阻断任何其他流量。

警告:当你配置这种情况时,应该是使用具有default目标的区域。 使用将目标设置为accept的区域会存在安全隐患,因为对于来自192.0.2.0/24的流量,所有的网络连接都会被接受。

流程

  1. 列出所有可用区:

    [root@deploy-150-64 ~]# firewall-cmd --get-zones
    block dmz drop external home internal public trusted work
    
  2. 将 IP 范围添加到 internal 区域,将来自源的网络流量路由到区:

    [root@deploy-150-64 ~]# firewall-cmd --zone=internal --add-source=192.0.2.0/24
    
  3. internal 区中添加 http 服务:

    [root@deploy-150-64 ~]# firewall-cmd --zone=internal --add-service=http
    
  4. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

验证

  • 检查 internal 区是否运行,且该服务是否允许。

    # firewall-cmd --zone=internal --list-all
    internal (active)
      target: default
      icmp-block-inversion: no
      interfaces:
      sources: 192.0.2.0/24
      services: cockpit dhcpv6-client mdns samba-client ssh http
      ...
    

8. 使用firewalld配置NAT

使用firewalld,可以使用以下网络地址转换(NAT)类型:

  • 伪装
  • 源NAT (SNAT)
  • 目标NAT(DNAT)
  • 重定向

8.1 不同的NAT类型:masquerading、source NAT、destination NAT和redirect

伪装和源NAT(SNAT)

使用以上NAT类型之一更改数据包的源IP地址。列如:互联网服务提供商不会路由私有IP范围,如10.0.0.0/8。如果你在网络中欧使用私有IP范围,并且用户可以访问互联网中的服务器,请将这些范围内的数据包源IP地址映射到一个公共IP地址。

伪装和SNAT都非常相似。不同之处是:

  • 伪装自动使用传出接口的IP地址。因此,如果传出接口使用了动态IP地址,则使用伪装
  • SNAT将数据包的源IP地址设置为指定的IP地址,且不会动态查找传出接口的IP地址。因此,SNAT要比伪装要快。如果传出接口使用了固定IP地址,则使用SNAT。

目标NAT(DNAT)

使用此NAT类型重写传入数据包的目标地址和端口。例如,你的网页服务器使用了来自私有IP范围内的IP地址,因此无法直接从互联网访问,你可以在路由器上设置DNAT规则来重定向进入该服务器的流量。

重定向

这个类型是IDT的特殊示例,他根据链hook将数据包重定向到本地机器,例如,如果服务在标准端口不同的端口中原先,你可以将标准端口传入的流量重定向到这个特定端口。

8.2 配置IP地址伪装

流程

  1. 要检查 IP 伪装是否已启用(例如,对于 external 区),以 root 的身份输入以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --zone=external --query-masquerade
    yes
    

    如果已启用,该命令会输出 yes,退出状态为 0。否则,会输出 no,退出状态为 1。如果省略 zone,将使用默认区。

  2. 要启用 IP 伪装,以 root 的身份输入以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --zone=external --add-masquerade
    
  3. 要让此设置持久,请重复添加 --permanent 选项的命令。

要禁用 IP 伪装,以 root 身份输入以下命令:

[root@deploy-150-64 ~]# firewall-cmd --zone=external --remove-masquerade --permanent

9. 端口转发

使用此方法重定向端口只可用于基于IPv4的流量。对于IPv6重定向设置,你必须使用丰富的规则。

9.1 添加一个端口来重定向

使用firewalld 你可以设置端口重定向,以便将所有进入的流量传入到你选择的其它内部端口或者另一台机器上的外部端口。

先决条件

  • 在你将从一个端口的流量重新指向另一个端口或另一个地址前,你必须了解3个信息:数据包到达哪个端口,使用什么协议,以及你要重定向它们的位置。

流程

  1. 将端口重新指向另一个端口:

    [root@deploy-150-64 ~]# firewall-cmd --add-forward-port=port=port-number:proto=tcp|udp|sctp|dccp:toport=port-number
    
  2. 将端口重定向到不同 IP 地址的另一个端口:

    1. 添加要转发的端口:

      [root@deploy-150-64 ~]# firewall-cmd --add-forward-port=port=port-number:proto=tcp|udp:toport=port-number:toaddr=IP
      
    2. 启用伪装:

      [root@deploy-150-64 ~]# firewall-cmd --add-masquerade
      

9.2. 将TCP端口80重定向到同一台机器中的88端口

流程

  1. 将端口 80 重定向到 TCP 流量的端口 88:

    [root@deploy-150-64 ~]# firewall-cmd --add-forward-port=port=80:proto=tcp:toport=88
    
  2. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    
  3. 检查是否重定向了端口:

    [root@deploy-150-64 ~]# firewall-cmd --list-all
    

9.3 删除重定向的端口

流程

  1. 要删除重定向的端口:

    [root@deploy-150-64 ~]# firewall-cmd --remove-forward-port=port=port-number:proto=<tcp|udp>:toport=port-number:toaddr=<IP>
    
  2. 要删除重定向到不同地址的转发端口:

    1. 删除转发的端口:

      [root@deploy-150-64 ~]# firewall-cmd --remove-forward-port=port=port-number:proto=<tcp|udp>:toport=port-number:toaddr=<IP>
      
    2. 禁用伪装:

      [root@deploy-150-64 ~]# firewall-cmd --remove-masquerade
      

9.4 在同一台机器上将 TCP 端口 80 转发到端口 88

这个步骤描述了如何删除端口重定向。

流程

  1. 列出重定向的端口:

    ~]# firewall-cmd --list-forward-ports
    port=80:proto=tcp:toport=88:toaddr=
    
  2. 从防火墙中删除重定向的端口:

    ~]# firewall-cmd  --remove-forward-port=port=80:proto=tcp:toport=88:toaddr=
    
  3. 使新设置具有持久性:

    ~]# firewall-cmd --runtime-to-permanent
    

10. 管理ICMP请求

Internet Control Message ProtocolICMP)是一个支持协议,不同的网络设备使用它来发送错误信息和现实连接问题的擦偶作信息,例如:请求的服务不可用。ICMP与TCP和UDP等传输协议不同,因为它没有用来系统间交换数据。

使用 ICMP 信息(特别是 echo-requestecho-reply )可能会公开您的网络信息,这些信息可能会被利用而造成安全隐患。因此, firewalld 启用阻止 ICMP 请求来保护您的网络信息。

10.1 列出和阻塞ICMP请求

列出ICMP请求

ICMP 请求在位于 /usr/lib/firewalld/icmptypes/ 目录中的独立 XML 文件中描述。你可以阅读这些文件来查看请求的描述。firewall-cmd 命令控制 ICMP 请求操作。

  • 列出所有可用的 ICMP 类型:

    [root@deploy-150-64 ~]# firewall-cmd --get-icmptypes
    
  • IPv4、IPv6 或两个协议都可以使用 ICMP 请求。要查看 ICMP 请求使用的协议:

    [root@deploy-150-64 ~]# firewall-cmd --info-icmptype=<icmptype>
    
  • ICMP 请求的状态会显示为 yes (请求当前被阻塞)或 no (请求当前没有被阻塞)。检查 ICMP 请求当前是否被阻断:

    [root@deploy-150-64 ~]# firewall-cmd --query-icmp-block=<icmptype>
    

阻塞或是取消阻塞 ICMP 请求

当你的服务器阻断ICMP请求时,他不会提供通常会提供的信息,但这并不意味着根本不给出任何信息。客户端收到特定ICMP请求备足端的信息(拒绝)。应仔细考虑阻塞ICMP请求,因为它可能会造成通信问题,特别是IPV6流量。

  • 检查 ICMP 请求当前是否被阻断:

    [root@deploy-150-64 ~]# firewall-cmd --query-icmp-block=<icmptype>
    
  • 阻止 ICMP 请求:

    [root@deploy-150-64 ~]# firewall-cmd --add-icmp-block=<icmptype>
    
  • 删除 ICMP 请求的块:

    [root@deploy-150-64 ~]# firewall-cmd --remove-icmp-block=<icmptype>
    

在不提供任何信息情况下阻断ICMP请求

通常,如果你阻断ICMP请求,客户端会知道你正在阻断他。这样潜在的攻击者任然可以看到的你IP地址在线。要完全隐藏这些信息,你必须删除所有ICMP请求。

  • 阻塞和丢弃所有ICMP请求:

  • 将区的目标设置为DROP:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --set-target=DROP
    

    注意:需要执行firewall-cmd reload才能立即生效

现在,除您明确允许的流量外,所有流量(包括 ICMP 请求)将被丢弃。

阻塞或丢弃特定的 ICMP 请求,并允许其他请求:

  1. 将区的目标设置为 DROP:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --set-target=DROP
    
  2. 添加 ICMP 块 inversion 以阻止所有 ICMP 请求:

    [root@deploy-150-64 ~]# firewall-cmd --add-icmp-block-inversion
    
  3. 为那些 ICMP 请求添加 ICMP 块:

    [root@deploy-150-64 ~]# firewall-cmd --add-icmp-block=<icmptype>
    
  4. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

block inversion 用来转换 ICMP 请求块的设置,因此所有之前没有阻断的请求都因为区的目标改变为 DROP 而被阻断。被阻断的请求不会被阻断。这意味着,如果您想要取消阻塞请求,则必须使用 blocking 命令。

将块 inversion 恢复到完全 permissive 设置:

  1. 将区的目标设置为 defaultACCEPT

    [root@deploy-150-64 ~]# firewall-cmd --permanent --set-target=default
    
  2. 删除 ICMP 请求的所有添加的块:

    [root@deploy-150-64 ~]# firewall-cmd --remove-icmp-block=<icmptype>
    
  3. 删除 ICMP 块 inversion:

    [root@deploy-150-64 ~]# firewall-cmd --remove-icmp-block-inversion
    
  4. 使新设置具有持久性:

    [root@deploy-150-64 ~]# firewall-cmd --runtime-to-permanent
    

11. 使用firewalld

要查看 firewalld 支持的 IP 集合类型列表,以 root 用户身份输入以下命令。

~]# firewall-cmd --get-ipset-types
hash:ip hash:ip,mark hash:ip,port hash:ip,port,ip hash:ip,port,net hash:mac hash:net hash:net,iface hash:net,net hash:net,port hash:net,port,net

46.10.1. 使用 CLI 配置 IP 设置选项

IP集可以在firewalld区域中用作源,也可以作为丰富的规则的源使用。在Red Hat Enterprise linux中,首选的方法是使用在直接规则firewalld中创建的IP集合。

  • 要列出永久环境中 firewalld 已知的 IP 集,请使用以下命令 root

    [root@deploy-150-64 ~]# firewall-cmd --permanent --get-ipsets
    
  • 要添加新 IP 集,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --new-ipset=test --type=hash:net
    success
    

    以上命令为 IPv4 创建了名称为 test 类型为 hash:net 的新 IP 设置。要创建用于 IPv6 的 IP 集,添加 --option=family=inet6 选项。要使新设置在运行时环境中有效,请重新载入 firewalld

  • 使用以下命令列出新 IP 设置:root

    [root@deploy-150-64 ~]# firewall-cmd --permanent --get-ipsets
    test
    
  • 要获得有关 IP 集的更多信息,以 root 用户身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --info-ipset=test
    test
    type: hash:net
    options:
    entries:
    

    请注意,IP 集目前没有任何条目。

  • 要在 test IP 集中添加一个项,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --ipset=test --add-entry=192.168.0.1
    success
    

    前面的命令将 IP 地址 192.168.0.1 添加到 IP 集合中。

  • 要获取 IP 集合中当前条目列表,以 root 用户身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --ipset=test --get-entries
    192.168.0.1
    
  • 生成包含 IP 地址列表的文件,例如:

    [root@deploy-150-64 ~]# cat > iplist.txt <<EOL
    192.168.0.2
    192.168.0.3
    192.168.1.0/24
    192.168.2.254
    EOL
    

    包含 IP 集合 IP 地址列表的文件应该每行包含一个条目。以 hash、分号或空行开头的行将被忽略。

  • 要添加 iplist.txt 文件中的地址,以 root 身份运行以下命令:

    # firewall-cmd --permanent --ipset=test --add-entries-from-file=iplist.txt
    success
    
  • 要查看 IP 集合的扩展条目列表,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --ipset=test --get-entries
    192.168.0.1
    192.168.0.2
    192.168.0.3
    192.168.1.0/24
    192.168.2.254
    
  • 要从 IP 集合中删除地址并检查更新的条目列表,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --ipset=test --remove-entries-from-file=iplist.txt
    success
    [root@deploy-150-64 ~]# firewall-cmd --permanent --ipset=test --get-entries
    192.168.0.1
    
  • 您可以将 IP 集合作为一个源添加到区,以便处理所有来自 IP 集合中列出的任意地址的网络流量。例如:要将 test IP 集添加为 drop 区的一个源,以便丢弃所有来自在 test IP 集中列出的所有条目的所有数据包,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --permanent --zone=drop --add-source=ipset:test
    success
    

    源中的 ipset: 前缀显示 firewalld,源是一个 IP 集,而不是一个 IP 地址或地址范围。

只有创建和删除 IP 集限于永久环境,其它所有 IP 设置选项也可以在运行时环境中使用,即使没有 --permanent 选项。

注意:红帽不推荐使用不是通过 firewalld 管理的 IP 集。要使用这样的 IP 组,需要一个永久直接规则来引用集合,且必须添加自定义服务来创建这些 IP 组件。这个服务需要在 firewalld 启动前启动,否则 firewalld 无法使用这些组添加直接规则。您可以使用 /etc/firewalld/direct.xml 文件添加永久直接规则

12. 丰富规则的优先级

默认情况下,丰富的规则会根据其规则操作进行组织,例如:deny规则优先于allow规则。proiority参数丰富的规则可让管理员对丰富的规则及其执行顺序进行精细化的控制。

12.1 priority参数如何讲规则组织为不同的链

你可以将priority参数设置为在 -3276832767 之间的任意数量,较低值具有更高的优先级。

firewalld服务根据优先级值在不同的链中组织规则:

  • 优先级低于0:规则被重定向到带有_pre后缀的链中。
  • 优先级高于0:规则被重定向到使用_post后缀的链中。
  • 优先级等于0:基于操作,规则会被重定向带到带有_log、_deny或_allow操作的链中。

在这些子链中,firewalld会根据其优先级值对规则排序。

12.2. 设置丰富的规则的优先级

以下流程介绍了一个实例,他创建了一个丰富的规则,他是用priority参数记录被他规则不允许或拒绝的所有流量。你可以使用此规则标记意非预期的流量。

流程

  1. 添加一个带有非常低优先级的丰富规则记录 未被其他规则匹配的所有流量:

    # firewall-cmd --add-rich-rule='rule priority=32767 log prefix="UNEXPECTED: " limit value="5/m"
    

这个命令还会将日志条目数限制为每分钟 5 个。

  1. 另外,显示上一步中命令创建的 nftables 规则:

    # nft list chain inet firewalld filter_IN_public_post
    table inet firewalld {
      chain filter_IN_public_post {
        log prefix "UNEXPECTED: " limit rate 5/minute
      }
    }
    

13. 配置防火墙锁定

如果本地应用程序或服务是作为root运行的,则可以更改防火墙配置。使用这个特性,管理员可以锁定防火墙配置,从而达到没有应用程序或只有添加到锁定白名单中的应用程序可以请求防火墙更改的目的。锁定设置默认会被禁用。如果启用,用户就可以确定,防火墙没有被本地的应用程序或服务进行了不必要的配置更改。

13.1. 使用CLI配置锁定

这个步骤描述了如何使用命令行启用或禁用锁定。

  • 要查询是否启用锁定,使用以下命令: root

    [root@deploy-150-64 ~]# firewall-cmd --query-lockdown
    

    如果启用了锁定,则命令会输出 yes,退出状态为 0。否则,它会输出 no,退出状态为 1

  • 要启用锁定,以 root 身份输入以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --lockdown-on
    
  • 要禁用锁定,以 root 身份运行以下命令:

    [root@deploy-150-64 ~]# firewall-cmd --lockdown-off
    

13.2. 使用CLI配置锁定允许列表选项

锁定允许吗名单中可以包括命令、安全上下文、用户和用户ID。如果允许列表中的命令条目以星号“*”结尾。则所有以该命令开头的命令行都进行匹配。

  • 上下文是正在运行的应用程序或服务的安全(SELinux)上下文。要获得正在运行的应用程序的上下文,请使用以下命令:

    $ ps -e --context
    

    该命令返回所有正在运行的应用程序。通过 grep 工具管道输出以便获取您感兴趣的应用程序。例如:

    $ ps -e --context | grep example_program
    
  • 要列出允许列表中的所有命令行,以 root 身份输入以下命令:

    # firewall-cmd --list-lockdown-whitelist-commands
    
  • 要在允许列表中添加 命令 command,以 root 身份输入以下命令:

    # firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python3 -Es /usr/bin/command'
    
  • 要从允许列表中删除 命令 command,以 root 身份输入以下命令:

    # firewall-cmd --remove-lockdown-whitelist-command='/usr/bin/python3 -Es /usr/bin/command'
    
  • 要查询 command 命令是否在 allowlist 中,以 root 身份输入以下命令:

    # firewall-cmd --query-lockdown-whitelist-command='/usr/bin/python3 -Es /usr/bin/command'
    

    如果为 true,该命令会输出 yes,退出状态为 0。否则,它会输出 no,退出状态为 1

  • 要列出允许列表中的所有安全上下文,以 root 身份输入以下命令:

    # firewall-cmd --list-lockdown-whitelist-contexts
    
  • 要在允许列表 添加上下文 context,以 root 身份输入以下命令:

    # firewall-cmd --add-lockdown-whitelist-context=context
    
  • 要从允许列表 删除上下文 context,以 root 身份输入以下命令:

    # firewall-cmd --remove-lockdown-whitelist-context=context
    
  • 要查询上下文 context 是否在允许列表中,以 root 身份输入以下命令:

    # firewall-cmd --query-lockdown-whitelist-context=context
    

    如果为 true,输出 yes,退出状态为 0,否则输出 1,退出状态为 no

  • 要列出允许列表中的所有用户 ID,以 root 身份输入以下命令:

    # firewall-cmd --list-lockdown-whitelist-uids
    
  • 要在允许列表中添加用户 ID uid,以 root 身份输入以下命令:

    # firewall-cmd --add-lockdown-whitelist-uid=uid
    
  • 要从允许列表中删除用户 ID uid,以 root 身份输入以下命令:

    # firewall-cmd --remove-lockdown-whitelist-uid=uid
    
  • 要查询用户 ID uid 是否在 allowlist 中,请输入以下命令:

    $ firewall-cmd --query-lockdown-whitelist-uid=uid
    

    如果为 true,输出 yes,退出状态为 0,否则输出 1,退出状态为 no

  • 要列出允许列表中的所有用户名,以 root 身份输入以下命令:

    # firewall-cmd --list-lockdown-whitelist-users
    
  • 要在允许列表中添加用户名 user,以 root 身份输入以下命令:

    # firewall-cmd --add-lockdown-whitelist-user=user
    
  • 要从允许列表中删除用户名 user,以 root 身份输入以下命令:

    # firewall-cmd --remove-lockdown-whitelist-user=user
    
  • 要查询用户名 user 是否在 allowlist 中,请输入以下命令:

    $ firewall-cmd --query-lockdown-whitelist-user=user
    

    如果为 true,输出 yes,退出状态为 0,否则输出 1,退出状态为 no

13.3 使用配置文件配置锁定的allowlist选项

默认allowlist配置文件包含NetworkManager上下文和 libvirt默认上下文。用户ID0 也位于列表中。

<?xml version="1.0" encoding="utf-8"?>
	<whitelist>
	  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
	  <selinux context="system_u:system_r:virtd_t:s0-s0:c0.c1023"/>
	  <user id="0"/>
	</whitelist>

以下是一个允许名单配置文件实例,为firewall-cmd 工具程序启用所有命令,对于一个名为 user,用户 ID 为 815 的用户:

<?xml version="1.0" encoding="utf-8"?>
	<whitelist>
	  <command name="/usr/libexec/platform-python -s /bin/firewall-cmd*"/>
	  <selinux context="system_u:system_r:NetworkManager_t:s0"/>
	  <user id="815"/>
	  <user name="user"/>
	</whitelist>

这个示例显示 user iduser name,但只需要一个选项。Python 是程序解释器,它位于命令行的前面。您还可以使用特定的命令,例如:

/usr/bin/python3 /bin/firewall-cmd --lockdown-on

在这个示例中,只允许 --lockdown-on 命令。

在 Red Hat Enterprise Linux 中,所有工具都放置在 /usr/bin/ 目录中, /bin/ 目录被符号链接到 /usr/bin/ 目录。换句话说,虽然作为 root 输入 firewall-cmd 的路径时,可能会解析为 /bin/firewall-cmd,但现在可以使用 /usr/bin/firewall-cmd。所有新脚本都应该使用新位置。但请注意,如果以 root 身份运行的脚本被写入来使用 /bin/firewall-cmd 路径,则必须在允许列表中添加该命令路径,除了通常用于非root 用户的 /usr/bin/firewall-cmd 路径外。

一个命令的 name 属性末尾的 * 意味着,所有以这个字符串开头的命令都匹配。如果没有 *,包括参数的绝对命令必须匹配。

posted @ 2021-11-21 14:30  知无不言~  阅读(914)  评论(0编辑  收藏  举报