如何使用 firewall-cmd 管理网络服务
防火墙
![](/data/attachment/album/202006/03/090806hcmc9cxcbbcuccbe.jpg)


在上一篇文章中，我们探讨了如何在 Fedora 中[用命令行控制防火墙](/article-12103-1.html)。


现在你将看到如何“添加”、“删除”和“列出”服务、协议和端口，以便“阻止”或“允许”它们。


### 简短回顾


首先，最好检查一下防火墙的*状态*，看它是否正在运行。如我们先前所学，你可以使用状态选项（`firewall-cmd ‐‐state`）来得到。


下一步是获取网络接口适用的<ruby> 域 <rt>  zone </rt></ruby>。例如，我使用的桌面有两个网络接口：一个*物理*接口（`enp0s3`），代表我实际的*网卡*，和*虚拟*接口（`virbr0`），它由 KVM 等虚拟化软件使用。要查看哪些域处于活动状态，请运行 `firewall-cmd ‐‐get-active-zones`。


现在，你知道了你感兴趣的域，可以使用 `firewall-cmd ‐‐info-zone=FedoraWorkstation` 这样的命令列出该域的规则。


### 读取区域信息


要显示*特定域*的信息，请运行 `firewall-cmd ‐‐zone=ZoneName ‐‐list-all`，或使用以下命令显示默认域的信息：



```
[dan@localhost ~]$ firewall-cmd --list-all
FedoraWorkstation (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: dhcpv6-client mdns samba-client ssh
ports: 1025-65535/udp 1025-65535/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
```

现在，让我们查看输出。第一行表明以下信息关联的域以及该域当前是否在使用中。


`target: default`：告诉我们这是默认域。可以通过 `‐‐set-default-zone=ZoneName` 和 `‐‐get-default-zone` 设置或获取。


`icmp-block-inversion` 表明是否阻止 [ICMP](https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol) 请求。例如，如果机器响应来自网络上其他机器的 ping 请求。


`interfaces` 字段显示接受此域的所有接口。


### 处理服务、端口和协议


现在，重点关注 `services`、`ports` 和 `protocols` 所在行。默认情况下，防火墙将阻止所有端口、服务和协议，而只允许列出的。


在这里，你可以看到允许的服务是非常基本的客户端服务。例如，访问网络上的共享文件夹（`samba-client`）、与 DNS 服务器通信或通过 SSH（`ssh` 服务）连接到计算机。你可以将 `service` 视为与端口组合的协议，例如 `ssh` 服务使用 SSH 协议，并且按照惯例使用 22 端口。通过允许 `ssh` 服务，你实际上所做的就是允许传入的连接在默认 22 端口上使用 SSH 协议。


请注意，根据经验，名称中带有 `client` 字样的服务是指传出连接，也就是你使用你的 IP 作为源对外部的*连接*，与之相反的是 `ssh` 服务，比如，它将接受传入连接（监听来自外部的连接）。


你可以在文件 `/etc/services` 中查找服务。例如，如果你想知道这些服务使用什么端口和协议：



```
[dan@localhost ~]$ cat /etc/services | grep ssh
ssh 22/tcp # The Secure Shell (SSH) Protocol
ssh 22/udp # The Secure Shell (SSH) Protocol
```

你可以看到 SSH 同时使用 TCP 和 UDP 的 22 端口。此外，如果你希望查看所有可用的服务，只需使用 `firewall-cmd --get-services`。


#### 打开端口


如果要阻止端口、服务或协议，请确保在此处未列出它们。展开来说，如果要允许服务，那么需要将它添加到列表中。


假设你要打开 `5000` 端口用于 TCP 连接。为此，请运行：



```
sudo firewall-cmd --zone=FedorwaWorkstation --permanent --add-port=5000/tcp
```

请注意，你需要指定规则适用的域。添加规则时，还需要如上指定它是 `tcp` 还是 `udp` 端口。`--permanent` 参数将规则设置为即使系统重启后也可以保留。


再次查看你所在区域的信息：



```
[dan@localhost ~]$ firewall-cmd --list-all
FedoraWorkstation (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources:
services: dhcpv6-client mdns samba-client ssh
ports: 1025-65535/udp 1025-65535/tcp 5000/tcp
protocols:
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
```

类似地，如果你想从列表删除该端口，请运行：



```
sudo firewall-cmd --zone=FedorwaWorkstation --permanent --remove-port=5000/tcp
```

相同的 `remove` （`‐‐remove-protocol`、`‐‐remove-service`） 和 `add`（`‐‐add-protocol`、`‐‐add-service`）选项同样适用于*服务*和*协议*。




---


via: <https://fedoramagazine.org/how-to-manage-network-services-with-firewall-cmd/>


作者：[dan01](https://fedoramagazine.org/author/dan01/) 选题：[lujun9972](https://github.com/lujun9972) 译者：[geekpi](https://github.com/geekpi) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出


OK
In a previous article, you explored how to [control the firewall at the command line](https://fedoramagazine.org/control-the-firewall-at-the-command-line/) in Fedora.

Now you are going to see how to see how *add*, *remove*, and *list* *services*, *protocols* and *ports* in order to *block* or *allow* them.

## A short recap

First, it’s a good idea to check the *status* of your firewall, see if it’s running or not. You do this, as we previously learned, by using the state option (*firewall-cmd *‐‐*state*).

The next step is to get the zone for the desired network interface. For example, I use a desktop that has two network interfaces: a *physical* interface (*enp0s3*), representing my actual *network card* and a *virtual* interface (*virbr0*) used by virtualization software like *KVM*. To see what zones are active, run *firewall-cmd ‐‐get-active-zones*.

Now that you know what zone you’re interested in, you can list the rules for the zone with *firewall-cmd ‐‐info-zone=FedoraWorkstation*.

## Reading zone information

To display information for a particular *zone*, run *firewall-cmd ‐‐zone=ZoneName ‐‐list-all*, or simply display information for the default zone with:

[dan@localhost ~]$ firewall-cmd --list-all

FedoraWorkstation (active)

target: default

icmp-block-inversion: no

interfaces: enp0s3

sources:

services: dhcpv6-client mdns samba-client ssh

ports: 1025-65535/udp 1025-65535/tcp

protocols:

masquerade: no

forward-ports:

source-ports:

icmp-blocks:

rich rules:

Now, let’s explore the output. The first line is showing which *zone* the following information applies to and if that zone is currently in use.

The *target* : *default* simply tells us this is the default zone. This can be set or retrieved via the *‐‐set-default-zone=ZoneName* and *‐‐get-default-zone*.

*icmp-block-inversion*, indicates if [ICMP](https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol) requests are blocked. For example if the machine responds to *ping* requests from other machines on the network. The *interfaces* field shows all interfaces that adopt this zone.

## Handling services, ports, and protocols

Now focus on the *services*, *ports*, and *protocols* rows. By default, the firewall will block all ports, services and protocols. Only the listed ones will be allowed.

You can see the allowed services are very basic client services in this case. For example, accessing a shared folder on the network (*samba-client*), to talk to a *DNS* server or connect to a machine via SSH (the *ssh* service). You can think of a *service *as a protocol in combination to a port, for instance the ssh service is using the SSH protocol and, by convention, port 22. By allowing the ssh service, what you’re really doing is allowing incoming connections that use the ssh protocol at default port 22.

Notice, services that have the *client* word in their name, as a rule of thumb, refer to outgoing connections, i.e. *connections *that you make with your IP as source going to the outside, as opposed to the SSH* *service, for example, that will accept incoming connections (listening to connection coming from outside at you).

You can look up services in the file */etc/services*. For example if you wish to know what port and protocol these service uses:

[dan@localhost ~]$ cat /etc/services | grep ssh

ssh 22/tcp # The Secure Shell (SSH) Protocol

ssh 22/udp # The Secure Shell (SSH) Protocol

You can see SSH uses both TCP and UDP port 22. Also, if you wish to see all available services, just use *firewall-cmd ‐‐get-services*.

### Opening a port

If you want to block a port, service, or protocol, all you have to do if make sure it’s not listed here. By extension, if you want to allow a service, you need add it to your list.

Let’s say you want to open the port *5000* for *TCP*** **connection. To do this, run:

sudo firewall-cmd --zone=FedorwaWorkstation --permanent --add-port=5000/tcp

Notice that you need to specify the zone for which the rule applies. When you add the rule, you also need to specify if it is a *TCP* or *UDP* port via as indicated above. The *permanent* parameter sets the rule to persist even after a system reboot.

Look at the information for your zone again:

[dan@localhost ~]$ firewall-cmd --list-all FedoraWorkstation (active) target: default icmp-block-inversion: no interfaces: enp0s3 sources: services: dhcpv6-client mdns samba-client ssh ports: 1025-65535/udp 1025-65535/tcp 5000/tcp protocols: masquerade: no forward-ports: source-ports: icmp-blocks: rich rules:

Similarly, if you wish to remove this port from the list, run:

sudo firewall-cmd --zone=FedorwaWorkstation --permanent --remove-port=5000/tcp

The very same *remove* (*‐‐remove-protocol*,* ‐‐remove-service*) and *add* (*‐‐add-protocol*,* ‐‐add-service*) options are also available for *services* and *protocols*.

## Jack

You seriously should delete this google+ button from top right corner 🙂

## Joao Rodrigues

If you use the –permanent, your rules won’t be applied until you do a firewall-cmd –reload or until you reboot.

Also, there’s a couple of typos.

It’s written fedorwa instead of fedora

## dan01

Good remark! And thanks for the observation, I’ll see what I can to correct that!

## Steven

Being able to create your own service definitions and applying those to specific zones and interfaces is also super useful.

## Jordan

Nice job, I need to learn more about this.

## dan01

Thank you! Means much to me! I know it’s a bit repetitive to what was written in part one, maybe should have covered also how to deal with custom services.

## Giovanni Fabbro

So I noticed that Fedora 33 is going to be using systemd-resolved by default too.

Great, but can we standardize on systemd-swap as well? Swap partitions seem to be wasteful and outdated at this point in time. Isn’t there security improvements having it as a file on an encrypted filesystem vs a standalone partition (does LUKS do this automatically?)? And shouldn’t it be more economical on resources with the EarlyOOM improvements?

## Muhammad Nabeel

Nice job, I need to learn more about this.Thank alot i hope you update upto time

## MF

One thing I have been missing in firewalld is the ability to add private services from e.g. rpm packages.

Assume that I have a exampled.rpm which contains a server listening on the “example” port, upon installation of that I would like to be able to register the “example” service in firewalld, how would I go about doing that?

## dan01

Good question! I think that by simply opening the correct port and protocol, it would become neutral or agnostic in regards to what you are running. In other words you could run http server X or server Y as long as they operate on same port/protocol and that’s set up in the firewall you can exchange them with no problem.

Now you could also create your custom service myHttpServer and deal with that level of abstractin if so wish.

Hope it helps

## Steven

You can easily create your own custom services by adding them at the command line with firewall-cmd and leverage the –new-service (I’d just inject all of the ports/description/etc, and then do a –runtime-to-permanent call).

Or you can write the file in your favorite text editor, and then call firewall-cmd –new-service-from-file.

Or you can write the definition straight to: /etc/firewalld/services/${YOUR_SERVICE}.xml, and then firewall-cmd –add-service=${YOUR_SERVICE}

## Joao Rodrigues

Let’s say your example service listens on ports 666/tcp and 999/udp:

Create a file called /etc/firewalld/services/example-service.xml with the contents:

Example Service

A longer description where you explain what the example service is and what it does

Then you can register the example service like this:

firewall-cmd –permanent –add-service=example-service

firewall-cmd –reload

## Joao Rodrigues

(Edit: Let’s see if this displays correctly – can we have a preview comment?)

Let’s say your example service listens on ports 666/tcp and 999/udp:

Create a file called /etc/firewalld/services/example-service.xml with the contents:

<service>

<short>Example Service</short>

<description>A longer description where you explain what the example service is and what it does</description>

<port protocol="tcp" port="666"/>

<port protocol="udp" port="999"/>

</service>

Then you can register the example service like this:

# firewall-cmd –permanent –add-service=example-service

# firewall-cmd –reload

## Ondrej

No it did not 😀

The default services are defined in:

/usr/lib/firewalld/services/*.xml

so you can always have a look and just copy paste them O:)

## itsmefma

Thanks for the article!

If there is another entry in this series I would like it to be about rich rules 😀

greets!

## Anonymous

A few tips and tricks for firewall-cmd I’ve learned over the years that are valuable when using Fedora on a multi-NIC system as firewall:

Get familiar with nmcli for managing the IP settings and configurations on your interfaces. Running nmcli without parameters will give you a quick overview of your current interfaces and their configuration. The nmcli commands aren’t difficult – nmcli connection edit ‘Connection Name’ drops you in, goto section lets you configure a section, print shows you the settings, back goes up a level, save, quit, etc. It’s all pretty self explanatory. Note it likes /CIDR notation (i.e. 123.45.67.89/24) for addresses, and it assumes when you got to set the address that you’re adding to an existing one, so you need to clear the existing address if it has one before adding a new one. At this point, I disable all IPv6 because I don’t know enough to secure it properly.

Next, you set up your zones using firewall-cmd independently of binding to them. I typically have an internal zone and two external zones – external_lockdown for when I don’t want any inbound connectivity, and external_normal that exposes my normal services to the Internet. For my external_lockdown zone, I even use –add-icmp-block for everything – I go completely icmp quiet.

On both of my external zones I have –add-masquerade – that’s how you get IPv4 NATing to work.

Finally, the tricky piece of the puzzle is that my experience is that firewall-cmd doesn’t bind zones to interfaces properly if the interface isn’t plugged in. Futher more, sometimes it seems like you can end up with multiple zones bound to a single interface, and that doesn’t seem helpful. So what I do now is do my zone binding from a console connection. Next, when I’m messing with zones on the external interface, I disconnect my external feed and just the cable from my internal network switch to whichever interface I’m binding. I unbind the current zone on that interface with –remove-interface, then add the interface to the new zone with –add-interface, then use –reload, then check everything with –get-active-zones.

Finally, I use GRC’s Shields Up to probe my machine from the Internet after doing any work as confirmation that the ports I expect to see are open and everything else is locked down tight.

## http://167.71.215.86

Hello to every one, for the reason that I am really keen of reading this

webpage’s post to be updated daily. It contains good data.