Checking firewall status on Linux ensures that only intended network traffic reaches exposed services, reducing the risk of accidental open ports or silently blocked applications. Regular visibility into which firewall framework is active and what it believes the policy to be is essential for troubleshooting and hardening.

Most modern systems rely on the kernel’s netfilter framework, exposed through tools such as ufw (Uncomplicated Firewall), firewalld, nftables, or legacy iptables. Each layer provides its own status and listing commands, and the most accurate picture usually comes from combining service status via systemd with the firewall tool’s own summary of active rules and policies.

Viewing firewall status generally requires sudo-level privileges and a terminal on the target host, but the commands below only read configuration and counters. Running multiple firewall frameworks simultaneously can create overlapping rules, so correlating service status with the actual rule listings avoids misinterpreting whether traffic is truly blocked or allowed.

Steps to check firewall status:

  1. Open a terminal session on the target Linux system with sudo privileges.
    $ whoami
    root

    Refreshing sudo credentials up front avoids repeated password prompts while running status commands.

  2. Check the ufw service status on systems that use the Uncomplicated Firewall.
    $ systemctl status ufw --no-pager | head -n 8
    * ufw.service - Uncomplicated firewall
         Loaded: loaded (/usr/lib/systemd/system/ufw.service; enabled; preset: enabled)
         Active: inactive (dead)
           Docs: man:ufw(8)

    If the unit is reported as

    inactive

    ,

    failed

    , or not found, ufw is not currently controlling packet filtering.

  3. Display detailed ufw status and rule summary when ufw is installed.
    $ ufw status verbose
    Status: active
    Logging: on (low)
    Default: deny (incoming), allow (outgoing), deny (routed)
    New profiles: skip
    
    To                         Action      From
    --                         ------      ----
    22/tcp (OpenSSH)           ALLOW IN    Anywhere                  
    1194/udp                   ALLOW IN    Anywhere                  
    22/tcp (OpenSSH (v6))      ALLOW IN    Anywhere (v6)             
    1194/udp (v6)              ALLOW IN    Anywhere (v6)             

    The

    Default:

    line shows the base policy, while the table lists explicit allows or denies per port and address.

  4. Check the firewalld service status on systems that use firewalld instead of ufw.
    $ systemctl status firewalld --no-pager | head -n 12
    * firewalld.service - firewalld - dynamic firewall daemon
         Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled; preset: enabled)
         Active: inactive (dead) since Mon 2026-01-12 23:54:24 UTC; 15min ago
       Duration: 201ms
           Docs: man:firewalld(1)
        Process: 3488 ExecStart=/usr/sbin/firewalld --nofork --nopid (code=exited, status=0/SUCCESS)
       Main PID: 3488 (code=exited, status=0/SUCCESS)
            CPU: 175ms
    
    Jan 12 23:54:24 host.example.net systemd[1]: Started firewalld.service - firewalld - dynamic firewall daemon.
    Jan 12 23:54:24 host.example.net firewalld[3488]: ERROR: 'python-nftables' failed: internal:0:0-0: Error: Could not process rule: No such file or directory

    An

    active (running)

    state indicates that zones and rules are being enforced by firewalld.

  5. Show firewalld runtime status and active zones.
    $ firewall-cmd --state
    not running
    $ firewall-cmd --get-active-zones
    FirewallD is not running
    $ firewall-cmd --list-all
    FirewallD is not running

    The active zone’s

    services:

    and

    ports:

    lines reveal which ports are allowed for each interface.

  6. Inspect the nftables ruleset on systems using nftables directly as the primary firewall.
    $ sudo nft list ruleset | head -n 40
    table ip filter {
    	chain ufw-before-logging-input {
    	}
    
    	chain ufw-before-logging-output {
    	}
    
    	chain ufw-before-logging-forward {
    	}
    
    	chain ufw-before-input {
    		iifname "lo" counter packets 14 bytes 791 accept
    		ct state related,established counter packets 7 bytes 532 accept
    		ct state invalid counter packets 0 bytes 0 jump ufw-logging-deny
    		ct state invalid counter packets 0 bytes 0 drop
    		ip protocol icmp icmp type destination-unreachable counter packets 0 bytes 0 accept
    ##### snipped #####
    	}
    # Warning: table ip filter is managed by iptables-nft, do not touch!

    The table and chain definitions show default policies (such as

    policy drop

    ) and any accept rules for specific ports or addresses.

  7. Inspect legacy iptables filter rules when iptables is still used or emulated by compatibility layers.
    $ sudo iptables -L -n -v | head -n 20
    Chain INPUT (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
       21  1323 ufw-before-logging-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
       21  1323 ufw-before-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-after-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-after-logging-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-reject-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-track-input  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    
    Chain FORWARD (policy DROP 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         
        0     0 ufw-before-logging-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-before-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-after-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-after-logging-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-reject-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
        0     0 ufw-track-forward  0    --  *      *       0.0.0.0/0            0.0.0.0/0           
    
    Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes)
     pkts bytes target     prot opt in     out     source               destination         

    Large or complex rule sets can produce extensive output; misinterpreting default policies such as

    DROP

    versus

    ACCEPT

    may lead to incorrect assumptions about open ports.

  8. List running firewall-related services to see which frontend currently controls packet filtering.
    $ systemctl --type=service --state=running | grep -E 'ufw|firewalld|nftables'
    

    Multiple running firewall frontends on the same host can conflict; typically only one of ufw, firewalld, or a direct nftables service should manage rules.

  9. Compare firewall status with listening sockets for a specific service such as SSH.
    $ ss -tulpn | grep ':22'
    tcp   LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=3846,fd=3),("systemd",pid=1,fd=87))
    tcp   LISTEN 0      4096            [::]:22           [::]:*    users:(("sshd",pid=3846,fd=4),("systemd",pid=1,fd=88))

    If a service is listening but not reachable from another host, the firewall’s default policy or a missing allow rule is a likely culprit.

  10. Verify that the observed firewall status matches operational expectations by testing connectivity from a separate system.
    $ nc -vz 127.0.0.1 22
    Connection to 127.0.0.1 22 port [tcp/ssh] succeeded!

    A successful test when the firewall status shows an allow rule for the corresponding port indicates consistent configuration and behavior.