Firewall Uses and Setup in Linux

Firewall Uses and setup in Linux

A firewall is like a security guard standing at the entrance of a building, checking every person (packet) trying to come in or go out, and deciding — based on a rulebook — whether to let them pass, turn them away, or silently ignore them. In networking, a firewall inspects traffic flowing to, from, or through a system, and enforces rules that control what is allowed.

Linux, being the backbone of much of the internet’s infrastructure, has powerful, flexible, built-in firewall capabilities. This article explains firewall concepts from first principles and walks through practical configuration using Linux’s major firewall tools: iptables, nftables, firewalld, and ufw.


1. What a Firewall Actually Does

At its core, a firewall makes decisions based on packet attributes:

  • Source IP address — where the traffic claims to come from
  • Destination IP address — where it’s going
  • Source/destination port — which service/application it’s targeting
  • Protocol — TCP, UDP, ICMP, etc.
  • Connection state — is this a new connection, an established one, or related to an existing one?

Based on matching rules, the firewall takes an action:

ActionMeaning
ACCEPTAllow the packet through
DROPSilently discard the packet (no response sent)
REJECTDiscard the packet, but send back an error response (e.g., ICMP “port unreachable”)
LOGRecord the packet match in logs (usually combined with another action)
flowchart TD
    A[Incoming Packet] --> B{Matches a Rule?}
    B -- Yes --> C{Action: ACCEPT/DROP/REJECT}
    B -- No --> D[Default Policy Applied]
    C --> E[Packet Processed Accordingly]
    D --> E

2. Types of Firewalls

TypeDescription
Packet-filtering firewallInspects individual packets against static rules (source/dest IP, port, protocol)
Stateful firewallTracks the state of connections (new, established, related) — modern standard
Application-layer (proxy) firewallInspects traffic at Layer 7 (application data), e.g., web application firewalls
Host-based firewallRuns on an individual machine (e.g., iptables on a Linux server)
Network-based firewallDedicated appliance protecting an entire network segment (e.g., Cisco ASA, Palo Alto)

This article focuses on host-based, stateful firewalls on Linux.


3. Linux Firewall Architecture: Netfilter

Underneath every Linux firewall tool (iptables, nftables, firewalld, ufw) is the kernel subsystem called Netfilter — a framework of hooks inside the Linux kernel network stack that intercepts packets at various points (before routing, after routing, entering/leaving the system) and allows rules to be applied.

flowchart LR
    A[Packet Enters NIC] --> B[PREROUTING]
    B --> C{Routing Decision}
    C -- To Local Process --> D[INPUT]
    C -- To Another Host --> E[FORWARD]
    D --> F[Local Process]
    F --> G[OUTPUT]
    E --> H[POSTROUTING]
    G --> H
    H --> I[Packet Leaves NIC]
  • INPUT: packets destined for the local machine
  • OUTPUT: packets originating from the local machine
  • FORWARD: packets passing through the machine (when it acts as a router)
  • PREROUTING / POSTROUTING: used for NAT and packet mangling before/after routing decisions

Understanding these chains is essential because every firewall tool ultimately configures rules against them.


4. iptables — The Classic Tool

iptables has been the standard Linux firewall management tool for over two decades, and remains widely used and understood even as nftables becomes the modern kernel default.

4.1 Basic Syntax

iptables -A <chain> -p <protocol> --dport <port> -s <source> -j <action>

4.2 Common Examples

# Allow SSH (port 22) from anywhere
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Allow HTTP and HTTPS
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# Allow established/related connections (stateful behavior)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow loopback traffic (essential for many local services)
sudo iptables -A INPUT -i lo -j ACCEPT

# Drop everything else by default
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

4.3 Restricting SSH Access to a Specific IP

sudo iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

This only allows SSH from the trusted management IP 203.0.113.10, dropping all other SSH attempts.

4.4 Viewing and Saving Rules

sudo iptables -L -n -v --line-numbers
sudo iptables-save > /etc/iptables/rules.v4
sudo iptables-restore < /etc/iptables/rules.v4

Warning: iptables rules are not persistent by default — they disappear on reboot unless saved and restored via a boot service (e.g., iptables-persistent on Debian/Ubuntu).


5. nftables — The Modern Replacement

nftables is the successor to iptables, offering a cleaner syntax, better performance, and unification of IPv4/IPv6 rules into a single framework.

5.1 Basic Structure

sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input tcp dport 22 accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept

5.2 Viewing Rules

sudo nft list ruleset

5.3 Saving Configuration

sudo nft list ruleset > /etc/nftables.conf
sudo systemctl enable nftables

Example /etc/nftables.conf:

#!/usr/sbin/nft -f

table inet filter {
    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        iif lo accept
        tcp dport 22 accept
        tcp dport { 80, 443 } accept
        ip protocol icmp accept
    }
}

6. firewalld — Zone-Based Firewall Management

firewalld (common on RHEL/CentOS/Fedora) manages iptables/nftables under the hood using the concept of zones — predefined trust levels applied to network interfaces.

ZoneTrust Level
publicDefault, limited trust — typical for internet-facing interfaces
internalHigher trust — for internal LAN interfaces
dmzRestricted access for publicly reachable but isolated servers
trustedFull access — all traffic accepted

6.1 Basic Commands

sudo systemctl start firewalld
sudo systemctl enable firewalld

# Check current zone assignments
sudo firewall-cmd --get-active-zones

# Allow SSH permanently in the public zone
sudo firewall-cmd --zone=public --add-service=ssh --permanent

# Allow HTTP/HTTPS
sudo firewall-cmd --zone=public --add-service=http --permanent
sudo firewall-cmd --zone=public --add-service=https --permanent

# Reload to apply permanent rules
sudo firewall-cmd --reload

# List all rules in a zone
sudo firewall-cmd --zone=public --list-all

6.2 Allowing a Specific Port

sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

7. ufw (Uncomplicated Firewall) — Simplified iptables Frontend

ufw, common on Ubuntu/Debian systems, provides a beginner-friendly interface over iptables.

sudo apt install ufw -y

# Set default policies
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow specific services
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Allow from a specific IP only
sudo ufw allow from 203.0.113.10 to any port 22

# Enable the firewall
sudo ufw enable

# Check status
sudo ufw status verbose

8. Comparison Table: Linux Firewall Tools

ToolUnderlying EngineComplexityBest For
iptablesNetfilter (legacy)Moderate–HighFine-grained manual control, legacy systems
nftablesNetfilter (modern)ModerateModern replacement for iptables, better performance
firewalldiptables/nftables backendLow–ModerateRHEL/CentOS/Fedora, zone-based dynamic management
ufwiptables backendLowBeginners, Ubuntu/Debian desktops and simple servers

9. Python: Automating Firewall Rule Auditing

Firewall rules can drift over time. This script checks whether critical ports are properly restricted using iptables.

import subprocess

def get_iptables_rules():
    result = subprocess.run(
        ["sudo", "iptables", "-L", "INPUT", "-n", "-v"],
        capture_output=True, text=True
    )
    return result.stdout

def audit_ssh_exposure():
    rules = get_iptables_rules()
    if "dpt:22" in rules and "0.0.0.0/0" in rules:
        print("WARNING: SSH (port 22) appears open to the entire internet!")
    else:
        print("SSH exposure looks restricted.")

audit_ssh_exposure()

This kind of script is a starting point for building automated compliance checks in CI/CD pipelines or scheduled security audits.


10. Real-World Example: Hardening a Public Web Server

A company deploys a public-facing Linux web server. The firewall policy should:

  1. Deny all inbound traffic by default.
  2. Allow HTTP (80) and HTTPS (443) from anywhere — since it’s a public web server.
  3. Allow SSH (22) only from the office’s static IP — not the whole internet.
  4. Allow established/related traffic so return traffic for outbound connections isn’t blocked.
  5. Log dropped packets for security monitoring.
sudo nft add table inet filter
sudo nft add chain inet filter input { type filter hook input priority 0 \; policy drop \; }
sudo nft add rule inet filter input ct state established,related accept
sudo nft add rule inet filter input iif lo accept
sudo nft add rule inet filter input tcp dport { 80, 443 } accept
sudo nft add rule inet filter input ip saddr 203.0.113.10 tcp dport 22 accept
sudo nft add rule inet filter input log prefix \"DROPPED: \" drop

This layered approach — deny by default, allow only what’s necessary — is called the principle of least privilege, and it is the cornerstone of firewall design.


11. Best Practices

  • Always set a default deny policy on inbound traffic; explicitly allow only what’s required.
  • Allow established/related connections so return traffic isn’t blocked (stateful filtering).
  • Restrict management access (SSH, RDP, admin panels) to specific trusted IP addresses, not the whole internet.
  • Log dropped/rejected packets for later analysis, but avoid excessive logging that fills up disk space.
  • Persist firewall rules across reboots (iptables-persistent, nftables.service, or firewalld/ufw which persist automatically).
  • Regularly audit and review rules — remove stale or unused rules.
  • Combine host-based firewalls (iptables/nftables) with network-based firewalls for defense in depth.
  • Use rate limiting to mitigate brute-force and DoS attempts against exposed services.

12. Troubleshooting Firewall Issues

SymptomLikely CauseFix
Service unreachable despite app runningPort not allowed in firewallCheck with sudo iptables -L -n or sudo firewall-cmd --list-all
SSH locked out after enabling firewallDefault policy set to DROP before allowing SSHAlways allow SSH before setting default deny
Rules disappear after rebootRules not persistedUse netfilter-persistent save or enable nftables.service
Outbound connections failingOUTPUT chain policy too restrictiveCheck iptables -L OUTPUT -n and allow necessary outbound traffic
firewalld changes not applyingForgot --permanent or --reloadAlways follow permanent changes with firewall-cmd --reload

Useful diagnostic commands:

sudo iptables -L -n -v --line-numbers
sudo nft list ruleset
sudo firewall-cmd --list-all
sudo ufw status verbose
sudo tail -f /var/log/syslog | grep -i drop

13. Summary

Linux firewalls — whether managed via iptables, nftables, firewalld, or ufw — all ultimately configure the kernel’s Netfilter framework to inspect and control traffic based on source, destination, port, protocol, and connection state. The universal principle across all tools is the same: deny by default, allow only what is explicitly necessary, track connection state, and log for visibility.

Mastering at least one of these tools deeply (most engineers start with iptables or ufw, then grow into nftables) is an essential skill for securing any Linux-based server or network device.


14. Deep Dive: NAT with iptables

Beyond simple packet filtering, Linux firewalls commonly handle NAT (Network Address Translation), especially when a Linux box acts as a router or gateway for a private network.

14.1 Enabling IP Forwarding

Before a Linux system can route/NAT traffic between interfaces, IP forwarding must be enabled at the kernel level:

echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward

For persistence across reboots:

echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

14.2 Masquerading (Source NAT) for Internet-Sharing Gateway

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o eth1 -m state --state ESTABLISHED,RELATED -j ACCEPT

This configuration allows devices on an internal interface (eth1) to reach the internet through eth0, with their private source IP addresses translated (masqueraded) to the gateway’s public IP — the same fundamental mechanism used by consumer home routers.

14.3 Port Forwarding (Destination NAT)

sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80
sudo iptables -A FORWARD -p tcp -d 192.168.1.100 --dport 80 -j ACCEPT

This forwards incoming traffic on port 8080 to an internal web server at 192.168.1.100:80 — commonly used to expose an internal service through a single public-facing gateway without directly exposing the internal host.


15. Deep Dive: Intrusion Detection with Firewall Logging + fail2ban Integration

A firewall alone only enforces static rules — it doesn’t adapt based on observed behavior. Combining firewall logging with a tool like fail2ban (introduced briefly in the network security article) creates a dynamic, self-adjusting defense.

sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 3/minute --limit-burst 5 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -j DROP

This rate-limits new SSH connection attempts to 3 per minute (with a small burst allowance), throttling brute-force attempts directly at the firewall layer, before they ever reach the SSH daemon itself — a lighter-weight complement to fail2ban’s more sophisticated log-pattern-based banning.


16. Deep Dive: Comparing Linux Host Firewalls to Network Firewalls

It’s worth clarifying how a host-based Linux firewall relates to a dedicated network firewall appliance (like a Cisco ASA, Palo Alto, or Fortinet device), since both are commonly used together in real deployments rather than as substitutes for each other.

AspectLinux Host Firewall (iptables/nftables)Dedicated Network Firewall Appliance
ScopeProtects the single host it runs onProtects an entire network segment/perimeter
PerformanceLimited by host CPU/kernel resourcesOften has dedicated hardware acceleration
GranularityExtremely fine-grained per-host controlBroad segment-level policy enforcement
Typical RoleLast line of defense on each server (“defense in depth”)First line of defense at the network edge
Application-layer inspectionLimited (basic tools); usually paired with fail2ban/IDSOften includes deep packet inspection, IPS, and application-aware filtering natively

Best practice architecture layers both: a network firewall/perimeter appliance enforces broad segmentation and internet-facing policy, while individual Linux hosts run their own local firewall as an additional layer — meaning even if an attacker breaches the network perimeter, they still face host-level restrictions on each individual server, directly reinforcing the defense-in-depth principle discussed in the network security article.


17. Common Misconceptions

  • “My cloud security group/firewall already protects the server, so I don’t need iptables too.” Cloud security groups are a valuable first layer, but relying on a single control anywhere in your architecture is a defense-in-depth violation; a misconfigured security group rule (a common real-world mistake) leaves the server fully exposed if there’s no host-level firewall as a second layer.
  • “DROP and REJECT are basically the same thing.” DROP silently discards packets with no response, which can help obscure which ports are actually closed versus filtered (useful against reconnaissance scans); REJECT sends back an explicit error, which is friendlier for legitimate internal traffic troubleshooting but reveals more information to a potential attacker probing the host.
  • “Once I set up my firewall rules, I never need to revisit them.” Application deployments change constantly — new services get added, old ones get decommissioned — and firewall rules that aren’t periodically audited tend to accumulate stale, overly permissive entries over time (sometimes called “firewall rule sprawl”).
  • “iptables and nftables can run simultaneously without conflict.” While technically both can coexist on the same kernel in certain configurations, mixing them in production is a common source of confusing, hard-to-debug behavior; pick one framework per host and stick with it consistently.

Further Reading

Total
3
Shares
1 comment

Leave a Reply

Previous Post
Secure Networking

Securing a Network from Unauthorized Access

Next Post
Nmap IPv6 Cheat Sheet

Nmap IPv6 Cheat Sheet

Related Posts