Firewall-cmd is the command that tells you, in seconds, whether the firewall is the reason a service will not answer. This guide opens one named service or port right now, tests it from a real client, then saves the working rule so it survives a restart, with the exact command to undo it again. The examples match firewalld 2.1.1, supplied here by package firewalld 2.1.1-1.
Allow about ten minutes. You need shell access and a service managed by firewalld. Commands that query the firewall are normally unprivileged, but changing firewall state usually needs sudo or a root shell. Keep an existing SSH session open while changing a remote host: a bad rule is a lot less funny when it is the rule that locked you out.
Start with read-only checks. They do not change firewall rules:
$ firewall-cmd --state
$ firewall-cmd --get-default-zone
$ firewall-cmd --get-active-zones
--zone.not running, so rule changes cannot work until the firewalld service is started by the system administrator.Checkpoint: do not continue until --state reports running. If you have several active zones, choose the one containing the interface that should receive the new traffic. Do not guess from the zone name.
Replace public with the zone you selected. The command below is read-only and shows services, ports, interfaces and other settings:
$ firewall-cmd --zone=public --list-all
If you need to check an interface directly, use:
$ firewall-cmd --get-zone-of-interface=INTERFACE_NAME
Replace INTERFACE_NAME with a real interface such as enp1s0. A result of no zone means the interface is not directly bound to a zone; it does not tell you which zone a connection manager may select later.
Prefer a predefined service when one describes the application. The http service, for example, represents web traffic without making you remember its port number:
$ firewall-cmd --get-services | tr ' ' '\n' | grep '^http$'
8443/tcp instead.Runtime rules take effect now but are not retained after firewalld restarts. Use one of these examples, with elevated privileges:
$ sudo firewall-cmd --zone=public --add-service=http
success
$ sudo firewall-cmd --zone=public --add-port=8443/tcp
success
Do not run both examples unless the application really needs both. Both options can be repeated, and the port format is port, port-port, followed by /tcp, /udp or another supported protocol.
Checkpoint: ask firewalld whether the particular rule is present:
$ firewall-cmd --zone=public --query-service=http
$ firewall-cmd --zone=public --query-port=8443/tcp
A successful query exits with status 0. A valid query for a rule that is absent exits with status 1. To see the complete current zone, run firewall-cmd --zone=public --list-all again.
Use a client from the intended network, not only a local process. For HTTP, for example:
$ curl --fail --connect-timeout 5 http://SERVER_ADDRESS/
Replace SERVER_ADDRESS with the host name or address that clients use. A successful connection proves that the path you tested is working; it does not prove that every source network or protocol is permitted.
If the test fails, inspect the listener and the selected zone before adding more rules:
$ ss -ltnp
$ firewall-cmd --zone=public --list-all
Once the application works and the rule is correct, make the same rule permanent. This explicit two-command pattern keeps the difference between immediate and persistent state easy to review:
$ sudo firewall-cmd --permanent --zone=public --add-port=8443/tcp
success
$ sudo firewall-cmd --check-config
success
The --permanent change is written to firewalld's permanent configuration but does not change the current runtime rules. Because you already added the runtime rule, clients keep working while you reload. A reload replaces runtime configuration with the permanent configuration, so the new rule then has to exist in both places.
Tip: there is another workflow: make several runtime changes, test them, then run sudo firewall-cmd --runtime-to-permanent. That command overwrites the entire permanent configuration with the active runtime configuration, so use it only when you intend to save all current runtime changes, not just the one rule in this guide.
Removing a runtime rule does not remove its permanent counterpart. Remove both deliberately, and verify after each operation:
$ sudo firewall-cmd --zone=public --remove-port=8443/tcp
success
$ sudo firewall-cmd --permanent --zone=public --remove-port=8443/tcp
success
$ firewall-cmd --zone=public --query-port=8443/tcp
$ firewall-cmd --permanent --zone=public --query-port=8443/tcp
The two final queries should each return exit status 1. If a rule was added as a service, substitute --remove-service=http and --query-service=http.
Warning: the remove operation is targeted, but treat it as service-disrupting. Existing clients may lose access as soon as the runtime rule disappears.
firewall-cmd --state reported running and you identified the correct active zone.--check-config before it was relied upon.