The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 2,465 other followers

firewalld: show interfaces with their zone details and show zones in use

Posted by jpluimers on 2021/08/26

A while ago openSUSE switched to firewalld as a fronte-end for iptables. Tumbleweed was first in 2018, so I wrote a reminder: On my research list: migrate from OpenSuSE SuSEfirewall2 to firewalld « The Wiert Corner – irregular stream of stuff.

The core concept of firewalld is zones, which some people find hard to understand: [Archive.is/WayBack] Firewalld on Leap 15 – why is it so complicated ? : openSUSE.

Another concept is interfaces and how they bind to zones. [Wayback] Masquerading and Firewalls | Security Guide | openSUSE Leap 15.2 shows more of that.

The final concept is services that bind one or more aspects (like ports or addresses) to a service name [Wayback] Documentation – Manual Pages – firewalld.service | firewalld.

Other interesting bits of information:

Below are some examples on what I learned, especially finding details about active interfaces and the zones they are bound to.

All of them are based on:

  • the xargs shell trick (I known you can do some of them without the trick, but I try to use common patterns in my solution so I do not have to remember which boundary case fails
  • the echo -n trick to skip the newline output
  • the [WayBack] firewall-cmd options (which kind of care commands)
    • --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.

    • --list-interfaces:

      List interfaces that are bound to zone zone as a space separated list. If zone is omitted, default zone will be used.

    • --get-zone-of-interface=<zone>:

      Print the name of the zone the interface is bound to or no zone.

    • --info-zone=<zone> (which shows far more information than the manual indicates):

      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 ..

Two more notes before the examples:

  1. My first hunch was to use --list-all-zones, but that shows details of all un-used zones as well.
  2. I am not fully sure about the --list-interfaces to list *all* interfaces. I might replace this later with ls /sys/class/net (see [WayBack] linux – List only the device names of all available network interfaces – Super User).

Other useful commands

Besides lising zones and interfaces, you might be interested in services and ports:

# firewall-cmd --list-services
dhcpv6-client ssh
# firewall-cmd --list-ports

List used zones

The first only shows the zone names

# firewall-cmd --list-interfaces | xargs -I {} sh -c 'firewall-cmd --get-zone-of-interface={}'
public

The second both zones and interfaces:

# firewall-cmd --get-active-zones 
public
  interfaces: ens192

When there are no bound interfaces

OpenSuSE by default does not bind interfaces to zones; it means any interface uses the default zone. That means the --list-interfaces commands in this blog post fail.

You can check this behaviour by running this command:

# ls /sys/class/net | xargs -I {} sh -c 'echo -n "interface {} has zone " ; firewall-cmd --get-zone-of-interface={} | xargs -I [] sh -c "echo [] ; firewall-cmd --info-zone=[]"'
interface eth0 has zone no zone
interface lo has zone no zone
interface wlan0 has zone no zone

Alternatives:

  1. Finding the default zone
    # firewall-cmd --get-default-zone
    public
    
  2. Details of the default zone
    # firewall-cmd --info-zone=$(firewall-cmd --get-default-zone)
    public
      target: default
      icmp-block-inversion: no
      interfaces: 
      sources: 
      services: dhcpv6-client ssh
      ports: 
      protocols: 
      masquerade: no
      forward-ports: 
      source-ports: 
      icmp-blocks: 
      rich rules: 

You can see that here the public zone is marked default which means it binds to any interface that is not bound to a specific zone.

List used zone details

# firewall-cmd --list-interfaces | xargs -I {} sh -c 'firewall-cmd --get-zone-of-interface={} | xargs -I [] sh -c "firewall-cmd --info-zone=[]"'
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

List interfaces and their zones:

# firewall-cmd --list-interfaces | xargs -I {} sh -c 'echo -n "interface {} has zone " ; firewall-cmd --get-zone-of-interface={}'
interface ens192 has zone public

List interfaces and their zone details:

# firewall-cmd --list-interfaces | xargs -I {} sh -c 'echo -n "interface {} has zone " ; firewall-cmd --get-zone-of-interface={} | xargs -I [] sh -c "echo [] ; firewall-cmd --info-zone=[]"'
interface ens192 has zone public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens192
  sources: 
  services: dhcpv6-client ssh
  ports: 
  protocols: 
  masquerade: no
  forward-ports: 
  source-ports: 
  icmp-blocks: 
  rich rules: 

Verifying if dns service is available, then allow it on public

Verify if a DNS is in the enabled services:

# firewall-cmd --list-services
dhcpv6-client ssh

Here no DNS service is enabled, so I need to figure out if any DNS service is available to be enabled.

This lists all the services that can be enabled in a zone:

# firewall-cmd --get-services

On my system, this returned the following list:

RH-Satellite-6 amanda-client amanda-k5-client amqp amqps apcupsd audit bacula bacula-client bb bgp bitcoin bitcoin-rpc bitcoin-testnet bitcoin-testnet-rpc bittorrent-lsd ceph ceph-mon cfengine cockpit condor-collector ctdb dhcp dhcpv6 dhcpv6-client distcc dns dns-over-tls docker-registry docker-swarm dropbox-lansync elasticsearch etcd-client etcd-server finger freeipa-4 freeipa-ldap freeipa-ldaps freeipa-replication freeipa-trust ftp ganglia-client ganglia-master git grafana gre http https imap imaps ipp ipp-client ipsec irc ircs iscsi-target isns jenkins kadmin kdeconnect kerberos kibana klogin kpasswd kprop kshell ldap ldaps libvirt libvirt-tls lightning-network llmnr managesieve matrix mdns memcache minidlna mongodb mosh mountd mqtt mqtt-tls ms-wbt mssql murmur mysql nfs nfs3 nmea-0183 nrpe ntp nut openvpn ovirt-imageio ovirt-storageconsole ovirt-vmconsole plex pmcd pmproxy pmwebapi pmwebapis pop3 pop3s postgresql privoxy prometheus proxy-dhcp ptp pulseaudio puppetmaster quassel radius rdp redis redis-sentinel rpc-bind rsh rsyncd rtsp salt-master samba samba-client samba-dc sane sip sips slp smtp smtp-submission smtps snmp snmptrap spideroak-lansync spotify-sync squid ssdp ssh steam-streaming svdrp svn syncthing syncthing-gui synergy syslog syslog-tls telnet tentacle tftp tftp-client tile38 tinc tor-socks transmission-client upnp-client vdsm vnc-server wbem-http wbem-https wsman wsmans xdmcp xmpp-bosh xmpp-client xmpp-local xmpp-server zabbix-agent zabbix-server

I was searching to see if dns was available, so I split the string with tr, then searced with grep:

# firewall-cmd --get-services | tr " " "\n" | grep dns
dns
dns-over-tls
mdns

To get details, use the firewall-cmd --info-service=servicename like this:

# firewall-cmd --get-services | tr " " "\n" | grep dns | xargs -I [] sh -c "firewall-cmd --info-service=[]"
dns
  ports: 53/tcp 53/udp
  protocols: 
  source-ports: 
  modules: 
  destination: 
  includes: 
dns-over-tls
  ports: 853/tcp
  protocols: 
  source-ports: 
  modules: 
  destination: 
  includes: 
mdns
  ports: 5353/udp
  protocols: 
  source-ports: 
  modules: 
  destination: ipv4:224.0.0.251 ipv6:ff02::fb
  includes: 

So for named (bind), I need the dns service to be enabled:

# firewall-cmd --zone=public --add-service=dns --permanent
success

Now a –list-services will not show dns as we changed the --permanent configuration, not the current configuration:

# firewall-cmd --list-services
dhcpv6-client ssh

So you need to --reload the --permanent settings:

# firewall-cmd --list-services --permanent
dhcpv6-client dns ssh
# firewall-cmd --reload
success
# firewall-cmd --list-services
dhcpv6-client dns ssh

–jeroen

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

 
%d bloggers like this: