FIREWALL-CMD(1)

πŸ’– FIREWALL-CMD(1) β€” the firewall-cmd era πŸ’–

okay bestie, welcome to firewall-cmd(1), aka the manual page for the firewalld command line client. pull up a chair, grab a strawberry πŸ“, and let's get into it.


✨ NAME ✨

firewall-cmd β€” firewalld command line client


🌸 SYNOPSIS 🌸

firewall-cmd [OPTIONS...]

πŸ¦‹ DESCRIPTION πŸ¦‹

So. firewall-cmd is the command line client of the firewalld daemon. She's basically the interface that lets you manage your runtime configuration and your permanent configuration. Two worlds, one icon. πŸ‘‘

And here's the thing you have to internalize, fr fr: in firewalld, the runtime configuration is separated from the permanent configuration. What does that mean for you? It means things can get changed in the runtime configuration or in the permanent configuration. Separate places, separate vibes, and you get to pick which one you're messing with.


πŸ’… OPTIONS πŸ’…

First, let's talk about sequence options, because this is one of those things that's giving "important and also easy to misunderstand."

Sequence options are the ones you can specify multiple times. The exit code is 0 if there's at least one item that succeeded. And listen β€” the ALREADY_ENABLED (11), NOT_ENABLED (12) and also ZONE_ALREADY_SET (16) errors are treated as succeeded. Yes, really. They're not the enemy.

If there are issues while parsing the items, those get treated as warnings and they will not change the result, as long as there's one that succeeded. But if there's no succeeded item at all, then the exit code depends on the error codes:

  • If there's exactly one error code, that one gets used.
  • If there's more than one, then UNKNOWN_ERROR (254) gets used.

The following options are supported, and yes, we're doing all of them, no skips, no cap πŸ‘‡

πŸ”§ General Options

  • -h, --help β€” prints a short help text and then dips. help text says bye, exits.
  • -V, --version β€” prints the version string of firewalld. heads up bestie: this option is not combinable with other options. she's a solo act.
  • -q, --quiet β€” do not print status messages. silence is golden, periodt.

🩺 Status Options

  • --state β€” check whether the firewalld daemon is active (i.e. running). Returns an exit code 0 if it is active, RUNNING_BUT_FAILED if failure occurred on startup, NOT_RUNNING otherwise. See the section called β€œEXIT CODES”. It will also print the state to STDOUT. double duty, we love that.
  • --reload β€” reload firewall rules and keep state information. The current permanent configuration will become the new runtime configuration. iykyk: all runtime-only changes you made up until reload are lost with reload if they have not also been in the permanent configuration. 😭 that's just how she is.
Note: If FlushAllOnReload=no, runtime changes applied via the direct interface are not affected and will therefore stay in place until the firewalld daemon is restarted completely. For FlushAllOnReload, see firewalld.conf(5).
  • --complete-reload β€” reload firewall completely, even netfilter kernel modules. This will most likely terminate active connections, because state information is lost. This option should only be used in case of severe firewall problems. For example if there are state information problems that no connection can be established with correct firewall rules. it's giving "nuclear option, use with respect" πŸ’€
Note: If FlushAllOnReload=no, runtime changes applied via the direct interface are not affected and will therefore stay in place until the firewalld daemon is restarted completely. For FlushAllOnReload, see firewalld.conf(5).
  • --runtime-to-permanent β€” save the active runtime configuration and overwrite the permanent configuration with it. The way this is supposed to work is that when you're configuring firewalld you do runtime changes only, and once you're happy with the configuration and you tested that it works the way you want, you save the configuration to disk. this is the "test drive first, commit later" pipeline and honestly? main character energy. ✨
  • --check-config β€” run checks on the permanent configuration. This includes XML validity and semantics. vibe check for your config files, literally.
  • --reset-to-defaults β€” reset configuration to firewalld's default configuration. factory reset moment.

πŸ™ˆ Log Denied Options

  • --get-log-denied β€” print the log denied setting.
  • --set-log-denied=value β€” add logging rules right before reject and drop rules in the INPUT, FORWARD and OUTPUT chains for the default rules, and also final reject and drop rules in zones for the configured link-layer packet type. The possible values are: all, unicast, broadcast, multicast and off. The default setting is off, which disables the logging.

This is a runtime and permanent change and will also reload the firewall to be able to add the logging rules. two things at once, she's efficient.

πŸ‘‘ Permanent Options

  • --permanent β€” the permanent option --permanent can be used to set options permanently. These changes are not effective immediately β€” only after service restart/reload or system reboot. Without the --permanent option, a change will only be part of the runtime configuration.

If you want to make a change in runtime and permanent configuration, use the same call with and without the --permanent option. yep, twice. that's the move.

The --permanent option can be optionally added to all options further down where it is supported.

🌈 Zone Options

  • --get-default-zone β€” print default zone for connections and interfaces.
  • --set-default-zone=zone β€” set default zone for connections and interfaces where no zone has been selected. Setting the default zone changes the zone for the connections or interfaces that are using the default zone.

This is a runtime and permanent change.

  • --get-active-zones β€” print currently active zones altogether with interfaces and sources used in these zones. Active zones are zones that have a binding to an interface or source. The output format is:
zone1
  interfaces: interface1 interface2 ..
  sources: source1 ..
zone2
  interfaces: interface3 ..
zone3
  sources: source2 ..

If there are no interfaces or sources bound to the zone, the corresponding line will be omitted. no empty filler, she's tidy. πŸŽ€

  • [--permanent] --get-zones β€” print predefined zones as a space separated list.
  • [--permanent] --get-services β€” print predefined services as a space separated list.
  • [--permanent] --get-icmptypes β€” print predefined icmptypes as a space separated list.
  • [--permanent] --get-zone-of-interface=interface β€” print the name of the zone the interface is bound to, or no zone.
  • [--permanent] --get-zone-of-source=source[/mask]|MAC|ipset:ipset β€” print the name of the zone the source is bound to, or no zone.
  • [--permanent] --info-zone=zone β€” print information about the zone zone. The output format is:
zone
  interfaces: interface1 ..
  sources: source1 ..
  services: service1 ..
  ports: port1 ..
  protocols: protocol1 ..
  forward-ports:
        forward-port1
        ..
  source-ports: source-port1 ..
  icmp-blocks: icmp-type1 ..
  rich rules:
        rich-rule1
        ..
  • [--permanent] --list-all-zones β€” list everything added for or enabled in all zones. The output format is:
zone1
  interfaces: interface1 ..
  sources: source1 ..
  services: service1 ..
  ports: port1 ..
  protocols: protocol1 ..
  forward-ports:
        forward-port1
        ..
  icmp-blocks: icmp-type1 ..
  rich rules:
        rich-rule1
        ..
..
  • --permanent --new-zone=zone β€” add a new permanent and empty zone.

Zone names must be alphanumeric and may additionally include characters: '_' and '-'.

  • --permanent --new-zone-from-file=filename [--name=zone] β€” add a new permanent zone from a prepared zone file, with an optional name override.
  • --permanent --delete-zone=zone β€” delete an existing permanent zone. bye bestie 🫢
  • --permanent --load-zone-defaults=zone β€” load zone default settings or report NO_DEFAULTS error.
  • --permanent --path-zone=zone β€” print path of the zone configuration file.

🧚 Policy Options

  • [--permanent] --get-policies β€” print predefined policies as a space separated list.
  • [--permanent] --info-policy=policy β€” print information about the policy policy.
  • [--permanent] --list-all-policies β€” list everything added for or enabled in all policies.
  • --permanent --new-policy=policy β€” add a new permanent policy.

Policy names must be alphanumeric and may additionally include characters: '_' and '-'.

  • --permanent --new-policy-from-file=filename [--name=policy] β€” add a new permanent policy from a prepared policy file, with an optional name override.
  • --permanent --path-policy=policy β€” print path of the policy configuration file.
  • --permanent --delete-policy=policy β€” delete an existing permanent policy.
  • --permanent --load-policy-defaults=policy β€” load the shipped defaults for a policy. Only applies to policies shipped with firewalld. Does not apply to user defined policies. read that again, it matters. πŸ“Œ

πŸŽ€ Options to Adapt and Query Zones and Policies

Ok so this next group is a little different β€” options in this section affect only one particular zone or policy. If used with the --zone=zone or --policy=policy option, they affect the specified zone or policy. If both options are omitted, they affect the default zone (see --get-default-zone).

  • [--permanent] [--zone=zone] [--policy=policy] --list-all β€” list everything added or enabled.
  • --permanent [--zone=zone] [--policy=policy] --get-target β€” get the target.
  • --permanent [--zone=zone] [--policy=policy] --set-target=target β€” set the target.

For zones, target is one of: default, ACCEPT, DROP, REJECT

For policies, target is one of: CONTINUE, ACCEPT, DROP, REJECT

default is similar to REJECT, but it implicitly allows ICMP packets.

ACCEPT allows traffic to be forwarded from the zone, either to the same zone or other zones.

  • --permanent [--zone=zone] [--policy=policy] --set-description=description β€” set description.
  • --permanent [--zone=zone] [--policy=policy] --get-description β€” print description.
  • --permanent [--zone=zone] [--policy=policy] --set-short=description β€” set short description.
  • --permanent [--zone=zone] [--policy=policy] --get-short β€” print short description.
  • [--permanent] [--zone=zone] [--policy=policy] --list-services β€” list services added as a space separated list.
  • [--permanent] [--zone=zone] [--policy=policy] --add-service=service [--timeout=timeval] β€” add a service. This option can be specified multiple times (sequence option representation πŸ’…). If a timeout is supplied, the rule will be active for the specified amount of time and will be removed automatically afterwards. timeval is either a number (of seconds) or a number followed by one of the characters s (seconds), m (minutes), h (hours), for example 20m or 1h.

The service is one of the firewalld provided services. To get a list of the supported services, use firewall-cmd --get-services.

The --timeout option is not combinable with the --permanent option. pick a lane, bestie. 🚫

okay quick note bestie β€” some services come with connection tracking helpers. And the ones that can operate in client mode (looking at you, tftp πŸ’…) have to be added to an outbound policy, not a zone, or they will literally never kick in for your clients. Like, the helper just won't apply to the outbound traffic. The related traffic β€” the stuff the connection tracking helper defines on the return path (ingress) β€” that part gets allowed by the stateful firewall rules, so you're covered there. 🫢

Here's what an outbound policy for connection tracking helpers looks like:

# firewall-cmd --permanent --new-policy clientConntrack
# firewall-cmd --permanent --policy clientConntrack --add-ingress-zone HOST
# firewall-cmd --permanent --policy clientConntrack --add-egress-zone ANY
# firewall-cmd --permanent --policy clientConntrack --add-service tftp

  • [--permanent] [--zone=zone] [--policy=policy] --remove-service=service β€” takes a service out. You can say this option more than once, no cap.
  • [--permanent] [--zone=zone] [--policy=policy] --query-service=service β€” asks the universe "is this service in here or not?" Returns 0 if yeah, 1 if nope.
  • [--permanent] [--zone=zone] [--policy=policy] --list-ports β€” spills out every port you've added as a space-separated list. A port looks like portid[-portid]/protocol β€” so it's either a port-and-protocol pair, or a whole port range with a protocol attached. Cute and simple. ✨
  • [--permanent] [--zone=zone] [--policy=policy] --add-port=portid[-portid]/protocol [--timeout=timeval] β€” adds a port. Say it multiple times if you want, go off. And if you hand it a timeout, the rule stays live for exactly that long and then dips out automatically. timeval is either just a plain number (seconds, boo boring) or a number with one of these letters: s (seconds), m (minutes), h (hours) β€” like 20m or 1h. πŸ•

The port is either one single port number, or a range written portid-portid. The protocol is one of tcp, udp, sctp or dccp.

🚨 heads up: --timeout and --permanent cannot be combined. Pick a lane.

  • [--permanent] [--zone=zone] [--policy=policy] --remove-port=portid[-portid]/protocol β€” bye bye port. Multiple times? Totally allowed.
  • [--permanent] [--zone=zone] [--policy=policy] --query-port=portid[-portid]/protocol β€” returns whether that port got added. 0 = true, 1 = otherwise.
  • [--permanent] [--zone=zone] [--policy=policy] --list-protocols β€” shows every protocol you've added, space-separated, all lined up pretty. 🌸
  • [--permanent] [--zone=zone] [--policy=policy] --add-protocol=protocol [--timeout=timeval] β€” adds a protocol. Stack it as many times as you need. If a timeout is supplied, the rule is active for that amount of time and then removes itself, dramatic exit. timeval is a number (seconds) or a number followed by one of s (seconds), m (minutes), h (hours) β€” 20m, 1h, you know the drill.

Your protocol can be literally any protocol the system supports. Go peek at /etc/protocols for the roster. πŸ“‹

And again: --timeout is not combinable with --permanent.

  • [--permanent] [--zone=zone] [--policy=policy] --remove-protocol=protocol β€” removes a protocol. Repeatable, of course.
  • [--permanent] [--zone=zone] [--policy=policy] --query-protocol=protocol β€” did the protocol get added? 0 if yes, 1 if no.
  • [--permanent] [--zone=zone] [--policy=policy] --list-source-ports β€” lists the source ports you added, space-separated. Port format is portid[-portid]/protocol. Slay. πŸ’…
  • [--permanent] [--zone=zone] [--policy=policy] --add-source-port=portid[-portid]/protocol [--timeout=timeval] β€” adds a source port. Specify it multiple times if your heart desires. With a timeout, the rule lives for that long and then auto-dips. timeval = a number (seconds), or a number plus one of s (seconds), m (minutes), h (hours), e.g. 20m or 1h.

Port: single port number or a range portid-portid. Protocol: tcp, udp, sctp or dccp.

One more time for the people in the back: --timeout is not combinable with --permanent. πŸ™ˆ

  • [--permanent] [--zone=zone] [--policy=policy] --remove-source-port=portid[-portid]/protocol β€” removes the source port. Yeah, you can run it multiple times.
  • [--permanent] [--zone=zone] [--policy=policy] --query-source-port=portid[-portid]/protocol β€” returns whether the source port has been added. 0 = true, 1 = otherwise.
  • [--permanent] [--zone=zone] [--policy=policy] --list-icmp-blocks β€” lists all the Internet Control Message Protocol (ICMP) type blocks that have been added, as one space-separated list. πŸ¦‹
  • [--permanent] [--zone=zone] [--policy=policy] --add-icmp-block=icmptype [--timeout=timeval] β€” adds an ICMP block for icmptype. Specify it multiple times, iconic. With a timeout supplied, the rule is active for that stretch and then removes itself automatically. timeval is a number (seconds) or a number followed by one of s (seconds), m (minutes), h (hours) β€” 20m, 1h, whatever.

The icmptype is one of the ICMP types firewalld supports. Want the full list of supported ICMP types? Run firewall-cmd --get-icmptypes and ✨ behold ✨.

Also (say it with me): --timeout is not combinable with --permanent.

  • [--permanent] [--zone=zone] [--policy=policy] --remove-icmp-block=icmptype β€” removes the ICMP block for icmptype. Multiple times, sure.
  • [--permanent] [--zone=zone] [--policy=policy] --query-icmp-block=icmptype β€” returns whether an ICMP block for icmptype has been added. 0 if true, 1 otherwise.
  • [--permanent] [--zone=zone] [--policy=policy] --list-forward-ports β€” lists IPv4 forward ports, space-separated. πŸŽ€

For IPv6 forward ports? Bestie, go use the rich language.

  • [--permanent] [--zone=zone] [--policy=policy] --add-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] [--timeout=timeval] β€” adds the IPv4 forward port. Can be specified multiple times. With a timeout, the rule stays active for the specified amount of time and is then removed automatically. timeval is a number (seconds) or a number followed by one of s (seconds), m (minutes), h (hours) β€” for example 20m or 1h.

The port is a single port number portid or a port range portid-portid. The protocol is tcp, udp, sctp or dccp. The destination address is a simple IP address.

--timeout is not combinable with --permanent. 🚫

For IPv6 forward ports, please use the rich language.

Note: IP forwarding will be implicitly enabled if toaddr is specified. Not a suggestion, it just happens.
Note: When this option is used with --policy, the firewall backend cannot determine the egress zone. See section UNKNOWN DESTINATIONS for the whole saga. πŸ’€
  • [--permanent] [--zone=zone] [--policy=policy] --remove-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] β€” removes the IPv4 forward port. Specify it multiple times, no problem.

IPv6 forward ports: rich language, bestie. That's the way.

  • [--permanent] [--zone=zone] [--policy=policy] --query-forward-port=port=portid[-portid]:proto=protocol[:toport=portid[-portid]][:toaddr=address[/mask]] β€” returns whether that IPv4 forward port has been added. 0 if true, 1 otherwise.

(IPv6 forward ports β†’ rich language. You know the vibe by now. 🌈)

  • [--permanent] [--zone=zone] [--policy=policy] --add-masquerade [--timeout=timeval] β€” turns on IPv4 masquerade. If you supply a timeout, masquerading stays active for that amount of time. timeval is a number (seconds) or a number followed by one of s (seconds), m (minutes), h (hours), e.g. 20m or 1h. Masquerading is the move when your machine is a router and machines hooked up over an interface in another zone should be able to use that first connection. Main character routing energy, honestly. πŸ‘‘

--timeout is not combinable with --permanent.

For IPv6 masquerading, please use the rich language.

Note: IP forwarding gets implicitly enabled. Automatically. Surprise.
Note (Linux < 5.5): with the iptables backend, a policy may not enable masquerade if an ingress zone has assigned interfaces. The nftables backend doesn't have that restriction, but it does need Linux v5.5+ to actually function properly β€” otherwise it will silently fail. Silent. Failure. The worst kind. 😭
  • [--permanent] [--zone=zone] [--policy=policy] --remove-masquerade β€” turns IPv4 masquerade off. And if masquerading had been enabled with a timeout, this disables it too.

For IPv6 masquerading, please use the rich language.

  • [--permanent] [--zone=zone] [--policy=policy] --query-masquerade β€” returns whether IPv4 masquerading has been enabled. 0 = true, 1 = otherwise.

For IPv6 masquerading, please use the rich language.

  • [--permanent] [--zone=zone] [--policy=policy] --list-rich-rules β€” lists the rich language rules you've added, one per line (newline-separated). 🧚
  • [--permanent] [--zone=zone] [--policy=policy] --add-rich-rule='rule' [--timeout=timeval] β€” adds the rich language rule 'rule'. This option can be specified multiple times. Supply a timeout and the rule will be active for that amount of time before it removes itself automatically. timeval is a number (seconds) or a number followed by one of s (seconds), m (minutes), h (hours) β€” 20m or 1h, take your pick.

For the rich language rule syntax, go read firewalld.richlanguage(5).

And yes β€” --timeout is not combinable with --permanent. πŸ’–

  • [--permanent] [--zone=zone] [--policy=policy] --remove-rich-rule='rule' β€” removes the rich language rule 'rule'. Can be specified multiple times.

For the rich language rule syntax, hit up firewalld.richlanguage(5).

  • [--permanent] [--zone=zone] [--policy=policy] --query-rich-rule='rule' β€” returns whether a rich language rule 'rule' has been added. 0 if true, 1 otherwise.

For the rich language rule syntax, please have a look at firewalld.richlanguage(5).


⭐ Options to Adapt and Query Zones ⭐

Okay so everything in this lil section only touches one particular zone. Use it with the --zone=zone option and it affects that specified zone. Leave the option out and it hits the default zone instead (go check --get-default-zone if you forgot which one that is πŸ’œ).

  • [--permanent] [--zone=zone] --add-icmp-block-inversion β€” enables ICMP block inversion.
  • [--permanent] [--zone=zone] --remove-icmp-block-inversion β€” ok so turn ICMP block inversion OFF bestie, it's giving "let the pings through" energy πŸ’«
  • [--permanent] [--zone=zone] --query-icmp-block-inversion β€” asks the universe "is ICMP block inversion on?" and reports back. Returns 0 if true, 1 otherwise. no cap 🫢
  • [--permanent] [--zone=zone] --add-forward β€” switch on intra zone forwarding, slay ✨
  • [--permanent] [--zone=zone] --remove-forward β€” switch off intra zone forwarding, bye bestie πŸ’…
  • [--permanent] [--zone=zone] --query-forward β€” is intra zone forwarding enabled?? Returns 0 if true, 1 otherwise 🌸
  • --permanent [--zone=zone] --get-priority β€” grab the priority of the zone, pulling up 🌟
  • --permanent [--zone=zone] --set-priority β€” set the zone's priority for packet classification. this sets BOTH the ingress and the egress priority at once, two birds one stone fr fr 🐦
  • --permanent [--zone=zone] --get-ingress-priority β€” get the ingress priority of the zone πŸ‘‘
  • --permanent [--zone=zone] --set-ingress-priority β€” set the zone's ingress priority for packet classification πŸŽ€
  • --permanent [--zone=zone] --get-egress-priority β€” get the egress priority of the zone πŸ¦‹
  • --permanent [--zone=zone] --set-egress-priority β€” set the zone's egress priority for packet classification πŸ’–

πŸ’… Options to Adapt and Query Policies πŸ’…

okay so these options are like, super into ONE particular policy only. you literally HAVE to pass --policy=policy with them or it's not gonna work. it's giving "commitment issues but make it firewalld" 😭

  • --permanent --policy=policy --get-priority β€” get the priority, periodt 🌟
  • --permanent --policy=policy --set-priority=priority β€” set the priority. this priority thing decides the relative ordering of policies, it's the vibe check for who goes first. it's an integer value between -32768 and 32767 where -1 is the default value for new policies and 0 is reserved for internal use. lowkey important!! 🚨

if a priority is < 0, then the policy's rules will execute before all rules in all zones. it's jumping the line bestie πŸ’¨

if a priority is > 0, then the policy's rules will execute after all rules in all zones. fashionably late πŸ’…

  • [--permanent] --policy=policy --list-ingress-zones β€” list ingress zones that were added, as a space separated list 🌸
  • [--permanent] --policy=policy --add-ingress-zone=zone β€” add an ingress zone. you can specify this option multiple times, go off πŸ”₯

the ingress zone is one of the firewalld provided zones OR one of the pseudo-zones: HOST, ANY.

HOST is used for traffic originating from the host machine, i.e. the host running firewalld.

ANY is used for traffic originating from any zone. think of it like a wild card for zones. BUT it does not include traffic originating from the host machine β€” use HOST for that. this distinction is so real, iykyk 😌

  • [--permanent] --policy=policy --remove-ingress-zone=zone β€” remove an ingress zone. also can be specified multiple times πŸŽ€
  • [--permanent] --policy=policy --query-ingress-zone=zone β€” return whether the zone has been added. Returns 0 if true, 1 otherwise 🫢
  • [--permanent] --policy=policy --list-egress-zones β€” list egress zones added, as a space separated list ✨
  • [--permanent] --policy=policy --add-egress-zone=zone β€” add an egress zone. can be specified multiple times, no cap πŸ’«

the egress zone is one of the firewalld provided zones OR one of the pseudo-zones: HOST, ANY.

for clarification on HOST and ANY see option --add-ingress-zone. (spoiler: it's up there ⬆️)

  • [--permanent] --policy=policy --remove-egress-zone=zone β€” remove an egress zone. yep, can be specified multiple times 🌈
  • [--permanent] --policy=policy --query-egress-zone=zone β€” return whether the zone has been added. Returns 0 if true, 1 otherwise. slay πŸ’…
  • [--permanent] --policy=policy|--policy-set=policy-set --add-disable β€” administratively disable a policy. a disabled policy will not activate. it's on do-not-disturb mode fr 😴
  • [--permanent] --policy=policy|--policy-set=policy-set --remove-disable β€” remove the administratively disable from a policy. lets a policy activate again, welcome back bestie πŸ₯³
  • [--permanent] --policy=policy --query-disable β€” return if the policy is administratively disabled 🌸

πŸ¦‹ Options to Handle Bindings of Interfaces πŸ¦‹

okay so binding an interface to a zone means the zone settings get used to restrict traffic via that interface. that's the whole vibe ✨

periodt, these options affect only ONE particular zone. if you use them with the --zone=zone option, they affect the zone zone. if you skip the option, they affect the default zone (see --get-default-zone).

for a list of predefined zones use firewall-cmd --get-zones.

an interface name is a string up to 16 characters long, and it may NOT contain ' ', '/', '!' and '*'. so no wild shenanigans bestie 🚫

  • [--permanent] [--zone=zone] --list-interfaces β€” list interfaces bound to zone zone, as a space separated list. if zone is omitted, default zone will be used πŸ“‹
  • [--permanent] [--zone=zone] --add-interface=interface β€” bind interface interface to zone zone. if zone is omitted, default zone will be used πŸ’–

if the interface is under control of NetworkManager, it is at first connected to change the zone for the connection that is using the interface. if this fails, the zone binding is created in firewalld and the limitations below apply. for interfaces that are not under control of NetworkManager, firewalld tries to change the ZONE setting in the ifcfg file, if the file exists.

as an end user you don't need this in most cases, because NetworkManager (or legacy network service) adds interfaces into zones automatically (according to the ZONE= option from the ifcfg-interface file) if NM_CONTROLLED=no is not set. you should only do it if there's no /etc/sysconfig/network-scripts/ifcfg-interface file. if there IS such a file and you add interface to zone with this --add-interface option, make sure the zone is the same in both cases, otherwise the behavior would be undefined. πŸ’€ please also have a look at the firewalld(1) man page in the Concepts section. for permanent association of interface with a zone, see also 'How to set or change a zone for a connection?' in firewalld.zones(5).

  • [--permanent] [--zone=zone] --change-interface=interface β€” if the interface is under control of NetworkManager, it is at first connected to change the zone for the connection that is using the interface. if this fails, the zone binding is created in firewalld and the limitations below apply. for interfaces that are not under control of NetworkManager, firewalld tries to change the ZONE setting in the ifcfg file, if the file exists.

change the zone that interface interface is bound to, to zone zone. it's basically --remove-interface followed by --add-interface, glow up moment ✨. if the interface has not been bound to a zone before, it behaves like --add-interface. if zone is omitted, default zone will be used.

  • [--permanent] [--zone=zone] --query-interface=interface β€” query whether interface interface is bound to zone zone. Returns 0 if true, 1 otherwise 🫢
  • [--permanent] --remove-interface=interface β€” if the interface is under control of NetworkManager, it is at first connected to change the zone for the connection that is using the interface. if this fails, the zone binding is created in firewalld and the limitations below apply.

for the addition or change of interfaces that are not under control of NetworkManager: firewalld tries to change the ZONE setting in the ifcfg file, if an ifcfg file exists that is using the interface.

only for the removal of interfaces that are not under control of NetworkManager: firewalld is NOT trying to change the ZONE setting in the ifcfg file. this is needed to make sure that an ifdown of the interface will not result in a reset of the zone setting to the default zone. only the zone binding is then removed in firewalld then.

removes the binding of interface interface from the zone it was previously added to. it's out girlie πŸ‘‹

🌸 Options to Handle Bindings of Sources 🌸

binding a source to a zone means the zone settings will be used to restrict traffic from that source. that's the tea β˜•

a source address or address range is either an IP address or a network IP address with a mask for IPv4 or IPv6 or a MAC address or an ipset with the ipset: prefix. for IPv4, the mask can be a network mask or a plain number. for IPv6 the mask is a plain number. the use of host names is not supported. soz, no cute domain names here πŸ™ˆ

these options affect only ONE particular zone. if you use them with the --zone=zone option, they affect the zone zone. if the option is omitted, they affect the default zone (see --get-default-zone).

for a list of predefined zones use firewall-cmd [--permanent] --get-zones.

  • [--permanent] [--zone=zone] --list-sources β€” list sources bound to zone zone, as a space separated list. if zone is omitted, default zone will be used πŸ‘‘
  • [--permanent] [--zone=zone] --add-source=source[/mask]|MAC|ipset:ipset β€” bind the source to zone zone. if zone is omitted, default zone will be used πŸ’«
  • [--zone=zone] --change-source=source[/mask]|MAC|ipset:ipset β€” change the zone that the source is bound to, to zone zone. it's basically --remove-source followed by --add-source. if the source has not been bound to a zone before, it behaves like --add-source. if zone is omitted, default zone will be used ✨
  • [--permanent] [--zone=zone] --query-source=source[/mask]|MAC|ipset:ipset β€” query whether the source is bound to the zone zone. Returns 0 if true, 1 otherwise πŸŽ€
  • [--permanent] --remove-source=source[/mask]|MAC|ipset:ipset β€” remove the binding of the source from the zone it was previously added to πŸ¦‹

🌈 IPSet Options 🌈

  • --get-ipset-types β€” print the supported ipset types, pulling up the menu 😌
  • --permanent --new-ipset=ipset --type=type [--family=inet|inet6] [--option=key[=value]] β€” add a new permanent and empty ipset, specifying the type and optionally the family and options like timeout, hashsize and maxelem. for more information please have a look at the ipset(8) man page πŸ“–

ipset names must be alphanumeric and may additionally include characters: '_' and '-'. so cute but rules are rules πŸ’…

  • --permanent --new-ipset-from-file=filename [--name=ipset] β€” add a new permanent ipset from a prepared ipset file, with an optional name override 🌟
  • --permanent --delete-ipset=ipset β€” delete an existing permanent ipset. bye bestie 😭
  • --permanent --load-ipset-defaults=ipset β€” load ipset default settings or report NO_DEFAULTS error 🚨
  • [--permanent] --info-ipset=ipset β€” print information about the ipset ipset. the output format is:
ipset
  type: type
  options: option1[=value1] ..
  entries: entry1 ..
  • [--permanent] --get-ipsets β€” print predefined ipsets as a space separated list πŸ”₯
  • --permanent --ipset=ipset --set-description=description β€” set a new description to the ipset πŸ“
  • --permanent --ipset=ipset --get-description β€” print description for the ipset 🫢
  • --permanent --ipset=ipset --set-short=description β€” set short description to the ipset βœ‚οΈ
  • --permanent --ipset=ipset --get-short β€” prints the short description for the ipset, bestie ✨
  • [--permanent] --ipset=ipset --add-entry=entry β€” drops a shiny new entry into the ipset πŸ’–

Adding an entry to an ipset that has the timeout option is allowed, but heads up: firewalld does not track those entries. Not it being sneaky about it πŸ™ˆ

  • [--permanent] --ipset=ipset --remove-entry=entry β€” yeets entry out of the ipset 🫢
  • [--permanent] --ipset=ipset --query-entry=entry β€” tells you whether entry has been added to the ipset. Returns 0 if true, 1 otherwise.
Careful bestie 😭 β€” querying an ipset that has a timeout will straight up error. Entries are not tracked for ipsets with a timeout. Periodt.
  • [--permanent] --ipset=ipset --get-entries β€” lists every entry in the ipset 🌈
  • [--permanent] --ipset=ipset --add-entries-from-file=filename β€” loads a whole batch of new entries into the ipset from a file. For every entry that's in the file but already in the ipset, you get a warning printed. She's just letting you know πŸ’…

The file should have one entry per line. Lines starting with a hash or a semicolon are ignored. Empty lines too. Clean girl aesthetic ✨

  • [--permanent] --ipset=ipset --remove-entries-from-file=filename β€” removes existing entries from the ipset, using filename as the source. For every entry that's listed in the file but not in the ipset, a warning gets printed.

Same file rules, bestie: one entry per line, lines starting with a hash or semicolon ignored, empty lines ignored too 🌸

  • --permanent --path-ipset=ipset β€” prints the path of the ipset configuration file πŸ“

πŸŽ€ Service Options πŸŽ€

Options in this section affect only one particular service. One service, one little universe πŸ’–

  • [--permanent] --info-service=service β€” prints info about the service service. The output format is:
service
  ports: port1 ..
  protocols: protocol1 ..
  source-ports: source-port1 ..
  helpers: helper1 ..
  destination: ipv1:address1 ..

The following options are only usable in the permanent configuration. So lock in πŸ”’

  • --permanent --new-service=service β€” adds a brand new permanent and empty service. Blank canvas energy 🎨

Service names must be alphanumeric and may additionally include the characters '_' and '-'. No funny business βœ‹

  • --permanent --new-service-from-file=filename [--name=service] β€” adds a new permanent service from a prepared service file, with an optional name override. Slay, reuse the template πŸ‘‘
  • --permanent --delete-service=service β€” deletes an existing permanent service. Gone, bye, no notes πŸ’€
  • --permanent --load-service-defaults=service β€” loads service default settings, or reports a NO_DEFAULTS error. Sometimes the defaults just aren't there, and that's the vibe check 😭
  • --permanent --path-service=service β€” prints the path of the service configuration file πŸ—‚οΈ
  • --permanent --service=service --set-description=description β€” sets a new description on the service ✍️
  • --permanent --service=service --get-description β€” prints the description for the service πŸ“–
  • --permanent --service=service --set-short=description β€” sets the short description on the service 🌸
  • --permanent --service=service --get-short β€” prints the short description for the service ✨
  • --permanent --service=service --add-port=portid[-portid]/protocol β€” adds a new port to the permanent service πŸ”₯
  • --permanent --service=service --remove-port=portid[-portid]/protocol β€” removes a port from the permanent service 🫢
  • --permanent --service=service --query-port=portid[-portid]/protocol β€” returns whether that port has been added to the permanent service. Yes or no bestie πŸ’…
  • --permanent --service=service --get-ports β€” lists the ports added to the permanent service 🌈
  • --permanent --service=service --add-protocol=protocol β€” adds a new protocol to the permanent service πŸ‘‘
  • --permanent --service=service --remove-protocol=protocol β€” removes a protocol from the permanent service πŸ’€
  • --permanent --service=service --query-protocol=protocol β€” returns whether that protocol has been added to the permanent service πŸ”
  • --permanent --service=service --get-protocols β€” lists the protocols added to the permanent service ✨
  • --permanent --service=service --add-source-port=portid[-portid]/protocol β€” adds a new source port to the permanent service πŸ’–
  • --permanent --service=service --remove-source-port=portid[-portid]/protocol β€” removes a source port from the permanent service πŸŽ€
  • --permanent --service=service --query-source-port=portid[-portid]/protocol β€” returns whether that source port has been added to the permanent service πŸ”
  • --permanent --service=service --get-source-ports β€” lists the source ports added to the permanent service 🌸
  • --permanent --service=service --add-helper=helper β€” adds a new helper to the permanent service 🧚
  • --permanent --service=service --remove-helper=helper β€” removes a helper from the permanent service 🫢
  • --permanent --service=service --query-helper=helper β€” returns whether that helper has been added to the permanent service πŸ’…
  • --permanent --service=service --get-service-helpers β€” lists the helpers added to the permanent service ✨
  • --permanent --service=service --set-destination=ipv:address[/mask] β€” sets the destination for ipv to address[/mask] in the permanent service 🎯
  • --permanent --service=service --remove-destination=ipv β€” removes the destination for ipv from the permanent service πŸ—‘οΈ
  • --permanent --service=service --query-destination=ipv:address[/mask] β€” returns whether the destination ipv to address[/mask] has been set in the permanent service πŸ”
  • --permanent --service=service --get-destinations β€” lists the destinations added to the permanent service 🌈
  • --permanent --service=service --add-include=service β€” adds a new include to the permanent service πŸ’–
  • --permanent --service=service --remove-include=service β€” removes an include from the permanent service 🫢
  • --permanent --service=service --query-include=service β€” returns whether that include has been added to the permanent service πŸ”
  • --permanent --service=service --get-includes β€” lists the includes added to the permanent service ✨

πŸ¦‹ Helper Options πŸ¦‹

Options in this section affect only one particular helper. Just the one, she's the main character πŸ’…

  • [--permanent] --info-helper=helper β€” prints info about the helper helper. The output format is:
helper
  family: family
  module: module
  ports: port1 ..

The following options are only usable in the permanent configuration. Permanent mode only, bestie πŸ”’

  • --permanent --new-helper=helper --module=nf_conntrack_module [--family=ipv4|ipv6] β€” adds a new permanent helper with module and optionally family defined. Build-a-helper workshop 🧸

Helper names must be alphanumeric and may additionally include the character '-'. That's it, that's the rule βœ‹

  • --permanent --new-helper-from-file=filename [--name=helper] β€” adds a new permanent helper from a prepared helper file, with an optional name override πŸ‘‘
  • --permanent --delete-helper=helper β€” deletes an existing permanent helper πŸ’€
  • --permanent --load-helper-defaults=helper β€” loads helper default settings, or reports a NO_DEFAULTS error 😭
  • --permanent --path-helper=helper β€” prints the path of the helper configuration file πŸ—‚οΈ
  • [--permanent] --get-helpers β€” prints the predefined helpers as a space separated list ✨
  • --permanent --helper=helper --set-description=description β€” sets a new description on the helper ✍️
  • --permanent --helper=helper --get-description β€” prints the description for the helper πŸ“–
  • --permanent --helper=helper --set-short=description β€” sets the short description on the helper 🌸
  • --permanent --helper=helper --get-short β€” prints the short description for the helper ✨
  • --permanent --helper=helper --add-port=portid[-portid]/protocol β€” adds a new port to the permanent helper πŸ”₯
  • --permanent --helper=helper --remove-port=portid[-portid]/protocol β€” removes a port from the permanent helper 🫢
  • --permanent --helper=helper --query-port=portid[-portid]/protocol β€” returns whether that port has been added to the permanent helper πŸ”
  • --permanent --helper=helper --get-ports β€” lists the ports added to the permanent helper 🌈
  • --permanent --helper=helper --set-module=description β€” sets the module description for the helper 🧩
  • --permanent --helper=helper --get-module β€” prints the module description for the helper πŸ“–
  • --permanent --helper=helper --set-family=description β€” sets the family description for the helper πŸ‘¨β€πŸ‘©β€πŸ‘§
  • --permanent --helper=helper --get-family β€” prints the family description of the helper πŸ“–

🌈 Internet Control Message Protocol (ICMP) type Options 🌈

Options in this section affect only one particular icmptype. One icmptype and only one πŸ’–

  • [--permanent] --info-icmptype=icmptype β€” prints info about the icmptype icmptype. The output format is:
icmptype
  destination: ipv1 ..

The following options are only usable in the permanent configuration. Permanent only, no cap πŸ”’

  • --permanent --new-icmptype=icmptype β€” adds a brand new permanent and empty icmptype ✨

ICMP type names must be alphanumeric and may additionally include the characters '_' and '-'. Stay in your lane, names 😌

  • --permanent --new-icmptype-from-file=filename [--name=icmptype] β€” adds a new permanent icmptype from a prepared icmptype file, with an optional name override πŸ‘‘
  • --permanent --delete-icmptype=icmptype β€” deletes an existing permanent icmptype πŸ’€
  • --permanent --load-icmptype-defaults=icmptype β€” loads icmptype default settings, or reports a NO_DEFAULTS error 😭
  • --permanent --icmptype=icmptype --set-description=description β€” sets a new description on the icmptype ✍️
  • --permanent --icmptype=icmptype --get-description β€” prints the description for the icmptype πŸ“–
  • --permanent --icmptype=icmptype --set-short=description β€” sets the short description on the icmptype 🌸
  • --permanent --icmptype=icmptype --get-short β€” prints the short description for the icmptype ✨
  • --permanent --icmptype=icmptype --add-destination=ipv β€” enables the destination for ipv in the permanent icmptype. ipv is one of ipv4 or ipv6. Pick one bestie, there are only two πŸ’…
  • --permanent --icmptype=icmptype --remove-destination=ipv β€” disables the destination for ipv in the permanent icmptype. ipv is one of ipv4 or ipv6.
  • --permanent --icmptype=icmptype --query-destination=ipv β€” returns whether the destination for ipv is enabled in the permanent icmptype. ipv is one of ipv4 or ipv6.
  • --permanent --icmptype=icmptype --get-destinations β€” lists the destinations in the permanent icmptype 🌈
  • --permanent --path-icmptype=icmptype β€” prints the path of the icmptype configuration file πŸ—‚οΈ

πŸ’€ Direct Options πŸ’€

DEPRECATED

The direct interface has been deprecated. It will be removed in a future release. It is superseded by policies, see firewalld.policies(5).

Not me being the bearer of bad news 😭 but yeah, she's on her way out. Use policies instead, bestie.

The direct options give a more direct access to the firewall. These options require the user to know basic iptables concepts, i.e. table (filter/mangle/nat/...), chain (INPUT/OUTPUT/FORWARD/...), commands (-A/-D/-I/...), parameters (-p/-s/-d/-j/...) and targets (ACCEPT/DROP/REJECT/...). So like, hard mode iptables lore 🧠✨

Direct options should be used only as a last resort when it's not possible to use, for example, --add-service=service or --add-rich-rule='rule'. Last resort only, she said what she said πŸ’…

⚠️ Warning: Direct rules behavior is different depending on the value of FirewallBackend. See CAVEATS in firewalld.direct(5).

Okay bestie, listen β€” the first argument of each one of these options has to be ipv4, ipv6 or eb. With ipv4 it's for IPv4 (iptables(8)), with ipv6 it's for IPv6 (ip6tables(8)), and with eb it's for ethernet bridges (ebtables(8)). Periodt, that's the rules of the game. πŸŽ€


  • [--permanent] --direct --get-all-chains β€” grabs every chain that's been added to all the tables. Note bestie: this one only cares about chains you previously added with --direct --add-chain. Nothing else. πŸ’…
  • [--permanent] --direct --get-chains { ipv4 | ipv6 | eb } table β€” gets every chain added to table as a space separated list. Again, only chains you previously added with --direct --add-chain show up here. rigorous.
  • [--permanent] --direct --add-chain { ipv4 | ipv6 | eb } table chain β€” adds a brand new chain called chain to table. Pls make sure there's no other chain with that name already, okay? don't be messy. 😭

There are already basic chains built for you to use with direct options β€” for example the INPUT_direct chain (run iptables-save | grep direct and you'll see all of them, iykyk). These chains get jumped into before the chains for zones, which means every rule you put into INPUT_direct gets checked before the rules in zones. priority queen behavior. πŸ‘‘

  • [--permanent] --direct --remove-chain { ipv4 | ipv6 | eb } table chain β€” removes the chain named chain from table. Only chains previously added with --direct --add-chain can be removed this way, no sneaky exceptions. πŸ’€
  • [--permanent] --direct --query-chain { ipv4 | ipv6 | eb } table chain β€” tells you whether a chain named chain exists in table. Returns 0 if true, 1 otherwise. And yes, only chains previously added with --direct --add-chain count here. πŸ¦‹
  • [--permanent] --direct --get-all-rules β€” gets every rule added to every chain in every table, as a newline separated list of the priority and arguments. Only rules previously added with --direct --add-rule, so don't expect it to manifest anything else. ✨
  • [--permanent] --direct --get-rules { ipv4 | ipv6 | eb } table chain β€” gets every rule added to chain in table, as a newline separated list of the priority and arguments. Again: only rules previously added with --direct --add-rule. consistent queen.
  • [--permanent] --direct --add-rule { ipv4 | ipv6 | eb } table chain priority args β€” adds a rule with the arguments args to chain in table, with priority priority. πŸŽ€

The priority is what orders your rules, bestie. Priority 0 means the rule goes on top of the chain, and with a higher priority the rule gets added further down. Rules with the same priority sit on the same level, and the order of those is not fixed and may change. So if you need a rule to definitely land after another one, give the first one a low priority and the following one a higher priority. That's the whole trick, no cap. 🌈

  • [--permanent] --direct --remove-rule { ipv4 | ipv6 | eb } table chain priority args β€” removes the rule with priority and the arguments args from chain in table. Only rules previously added with --direct --add-rule can be removed this way. linear, clean, iconic. πŸ’…
  • [--permanent] --direct --remove-rules { ipv4 | ipv6 | eb } table chain β€” removes all rules in the chain named chain that exists in table. This one only concerns rules previously added with --direct --add-rule in this chain. bye bye rules 🫢
  • [--permanent] --direct --query-rule { ipv4 | ipv6 | eb } table chain priority args β€” returns whether a rule with priority and the arguments args exists in chain in table. Returns 0 if true, 1 otherwise. And yes, only rules previously added with --direct --add-rule are in scope here. πŸ‘‘
  • --direct --passthrough { ipv4 | ipv6 | eb } args β€” passes a command straight through to the firewall. args can be all iptables, ip6tables and ebtables command line arguments. Heads up bestie: this command is untracked, which means firewalld is not able to provide information about this command later on β€” not even a listing of the untracked passthroughs. it's giving mystery πŸ•΅οΈβ€β™€οΈ (there is no --permanent here, so don't try it.)
  • [--permanent] --direct --get-all-passthroughs β€” gets all passthrough rules as a newline separated list of the ipv value and arguments. ✨
  • [--permanent] --direct --get-passthroughs { ipv4 | ipv6 | eb } β€” gets all passthrough rules for the ipv value as a newline separated list of the priority and arguments. 🌸
  • [--permanent] --direct --add-passthrough { ipv4 | ipv6 | eb } args β€” adds a passthrough rule with the arguments args for the ipv value. πŸ’–
  • [--permanent] --direct --remove-passthrough { ipv4 | ipv6 | eb } args β€” removes a passthrough rule with the arguments args for the ipv value. πŸ’€
  • [--permanent] --direct --query-passthrough { ipv4 | ipv6 | eb } args β€” returns whether a passthrough rule with the arguments args exists for the ipv value. Returns 0 if true, 1 otherwise. πŸ¦‹

🚨 Panic Options 🚨

  • --panic-on β€” enables panic mode. All incoming and outgoing packets are dropped, and active connections will expire. Enable this only if there are serious problems with your network environment β€” for example if the machine is getting hacked in. 🚨😭

This is a runtime only change.

  • --panic-off β€” disables panic mode. After disabling it, established connections might work again, if panic mode was enabled for a short period of time. we're so back. 🫢

This is a runtime only change.

  • --query-panic β€” returns 0 if panic mode is enabled, 1 otherwise. vibe check on the panic. πŸ’…

🌸 EXAMPLES 🌸

πŸ’– Example 1

Enable the http service in the default zone. This is a runtime only change, i.e. effective until restart.

firewall-cmd --add-service=http

🌈 Example 2

Enable port 443/tcp immediately and permanently in the default zone. To make the change effective immediately and also after restart we need two commands. The first command makes the change in runtime configuration, i.e. makes it effective immediately, until restart. The second command makes the change in permanent configuration, i.e. makes it effective after restart. two commands, one slay. πŸ‘‘

firewall-cmd --add-port=443/tcp
firewall-cmd --permanent --add-port=443/tcp

πŸ¦‹ UNKNOWN DESTINATIONS πŸ¦‹

Some features occur at a point in the packet processing pipeline when it's impossible to determine the destination of the packet, e.g. prerouting. As a consequence, firewalld can only use the ingress interface/source to dispatch zones and policies, and packets get dispatched without considering the egress. it's giving "where are you going? we don't know her" πŸ’€

Since the egress cannot be determined, the order of precedence is determined by the policy's priority.

The following features are subject to this behavior:

  • --add-forward-port
  • --add-rich-rule rule ... forward-port ...
  • --add-rich-rule rule ... mark ...

remember this one, bestie, it will show up in a quiz. 🌸

okay so bestie, exit codes are literally the receipts of what just happened. πŸ’…

When everything is ✨perfect✨, firewall-cmd exits with 0. Zero. Nothing. Clean. Iconic. When it fails tho? The output turns red (dramatic, we love), and the exit code is either 2 if you fumbled the command-line options, or one of the following error codes in all the other cases. Keep this list in your notes app fr fr, iykyk. πŸ“Œ

  • ALREADY_ENABLED β€” code 11, aka bestie it's already enabled πŸ™ˆ
  • NOT_ENABLED β€” code 12, it's not enabled, so…
  • COMMAND_FAILED β€” code 13, the command just did not eat πŸ’€
  • NO_IPV6_NAT β€” code 14, no IPv6 NAT happening here
  • PANIC_MODE β€” code 15, full panic mode activated 😭
  • ZONE_ALREADY_SET β€” code 16, that zone is already set
  • UNKNOWN_INTERFACE β€” code 17, the interface is a mystery to us
  • ZONE_CONFLICT β€” code 18, zones are beefing
  • BUILTIN_CHAIN β€” code 19, it's giving builtin chain energy
  • EBTABLES_NO_REJECT β€” code 20, ebtables said no reject
  • NOT_OVERLOADABLE β€” code 21, can't overload it, sorry
  • NO_DEFAULTS β€” code 22, there are no defaults
  • BUILTIN_ZONE β€” code 23, builtin zone moment
  • BUILTIN_SERVICE β€” code 24, builtin service moment
  • BUILTIN_ICMPTYPE β€” code 25, builtin icmptype moment
  • NAME_CONFLICT β€” code 26, name conflict, rude
  • NAME_MISMATCH β€” code 27, the names don't match
  • PARSE_ERROR β€” code 28, parsing said nope
  • ACCESS_DENIED β€” code 29, access denied, bye πŸ‘‹
  • UNKNOWN_SOURCE β€” code 30, unknown source
  • RT_TO_PERM_FAILED β€” code 31, rt to perm failed
  • IPSET_WITH_TIMEOUT β€” code 32, ipset with timeout
  • BUILTIN_IPSET β€” code 33, builtin ipset
  • ALREADY_SET β€” code 34, it's already set bestie
  • MISSING_IMPORT β€” code 35, missing import
  • DBUS_ERROR β€” code 36, dbus error 😡
  • BUILTIN_HELPER β€” code 37, builtin helper
  • NOT_APPLIED β€” code 38, not applied
  • INVALID_ACTION β€” code 100, that action is invalid
  • INVALID_SERVICE β€” code 101, that service is invalid
  • INVALID_PORT β€” code 102, that port is invalid
  • INVALID_PROTOCOL β€” code 103, that protocol is invalid
  • INVALID_INTERFACE β€” code 104, that interface is invalid
  • INVALID_ADDR β€” code 105, that address is invalid
  • INVALID_FORWARD β€” code 106, that forward is invalid
  • INVALID_ICMPTYPE β€” code 107, that icmptype is invalid
  • INVALID_TABLE β€” code 108, that table is invalid
  • INVALID_CHAIN β€” code 109, that chain is invalid
  • INVALID_TARGET β€” code 110, that target is invalid
  • INVALID_IPV β€” code 111, that ipv is invalid
  • INVALID_ZONE β€” code 112, that zone is invalid
  • INVALID_PROPERTY β€” code 113, that property is invalid
  • INVALID_VALUE β€” code 114, that value is invalid
  • INVALID_OBJECT β€” code 115, that object is invalid
  • INVALID_NAME β€” code 116, that name is invalid
  • INVALID_FILENAME β€” code 117, that filename is invalid
  • INVALID_DIRECTORY β€” code 118, that directory is invalid
  • INVALID_TYPE β€” code 119, that type is invalid
  • INVALID_SETTING β€” code 120, that setting is invalid
  • INVALID_DESTINATION β€” code 121, that destination is invalid
  • INVALID_RULE β€” code 122, that rule is invalid
  • INVALID_LIMIT β€” code 123, that limit is invalid
  • INVALID_FAMILY β€” code 124, that family is invalid
  • INVALID_LOG_LEVEL β€” code 125, that log level is invalid
  • INVALID_AUDIT_TYPE β€” code 126, that audit type is invalid
  • INVALID_MARK β€” code 127, that mark is invalid
  • INVALID_CONTEXT β€” code 128, that context is invalid
  • INVALID_COMMAND β€” code 129, that command is invalid
  • INVALID_USER β€” code 130, that user is invalid
  • INVALID_UID β€” code 131, that uid is invalid
  • INVALID_MODULE β€” code 132, that module is invalid
  • INVALID_PASSTHROUGH β€” code 133, that passthrough is invalid
  • INVALID_MAC β€” code 134, that mac is invalid
  • INVALID_IPSET β€” code 135, that ipset is invalid
  • INVALID_ENTRY β€” code 136, that entry is invalid
  • INVALID_OPTION β€” code 137, that option is invalid
  • INVALID_HELPER β€” code 138, that helper is invalid
  • INVALID_PRIORITY β€” code 139, that priority is invalid
  • INVALID_POLICY β€” code 140, that policy is invalid
  • INVALID_LOG_PREFIX β€” code 141, that log prefix is invalid
  • INVALID_NFLOG_GROUP β€” code 142, that nflog group is invalid
  • INVALID_NFLOG_QUEUE β€” code 143, that nflog queue is invalid
  • INVALID_SOURCE β€” code 144, that source is invalid
  • MISSING_TABLE β€” code 200, missing table
  • MISSING_CHAIN β€” code 201, missing chain
  • MISSING_PORT β€” code 202, missing port
  • MISSING_PROTOCOL β€” code 203, missing protocol
  • MISSING_ADDR β€” code 204, missing addr
  • MISSING_NAME β€” code 205, missing name
  • MISSING_SETTING β€” code 206, missing setting
  • MISSING_FAMILY β€” code 207, missing family

aaaand here's the rest of the exit-code lineup, bestie β€” the dramatic finale of the table from earlier:

  • RUNNING_BUT_FAILED β€” 251 😭
  • NOT_RUNNING β€” 252 πŸ’€
  • NOT_AUTHORIZED β€” 253 πŸ”’
  • UNKNOWN_ERROR β€” 254 πŸ™ˆ

okay so special tea for the --query-* options: successful queries return 0, unsuccessful ones return 1, and if an actual error happened, then the table above is what applies. periodt. πŸ’…


πŸ‘€ SEE ALSO πŸ‘€

go read these next, they're all iconic:


πŸ“ NOTES πŸ“


πŸ’– AUTHORS πŸ’–

  • Thomas Woerner <twoerner@redhat.com> β€” Developer
  • Jiri Popelka <jpopelka@redhat.com> β€” Developer
  • Eric Garver <eric@garver.life> β€” Developer

and that's a wrap on this absolute saga πŸ’« this page comes from firewalld 2.5.2, and it's the FIREWALL-CMD(1) manual. no cap, you made it to the end, ily 🫢✨

πŸ“¦ where this page comes from