Your application listens on a port firewalld has never heard of, so you define a proper firewalld service instead of another ad hoc rule. You will create a named firewalld service for an application listening on TCP port 8443, validate the definition, enable it in one zone, and remove it cleanly if the change is wrong. The example follows firewalld 2.1.1, the version installed on the reference machine.
Allow about fifteen minutes.
Service definitions are XML files named after the service. Put administrator-created files in /etc/firewalld/services. Files in /usr/lib/firewalld/services are package-provided defaults and can be replaced by a file with the same name under /etc. Do not edit the package copy, because an update can overwrite it.
These read-only checks do not need root:
$ dpkg-query -W -f='${Package} ${Version}\n' firewalld
firewalld 2.1.1-1
$ command -v firewall-cmd
/usr/bin/firewall-cmd
$ firewall-cmd --help | grep -A18 'Service Options'
The exact package version varies by distribution. Keep the version in your change record if you are relying on a particular behaviour. The installed manpage describes the same service-file format as the upstream documentation linked in post.json.
Checkpoint: choose a service name that is short, lowercase, and unique on this host. The name below is warehouse-api, so the file will be warehouse-api.xml. The name is an identifier, not a display label.
Prepare the file outside /etc first. This lets you inspect it before making a privileged change. The port and protocol attributes are both required for a port element. A port can also be a range, but use one port until you have a reason to widen the rule.
<?xml version="1.0" encoding="utf-8"?>
<service version="1.0">
<short>Warehouse API</short>
<description>HTTPS API for the warehouse application.</description>
<port port="8443" protocol="tcp"/>
</service>
Save that content as /tmp/warehouse-api.xml, then inspect the result:
$ sed -n '1,20p' /tmp/warehouse-api.xml
<?xml version="1.0" encoding="utf-8"?>
<service version="1.0">
<short>Warehouse API</short>
<description>HTTPS API for the warehouse application.</description>
<port port="8443" protocol="tcp"/>
</service>
Do not add a service definition merely because a port number is available. Confirm that the application really listens on that port, and confirm whether it uses TCP or UDP. A TCP entry does not allow UDP traffic to the same number.
This is the first state-changing step and needs elevated privileges. The command creates the directory if necessary and installs a readable file with a predictable mode:
$ sudo install -D -m 0644 /tmp/warehouse-api.xml \
/etc/firewalld/services/warehouse-api.xml
$ sudo ls -l /etc/firewalld/services/warehouse-api.xml
-rw-r--r-- 1 root root ... /etc/firewalld/services/warehouse-api.xml
The owner, size and timestamp will differ. If a file with this name already exists, install replaces it. Stop here and take a backup first if you are modifying an existing service rather than adding a new one.
Checkpoint: the definition exists, but it is not yet enabled in any zone. Creating an XML service and allowing that service through a zone are separate operations.
Run the installed firewalld checker before reloading anything. On a running system, use:
$ sudo firewall-cmd --check-config
success
include that refers to a service that does not exist.If firewalld is stopped, firewall-cmd cannot contact its D-Bus service. Start it only if that is part of your maintenance plan. On systems where you need an offline check, the installed alternative is:
$ sudo firewall-offline-cmd --check-config
success
The offline command reads the system configuration and requires root. Neither checker proves that an application is listening, and neither proves that a remote client can reach the host.
Ask firewalld to show the parsed service. This is read-only, but firewalld must be running:
$ firewall-cmd --info-service=warehouse-api
warehouse-api
ports: 8443/tcp
protocols:
source-ports:
modules:
destination:
includes:
helpers:
Formatting varies slightly between releases. The key check is that 8443/tcp appears under ports. If the service cannot be found, check the filename, spelling, XML location and configuration error output before attempting a reload.
Choose the zone that actually contains the interface or source you intend to protect. Do not assume that public is correct. Inspect the active zones first:
$ firewall-cmd --get-active-zones
public
interfaces: ens3
Warning: the following change is security-sensitive: it permits new inbound TCP connections to port 8443 in the selected zone. Make it permanent, and use the real zone name instead of the example:
$ sudo firewall-cmd --permanent --zone=public --add-service=warehouse-api
success
$ sudo firewall-cmd --reload
success
A reload applies the permanent configuration while preserving runtime state according to firewalld's normal reload behaviour. It can still affect traffic, so schedule it for a suitable maintenance window if the host is busy.
Verify both the permanent service entry and the zone's current view:
$ firewall-cmd --zone=public --list-services
... warehouse-api ...
$ firewall-cmd --zone=public --query-service=warehouse-api
yes
If the application is not listening, clients will still fail even though the firewall now permits the traffic. Test from an approved client with the application's own health check, not with a random scan.
Use another element only when the service genuinely needs it. Multiple port, protocol, source-port, include and helper entries are supported.
/etc/protocols.helper instead.These features expand the rule's effect. Keep the first definition small, then add one verified requirement at a time.
Warning: if the rule is wrong or no longer needed, remove it from every zone where you enabled it, then reload. The removal is also security-sensitive because it changes live filtering.
$ sudo firewall-cmd --permanent --zone=public --remove-service=warehouse-api
success
$ sudo firewall-cmd --reload
success
$ firewall-cmd --zone=public --query-service=warehouse-api
no
Only after the service is no longer referenced should you remove its XML file:
$ sudo rm -- /etc/firewalld/services/warehouse-api.xml
Warning: removing the file is irreversible unless you have kept the source XML or a backup. If you need the definition later, move it to a restricted backup location instead of deleting it. Removing the XML without removing zone references can leave configuration errors at the next reload.
/etc/firewalld/services, not the package-owned directory.service element and a port entry matching the application's real protocol.firewall-cmd --check-config or the offline checker reports success.--info-service shows the expected parsed port.yes.