Linux-firewall-cmd

firewalld简介

Redhat Enterprise Linux7开始默认使用firewalld作为防火墙,基于iptables的防火墙被默认不启动,但仍然保留下来。
The dynamic firewall daemon firewalld provides a dynamically managed firewall with support for network “zones” to assign a level of trust to a network and its associated connections and interfaces. It has support for IPv4 and IPv6 firewall settings. It supports Ethernet bridges and has a separation of runtime and permanent configuration options. It also has an interface for services or applications to add firewall rules directly.

The configuration for firewalld is stored in various XML files in /usr/lib/firewalld/ and /etc/firewalld/. This allows a great deal of flexibility as the files can be edited, written to, backed up, used as templates for other installations and so on.

Other applications can communicate with firewalld using D-bus.

参考:4.5. USING FIREWALLS

Understanding Network Zones

Firewalls can be used to separate networks into different zones based on the level of trust the user has decided to place on the devices and traffic within that network. NetworkManager informs firewalld to which zone an interface belongs. An interface’s assigned zone can be changed by NetworkManager or via the firewall-config tool which can open the relevant NetworkManager window for you.
The zone settings in /etc/firewalld/ are a range of preset settings which can be quickly applied to a network interface. They are listed here with a brief explanation:

  • drop
    Any incoming network packets are dropped, there is no reply. Only outgoing network connections are possible.
  • block
    Any incoming network connections are rejected with an icmp-host-prohibited message for IPv4 and icmp6-adm-prohibited for IPv6. Only network connections initiated from within the system are possible.
  • public
    For use in public areas. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.
  • external
    For use on external networks with masquerading enabled especially for routers. You do not trust the other computers on the network to not harm your computer. Only selected incoming connections are accepted.
  • dmz
    For computers in your demilitarized zone that are publicly-accessible with limited access to your internal network. Only selected incoming connections are accepted.
  • work
    For use in work areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.
  • home
    For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.
  • internal
    For use on internal networks. You mostly trust the other computers on the networks to not harm your computer. Only selected incoming connections are accepted.
  • trusted
    All network connections are accepted.

It is possible to designate one of these zones to be the default zone. When interface connections are added to NetworkManager, they are assigned to the default zone. On installation, the default zone in firewalld is set to be the public zone.

安装firewalld

#
yum install -y firewalld firewall-config
systemctl disable firewalld
systemctl stop firewalld
systemctl start firewalld
systemctl status firewalld
#或者
firewall-cmd --state

Configuring the Firewall

firewall-cmd随firewalld安装,查看版本:

$
firewall-cmd --version

查看帮助:

$
firewall-cmd --help

使用 man firewall-cmd 查看更多。

NOTE
In order to make a command permanent or persistent, add the –permanent option to all commands apart from the –direct commands (which are by their nature temporary). Note that this not only means the change will be permanent but that the change will only take effect after firewall reload, service restart, or after system reboot. Settings made with firewall-cmd without the –permanent option take effect immediately, but are only valid till next firewall reload, system boot, or firewalld service restart. Reloading the firewall does not in itself break connections, but be aware you are discarding temporary changes by doing so.

查看Firewall配置

To get a text display of the state of firewalld, enter the following command:

$
firewall-cmd --state

To view the list of active zones, with a list of the interfaces currently assigned to them, enter the following command:

$
firewall-cmd --get-active-zones
public
interfaces: em1

To find out the zone that an interface, for example em1, is currently assigned to, enter the following command:

$
firewall-cmd --get-zone-of-interface=em1
public

To find out all the interfaces assigned to a zone, for example the public zone, enter the following command as root:

#
firewall-cmd --zone=public --list-interfaces
em1 wlan0

This information is obtained from NetworkManager and only shows interfaces, not connections.
To find out all the settings of a zone, for example the public zone, enter the following command as root:

#
firewall-cmd --zone=public --list-all
public
interfaces:
services: mdns dhcpv6-client ssh
ports:
forward-ports:
icmp-blocks: source-quench

To view the list of services currently loaded, enter the following command as root:

#
firewall-cmd --get-services
cluster-suite pop3s bacula-client smtp ipp radius bacula ftp mdns samba dhcpv6-client dns openvpn imaps samba-client http https ntp vnc-server telnet libvirt ssh ipsec ipp-client amanda-client tftp-client nfs tftp libvirt-tls

This will list the names of the predefined services loaded from /usr/lib/firewalld/services/ as well as any custom services that are currently loaded. Note that the configuration files themselves are named service-name.xml.
If custom services have been created but not loaded, they can be listed as follows:

#
firewall-cmd --permanent --get-services

This will list all services, including custom services configured in /etc/firewalld/services/, even if they are not yet loaded.

Change the Firewall Settings

  • Drop All Packets (Panic Mode)

    #
    firewall-cmd --panic-on
    firewall-cmd --panic-off
    firewall-cmd --query-panic
  • Reload the Firewall

    #
    firewall-cmd --reload
    firewall-cmd --complete-reload
  • 添加Interface到Zone

    #
    firewall-cmd --zone=public --add-interface=em1
    #To make this setting permanent, add the --permanent option and reload the firewall.
  • 配置 Default Zone
    As root, open /etc/firewalld/firewalld.conf and edit the file as follows:

     # default zone
    # The default zone used if an empty zone string is used.
    # Default: public
    DefaultZone=home

    #Reload the firewall, This will reload the firewall without losing state information (TCP sessions will not be interrupted).
    firewall-cmd --reload
  • 设置 Default Zone

    #
    firewall-cmd --set-default-zone=public
  • 打开 Ports
    List all open ports for a zone, for example dmz, by entering the following command as root:

    #
    firewall-cmd --zone=public --list-ports
    #Note that this will not show ports opened as a result of the --add-services command.

To add a port to a zone, for example to allow TCP traffic to port 8080 to the dmz zone:

#
firewall-cmd --zone=public --add-port=8080/tcp
#To make this setting permanent, add the --permanent option and reload the firewall.

To add a range of ports to a zone, for example to allow the ports from 5060 to 5061 to the public zone, enter the following command as root:

#
firewall-cmd --zone=public --add-port=5060-5061/udp

  • 添加服务到 Zone
    To add a service to a zone, for example to allow SMTP to the work zone, enter the following command as root:
    #
    firewall-cmd --zone=work --add-service=smtp

To make this setting permanent, add the –permanent option and reload the firewall.

  • 从Zone中删除服务
    To remove a service from a zone, for example to remove SMTP from the work zone:
    #
    firewall-cmd --zone=work --remove-service=smtp

Add the –permanent option to make the change persist after system boot. If using this option and you wish to make the change immediate, reload the firewall, by entering the following command as root:

#
firewall-cmd --reload

Note, this will not break established connections. If that is your intention, you could use the –complete-reload option but this will break all established connections not just for the service you have removed.

  • Configure IP Address Masquerading
    To check if IP masquerading is enabled, for example for the external zone, enter the following command as root:
    #
    firewall-cmd --zone=external --query-masquerade

Prints yes with exit status 0, if enabled, prints no with exit status 1 otherwise. If zone is omitted, the default zone will be used.
To enable IP masquerading, enter the following command as root:

#
firewall-cmd --zone=external --add-masquerade

To make this setting permanent, add the –permanent option and reload the firewall.
To disable IP masquerading, enter the following command as root:

#
firewall-cmd --zone=external --remove-masquerade

To make this setting permanent, add the –permanent option and reload the firewall.

  • 配置 Port Forwarding
    To forward inbound network packets from one port to an alternative port or address, first enable IP address masquerading for a zone, for example external, by entering the following command as root:
    #
    firewall-cmd --zone=external --add-masquerade

To forward packets to a local port, that is to say to a port on the same system, enter the following command as root:

#
firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753

In this example, the packets intended for port 22 are now forwarded to port 3753. The original destination port is specified with the port option. This option can be a port, or port range, together with a protocol. The protocol, if specified, must be one of either tcp or udp. The new local port, the port or range of ports to which the traffic is being forwarded to, is specified with the toport option. To make this setting permanent, add the –permanent option and reload the firewall.
To forward packets to another IPv4 address, usually an internal address, without changing the destination port, enter the following command as root:

#
firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toaddr=192.0.2.55

In this example, the packets intended for port 22 are now forwarded to the same port at the address given with the toaddr. The original destination port is specified with the port. This option can be a port, or port range, together with a protocol. The protocol, if specified, must be one of either tcp or udp. The new destination port, the port or range of ports to which the traffic is being forwarded to, is specified with the toport. To make this setting permanent, add the –permanent option and reload the firewall.
To forward packets to another port at another IPv4 address, usually an internal address, enter the following command as root:

#
firewall-cmd --zone=external /
--add-forward-port=port=22:proto=tcp:toport=2055:toaddr=192.0.2.55

In this example, the packets intended for port 22 are now forwarded to port 2055 at the address given with the toaddr option. The original destination port is specified with the port option. This option can be a port, or port range, together with a protocol. The protocol, if specified, must be one of either tcp or udp. The new destination port, the port or range of ports to which the traffic is being forwarded to, is specified with the toport. To make this setting permanent, add the –permanent option and reload the firewall.

Using the Direct Interface

It is possible to add and remove chains during runtime by using the –direct option with the firewall-cmd tool. A few examples are presented here, see the firewall-cmd(1) man page for more information.
It is dangerous to use the direct interface if you are not very familiar with iptables as you could inadvertently cause a breach in the firewall.
The direct interface mode is intended for services or applications to add specific firewall rules during runtime. The rules can be made permanent by adding the –permanent option using the firewall-cmd –permanent –direct command or by modifying /etc/firewalld/direct.xml. See man firewalld.direct(5) for information on the /etc/firewalld/direct.xml file.

  • Adding a Custom Rule Using the Direct Interface

To add a custom rule to the chain “IN_public_allow”, issuing a command as root in the following format:

#
firewall-cmd --direct --add-rule ipv4 filter IN_public_allow \
0 -m tcp -p tcp --dport 666 -j ACCEPT

Add the –permanent option if you want to make it persistent.

  • Removing a Custom Rule Using the Direct Interface

To remove a custom rule from the chain “IN_public_allow”, issuing a command as root in the following format:

#
firewall-cmd --direct --remove-rule ipv4 filter IN_public_allow \
0 -m tcp -p tcp --dport 666 -j ACCEPT

Add the –permanent option if you want to make it persistent.

  • Listing Custom Rules Using the Direct Interface

To list the rules in the chain “IN_public_allow”, issuing a command as root in the following format:

#
firewall-cmd --direct --get-rules ipv4 filter IN_public_allow

Firewall Lockdown

Local applications or services are able to change the firewall configuration if they are running as root (for example, libvirt). With this feature, the administrator can lock the firewall configuration so that either no applications, or only applications that are added to the lockdown whitelist, are able to request firewall changes. The lockdown settings default to disabled. If enabled, the user can be sure that there are no unwanted configuration changes made to the firewall by local applications or services.

  • Configuring Firewall Lockdown

Using an editor running as root, add the following line to the /etc/firewalld/firewalld.conf file as follows:
Lockdown=yes
Reload the firewall using the following command as root:

#
firewall-cmd --reload

Try to enable the service imaps in the default zone using the following command as an administrative user, that is to say, a user in group wheel (usually the first user on system). You will be prompted for the user password:

$
firewall-cmd --add-service=imaps
Error: ACCESS_DENIED: lockdown is enabled

To enable the use of firewall-cmd, issue the following command as root:

#
firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/firewall-cmd*'

Add the –permanent option if you want to make it persistent.
Reload the firewall as root:

#
firewall-cmd --reload

Try to enable the imaps service again in the default zone by entering the following command as an administrative user. You will be prompted for the user password:

$
firewall-cmd --add-service=imaps

This time the command succeeds.

  • Configure Lockdown with the Command Line Client

To query whether lockdown is enabled, enter the following command as root:

#
firewall-cmd --query-lockdown

Prints yes with exit status 0, if lockdown is enabled, prints no with exit status 1 otherwise.
To enable lockdown, enter the following command as root:

#
firewall-cmd --lockdown-on

To disable lockdown, enter the following command as root:

#
firewall-cmd --lockdown-off

  • Configure Lockdown Whitelist Options with the Command Line

The lockdown whitelist can contain commands, security contexts, users and user IDs. If a command entry on the whitelist ends with an asterisk “”, then all command lines starting with that command will match. If the “” is not there then the absolute command including arguments must match.
The context is the security (SELinux) context of a running application or service. To get the context of a running application use the following command:

$
ps -e --context

That command returns all running applications. Pipe the output through the grep tool to get the application of interest. For example:

$
ps -e --context | grep example_program

To list all command lines that are on the whitelist, enter the following command as root:

# firewall-cmd --list-lockdown-whitelist-commands

To add a command command to the whitelist, enter the following command as root:

# firewall-cmd --add-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command'

To remove a command command from the whitelist, enter the following command as root:

# firewall-cmd --remove-lockdown-whitelist-command='/usr/bin/python -Es /usr/bin/command'

To query whether the command command is on the whitelist, enter the following command as root:

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

Prints yes with exit status 0, if true, prints no with exit status 1 otherwise.
To list all security contexts that are on the whitelist, enter the following command as root:

# firewall-cmd --list-lockdown-whitelist-contexts

To add a context context to the whitelist, enter the following command as root:

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

Add the –permanent option to make it persistent.
To remove a context context from the whitelist, enter the following command as root:

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

Add the –permanent option to make it persistent.
To query whether the context context is on the whitelist, enter the following command root:

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

Prints yes with exit status 0, if true, prints no with exit status 1 otherwise.
To list all user IDs that are on the whitelist, enter the following command as root:

# firewall-cmd --list-lockdown-whitelist-uids

To add a user ID uid to the whitelist, enter the following command as root:

# firewall-cmd --add-lockdown-whitelist-uid=uid

Add the –permanent option to make it persistent.
To remove a user ID uid from the whitelist, enter the following command as root:

# firewall-cmd --remove-lockdown-whitelist-uid=uid

Add the –permanent option to make it persistent.
To query whether the user ID uid is on the whitelist, enter the following command:

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

Prints yes with exit status 0, if true, prints no with exit status 1 otherwise.
To list all user names that are on the whitelist, enter the following command as root:

# firewall-cmd --list-lockdown-whitelist-users

To add a user name user to the whitelist, enter the following command as root:

# firewall-cmd --add-lockdown-whitelist-user=user

Add the –permanent option to make it persistent.
To remove a user name user from the whitelist, enter the following command as root:

# firewall-cmd --remove-lockdown-whitelist-user=user

Add the –permanent option to make it persistent.
To query whether the user name user is on the whitelist, enter the following command:

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

Prints yes with exit status 0, if true, prints no with exit status 1 otherwise.