安装和管理firewalld

1
2
3
4
5
6
7
8
9
# 安装firewalld
yum install firewalld firewall-config
systemctl start firewalld # 启动
systemctl status firewalld # 或者 firewall-cmd --state 查看状态
systemctl stop firewalld # 停止
systemctl enable firewalld # 开机自自动
systemctl disable firewalld # 取消自启动
systemctl list-unit-files | grep firewalld # 查看是否开机自启动

基础命令

一些常用的命令如下:

  • 查看防火墙状态
    命令: firewall-cmd --list-all
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    $ sudo firewall-cmd --list-all
    public (active)
    target: default
    icmp-block-inversion: no
    interfaces: ens33
    sources:
    services: ssh dhcpv6-client
    ports:
    protocols:
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:
    $
  • 列出支持的服务
    命令: firewall-cmd --get-services

    1
    2
    3
    $ sudo firewall-cmd --get-services
    RH-Satellite-6 amanda-client amanda-k5-client bacula bacula-client bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc ceph ceph-mon cfengine condor-collector ctdb dhcp dhcpv6 dhcpv6-client dns docker-registry docker-swarm dropbox-lansync elasticsearch 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 jenkins kadmin kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls managesieve mdns minidlna mongodb mosh mountd ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy proxy-dhcp ptp pulseaudio puppetmaster quassel radius redis rpc-bind rsh rsyncd samba samba-client sane sip sips smtp smtp-submission smtps snmp snmptrap spideroak-lansync squid ssh syncthing syncthing-gui synergy syslog syslog-tls telnet tftp tftp-client tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-https xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server
    $
  • 添加某个服务
    命令: firewall-cmd --add-service=<service> --permanent

    1
    sudo firewall-cmd --add-service=http --permanent
  • 删除某个服务
    命令: firewall-cmd --remove-service=<service> --permanent

    1
    sudo firewall-cmd --remove-service=dhcpv6-client --permanent
  • 添加某个端口
    命令: firewall-cmd --add-port=<portid>[-<portid>]/<protocol> --permanent

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    # 添加rtmp端口
    $ sudo firewall-cmd --add-port=1935/tcp --permanent
    $ sudo firewall-cmd --reload
    $ sudo firewall-cmd --list-all
    public (active)
    target: default
    icmp-block-inversion: no
    interfaces: ens33
    sources:
    services: ssh dhcpv6-client http
    ports: 1935/tcp
    protocols:
    masquerade: no
    forward-ports:
    source-ports:
    icmp-blocks:
    rich rules:
    $
  • 删除某个端口
    命令: firewall-cmd --remove-port=<portid>[-<portid>]/<protocol> --permanent

  • 重启防火墙
    添加或删除服务和端口后,需要重新load防火墙,才能生效
    命令: firewall-cmd --reload

    1
    sudo firewall-cmd --reload

permanent参数

规则添加命令中--permanent参数的说明:

  • 不添加--permanent, 表示规则是临时的,对当前系统即时生效。重启防火墙服务后不会保留该规则。
  • 添加--permanent, 表示规则永久写入,但是不对当前环境生效,需要firewall-cmd --reload后才能生效。

命令firewall-cmd --list-all查看的是当前有效的规则。所以如果只添加了--permanent,但没有firewall-cmd --reload,因为规则未生效,所以不会在firewall-cmd --list-all的输出中出现。

自定义service文件

service文件介绍

firewalld内置了一些常用的services,对应的配置文件保存在/usr/lib/firewalld/services中,使用命令firewall-cmd --add-service=<service>可以很方便地添加这些服务。

很多情况下,我们要开放的端口不在这些预定义的服务中,此时有两个办法来实现

  1. 使用--add-port=<portid>[-<portid>]/<protocol>来直接添加端口
  2. 自建services配置文件,并添加到firewalld中

推荐使用自建services的方式,使用services方式的优点

  • 一个配置文件对应一个服务,更清晰
  • 配置文件中,可以添加服务描述
  • 配置文件中,可以添加多个端口和协议,如预置的rsyncd.xml中,就同时添加了873端口的TCP和UDP协议。

自建service文件

firewalld用到的所有service配置文件的存放路径是/usr/lib/firewalld/services,但自建的service文件不要直接写入该目录,而应该在/etc/firewalld/services/中进行设置。

下面是一个root下新建rtmp service的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 拷贝/usr/lib/firewalld/services/ssh.xml文件到/etc/firewalld/services/中,命名为rtmp.xml
cp /usr/lib/firewalld/services/ssh.xml /etc/firewalld/services/rtmp.xml
# 修改/etc/firewalld/services/rtmp.xml为如下内容
<?xml version="1.0" encoding="utf-8"?>
<service>
<short>RTMP</short>
<description>Allow RTMP Streaming.</description>
<port protocol="tcp" port="1935"/>
</service>
# 重新reload firewalld
firewall-cmd --reload
# 重新查看可用的firewall service
firewall-cmd --get-services
# 添加服务
firewall-cmd --add-service=rtmp --permanent
# 重新reload firewalld
firewall-cmd --reload
# 查看防火墙状态,看rtmp是否已成功添加
firewall-cmd --list-all

端口转发

转发到本地

命令: firewall-cmd --add-forward-port=port=<portid>[-<portid>]:proto=<protocol>[:toport=<portid>[-<portid>]][:toaddr=<address>[/<mask>]]
例子: 转发80端口流量到12345端口

1
sudo firewall-cmd --zone="public" --add-forward-port=port=80:proto=tcp:toport=12345

转发到其他机器

转发到其他机器时,需要开启masquerade(伪装)功能。

Masquerading will forward packets that are not directed to an IP address associated to the system itself onto the intended destination. The source IP address of the packets that are sent through our system will be changed to the IP address of our system, rather than the IP address of the original traffic source. Responses to these packets will then go through our system and the destination address will be modified so that the traffic will be sent back to the original host that initiated the traffic.

使用firewall-cmd --add-masquerade开启masquerade。
例子: 转发本地80端口到IP 10.0.0.2上的8080端口中

1
sudo firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080:toaddr=10.0.0.2

Rich rules细粒度控制

FirewallD的Rich rules 可以提供更细粒度的控制。可以使用man 5 firewalld.richlanguage来查看rich rules的语法,

例子:

允许来自192.168.0.14的所有IPv4流量

1
sudo firewall-cmd --add-rich-rule 'rule family="ipv4" source address=192.168.0.14 accept'

拒绝来自192.168.1.10的基于TCP的请求访问22端口, 也就是拒绝192.168.1.10进行ssh

1
sudo firewall-cmd --add-rich-rule 'rule family="ipv4" source address="192.168.1.10" port port=22 protocol=tcp reject'

只允许来自192.168.187.128/25的请求访问22端口,拒绝其余的ssh登录

1
2
sudo firewall-cmd --remove-service=ssh
sudo firewall-cmd --add-rich-rule="rule family="ipv4" source address="192.168.187.128/25" service name="ssh" accept" --permanent

允许来自10.1.0.3的TCP请求到80端口,并且转发到本地的6532端口。

1
sudo firewall-cmd --add-rich-rule 'rule family=ipv4 source address=10.1.0.3 forward-port port=80 protocol=tcp to-port=6532'

将来自172.31.4.2的访问80端口的TCP请求转发到主机172.31.4.2的8080端口。

1
2
sudo firewall-cmd --add-masquerade
sudo firewall-cmd --add-rich-rule 'rule family=ipv4 forward-port port=80 protocol=tcp to-port=8080 to-addr=172.31.4.2'

列出所有的rich rules

1
sudo firewall-cmd --list-rich-rules

firewall系列命令介绍

转载自: firewall防火墙

  1. 查看firewalld的状态

    1
    firewall-cmd --state
  2. 查看活动分区类别

    1
    firewall-cmd --get-active-zones
  3. 查看当前分配的接口

    1
    firewall-cmd --get-zone-of-interface=ens33
  4. 查看分配的区域的所有接口:

    1
    firewall-cmd --zone=public --list-interfaces
  5. 找出公共区域的所有设置

    1
    2
    firewall-cmd --zone=public --list-all
    firewall-cmd --list-all
  6. 关闭|开启所有的输入和输出的数据包(禁用)

    1
    2
    3
    4
    5
    6
    # 关闭所有输入输出的数据包
    firewall-cmd --panic-on
    # 开启再次输入输出的数据包
    firewall-cmd --panic-off
    # 查看panic模式的状态(yes启用 no退出)
    firewall-cmd --query-panic
  7. 重新加载防火墙

    1
    2
    3
    4
    # 重新加载防火墙,不中断用户连接(不丢失状态信息)
    firewall-cmd --reload
    # 重新加载防火墙并中断用户连接(丢失状态信息),防火墙出现严重问题才执行
    firewall-cmd --complete-reload
  8. 为分区增加接口

    1
    2
    # 把em1增加到公共分区,增加--permanent选择并重新加载防火墙,是之永久生效
    firewall-cmd --zone=public --add-interface=em1
  9. 设置分区(将一个端口加入分区)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 设置默认分区,立即生效,不需要重新加载防火墙
    firewall-cmd --set-default-zone=public
    # 将一个端口加入分区
    firewall-cmd --zone=public --permanent --add-port=8080/tcp
    firewall-cmd --reload
    # 查看开发的端口
    firewall-cmd --zone=public --list-ports
    # 删除
    firewll-cmd --zone=pubic --remove --remove-port=8080/tcp
  10. 将一个服务(http)加入到分区

    1
    2
    3
    4
    5
    6
    7
    # 加入
    firewall-cmd --permanent --zone=work --add-service=http
    firewall-cmd --reload
    # 移除
    firewall-cmd --permanent --zone=work --remove-service=http
    firewall-cmd --reload
    # 注意,这并不会中断已经建立的连接。如果您打算中断,您可以使用 --complete-reload 选项,但这不仅仅中断您已经移除的服务,还会中断所有已经建立的连接。
  11. 配置伪装 IP 地址

    1
    2
    3
    4
    5
    6
    # 查询是否可用
    firewall-cmd --zone=external --query-masquerade
    # 允许伪装IP
    firewall-cmd --zone=external --add-masquerade
    # 禁用伪装IP
    firewall-cmd --zone=external --remove-masquerade
  12. 配置端口转发,地址转发

    1
    2
    3
    4
    5
    6
    7
    # 将22端口转发到3753端口,使用tcp协议
    firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753
    # 原本发往22端口的程序包现在被转发到地址是192.0.2.55下相同的端口
    firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toaddr=192.0.2.55
    # 将22端口的数据包转发到192.0.2.55下的2055端口
    firewall-cmd --zone=external /
    --add-forward-port=port=22:proto=tcp:toport=2055:toaddr=192.0.2.55
  13. 使用直接接口增加一个自定义规则

    1
    2
    3
    4
    5
    6
    7
    8
    # 增加一个自定义规则到 “IN_public_allow” 链里:
    firewall-cmd --direct --add-rule ipv4 filter IN_public_allow \
    0 -m tcp -p tcp --dport 666 -j ACCEPT
    # 从 “IN_public_allow” 链移除一个自定义规则:
    firewall-cmd --direct --remove-rule ipv4 filter IN_public_allow \
    0 -m tcp -p tcp --dport 666 -j ACCEPT
    # 列出 “IN_public_allow” 链中的规则:
    firewall-cmd --direct --get-rules ipv4 filter IN_public_allow
  14. 配置rich language语法
    格式:

    1
    2
    3
    4
    5
    6
    # 添加
    firewall-cmd [--zone=zone] --add-rich-rule='rule' [--timeout 9=seconds]
    # 移除
    firewall-cmd [--zone=zone] --remove-rich-rule='rule'
    # 检查是否存在
    firewall-cmd [--zone=zone] --query-rich-rule='rule'

多规则结构:

1
2
3
4
5
6
7
rule [family="<rule family>"]
[ source address="<address>" [invert="True"] ]
[ destination address="<address>" [invert="True"] ]
[ <element> ]
[ log [prefix="<prefix text>"] [level="<log level>"] [limit value="rate/duration"] ]
[ audit ]
[ accept|reject|drop ]

多规则命令:

1
2
3
4
5
6
7
8
9
source:指定源地址,不支持使用主机名。可以通过增加 invert="true" 或 invert="yes" 来颠倒源地址命令的意思。所有提供的地址都匹配。
destination:通过制定目的地址,目标可以被限制在目的地址中。
service:服务名称是 firewalld 提供的其中一种服务。可以通过 firewall-cmd --get-services查看。格式: service name=service_name
port: 端口,可为范围或者独立数字 格式:port port=number_or_range protocol=protocol
protocol:协议
icmp-block:用这个命令阻绝一个或多个 ICMP 类型,查看支持的icmp类型列表:firewall-cmd --get-icmptypes,格式: icmp-block name=icmptype_name
masquerade:打开规则里的 IP 伪装。用源地址而不是目的地址来把伪装限制在这个区域内。在此,指定一个动作是不被允许的。
forward-port:从一个带有指定为 tcp 或 udp 协议的本地端口转发数据包到另一个本地端口,或另一台机器,或另一台机器上的另一个端口.格式:forward-port port=number_or_range protocol=protocol /
to-port=number_or_range to-addr=address

运行来自主机192.168.1.3的所有IPv4流量

1
firewall-cmd --zone=public --add-rich-rule="rule family='ipv4' source address=192.168.1.3 accept"

拒绝来自主机192.168.1.4到22端口的tcp流量

1
firewall-cmd --zone=public --add-rich-rule 'rule family="ipv4" source address=192.168.1.4 port port=22 protocol=tcp reject'

允许主机10.1.0.3到80端口的IPv4的TCP流量,并转发到65530端口上

1
firewall-cmd --zone=public --add-rich-rule 'rule family=ipv4 source address=10.1.0.3 forward-port port=80 protocol=tcp to-port=65530'

Reference

留言