Switch Language
Toggle Theme

Firewall Configuration: UFW, iptables, and Security Policy Design

3 AM. An alert SMS dragged me from sleep—a test environment database showed abnormal traffic. I logged into the server and found the firewall was completely disabled. After turning it on, I saw a mess of test configurations, and SSH had no rate limiting. Honestly, I was pretty stressed.

This made me realize something: many people (including myself) either copy-paste a few commands when configuring firewalls, or don’t even know the difference between UFW and iptables. Systematically designing security policies? Forget about it. Let’s talk about this properly today.


What’s Really Going on with Linux Firewalls

Before talking about firewalls, let’s clear up a commonly confused concept: Netfilter. Many people think iptables is the firewall. Wrong.

Netfilter is the network packet processing framework inside the Linux kernel. It places several “hooks” at key positions in the kernel protocol stack. Every passing network packet triggers these hooks, where you can mount your own processing logic—like intercepting, modifying, or logging.

iptables, UFW, nftables are just user-space configuration interfaces. The rules you write with them get converted into formats Netfilter understands and executed in the kernel.

Think of it this way: Netfilter is the valve system buried under the road, iptables is the old manual knob, and UFW is a modern control panel with a touchscreen—all can turn valves, but the operation is completely different.

Evolution of User-Space Tools

Linux firewall tools have changed a lot in recent years:

  • iptables: The classic tool, around since 2000. Directly operates Netfilter, complex syntax but powerful.
  • nftables: iptables’ modern replacement, introduced in 2014. More unified syntax, better performance, new Ubuntu versions default to it as backend.
  • UFW (Uncomplicated Firewall): Simplified tool launched by Ubuntu in 2008. Still iptables/nftables underneath, but commands simple enough to make you cry with joy.
  • firewalld: Red Hat’s dynamic firewall management tool, supports runtime rule changes without interrupting connections.

This article focuses on UFW and iptables since they’re most used in actual operations. nftables is more modern, but concepts overlap with iptables—once you learn iptables, nftables isn’t hard.


UFW: Making Firewall Configuration Less Painful

Anyone who’s used iptables knows the anxiety when writing rules—terrified that one wrong parameter will block SSH and lock you out.

UFW’s design philosophy is “simplicity first.” One command opens a port, no need to memorize -A INPUT -p tcp --dport 22 -j ACCEPT syntax that feels anti-human.

Compare:

iptables:

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j ACCEPT

UFW:

ufw allow ssh

Difference is obvious. UFW automatically handles protocol, state detection, IPv6 details—you just say “I want to open SSH.”

Basic Configuration: From Scratch

New server in hand, firewall configuration should go like this:

Step 1: Set Default Policies

Default policies decide “what to do when no rules match.” Security’s basic principle: deny all incoming, allow all outgoing.

sudo ufw default deny incoming   # Deny all inbound connections
sudo ufw default allow outgoing   # Allow all outbound connections

This way, unless you explicitly allow, no external requests can get in. Many people get lazy, set default to allow, and their server becomes a house with doors wide open for anyone to stroll in.

Step 2: Open Necessary Ports

Here’s a pitfall: Must open SSH first before enabling firewall! Otherwise your remote connection instantly drops.

sudo ufw allow ssh        # Open SSH (port 22)
sudo ufw allow 80/tcp     # HTTP
sudo ufw allow 443/tcp    # HTTPS

If running other services, like custom SSH port (say 2222):

sudo ufw allow 2222/tcp

Step 3: Enable Firewall

sudo ufw enable

System will warn: “This may disrupt existing ssh connections”—don’t panic, if you ran allow ssh earlier, no problem. Type y to confirm.

Step 4: Check Status

sudo ufw status verbose

Output looks like:

Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW IN    Anywhere
80/tcp                     ALLOW IN    Anywhere
443/tcp                    ALLOW IN    Anywhere

Seeing Status: active means firewall is live.

Advanced Tips: Making Configuration More Secure

Application Profiles (App Profiles)

UFW has a super useful feature—App Profiles. Many common services (Nginx, Apache, OpenSSH) have predefined configs.

Check available profiles:

sudo ufw app list

Output might include:

Available applications:
  Apache
  Apache Full
  Apache Secure
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH

Directly use app name to open ports:

sudo ufw allow 'Nginx Full'

This command opens both HTTP (80) and HTTPS (443), saves you writing two rules manually.

Rate Limiting: Prevent Brute Force

SSH ports are most vulnerable to brute force attacks. UFW has built-in rate limiting:

sudo ufw limit ssh

This rule means: if an IP tries connecting more than 6 times within 30 seconds, temporarily ban it. Much safer than plain allow ssh.

Restrict Specific IP Access

Sometimes you only want specific IPs accessing a service, like database admin backend only allowing company network:

# Only allow 192.168.1.100 to access MySQL
sudo ufw allow from 192.168.1.100 to any port 3306

# Deny a malicious IP
sudo ufw deny from 203.0.113.100

Logging

Firewall logs are key for troubleshooting:

sudo ufw logging on
sudo ufw logging medium   # Log level: low/medium/high

Logs stored at /var/log/ufw.log, format looks like:

Mar 15 10:23:45 server kernel: [UFW BLOCK] IN=eth0 OUT= MAC=... SRC=203.0.113.100 DST=... PROTO=TCP SPT=54321 DPT=22

Seeing [UFW BLOCK] means firewall intercepted this request.

UFW’s Limitations

UFW is handy but has boundaries:

  • NAT and Port Forwarding: Limited support, complex configs still need iptables
  • Complex Rule Chains: Doesn’t support custom chains, nested conditions
  • Content Filtering: Can’t do it (like filtering malicious payloads in HTTP requests)

If your needs exceed these boundaries, switch to iptables.


iptables: The Tool for Fine-Grained Control

Understanding iptables Architecture

iptables is more complex than UFW, but underlying logic is actually clear. Key is understanding “table-chain-rule” three-layer structure.

Tables

Different tables handle different task types:

  • filter table (default): Packet filtering, decide accept or reject
  • nat table: Address translation (NAT), rewrite source/destination addresses
  • mangle table: Modify packet’s TOS, TTL metadata
  • raw table: Configure exceptions, bypass connection tracking

Most scenarios only use filter table, so we default to operating it.

Chains

Chains are rule collections, executed in order. Filter table has five built-in chains:

  • INPUT: Inbound packets (destination is local machine)
  • OUTPUT: Outbound packets (source is local machine)
  • FORWARD: Forwarded packets (machine is just transit)
  • PREROUTING: Pre-routing processing
  • POSTROUTING: Post-routing processing

Daily config mainly uses INPUT and OUTPUT, FORWARD used when acting as router or gateway.

Rule Matching Order

Rules match from top to bottom, first match executes action, later rules not checked.

Example:

iptables -A INPUT -s 192.168.1.100 -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -j DROP

For these two rules, 192.168.1.100 matches first ACCEPT, passes directly, won’t check second rule. But if order reversed, 192.168.1.100 gets blocked by first DROP, never reaches second rule.

This is iptables config’s core principle: more specific rules go first, more general rules go later.

Basic Syntax Breakdown

iptables command basic format:

iptables -t table_name -A chain_name match_conditions -j action

Common parameters:

  • -t: Specify table (default filter, can omit)
  • -A: Append rule to chain end
  • -I: Insert rule at specified position
  • -D: Delete rule
  • -L: List rules
  • -F: Flush all rules
  • -P: Set default policy

Match Conditions

  • -s: Source IP address (like -s 192.168.1.100)
  • -d: Destination IP address
  • -p: Protocol (tcp, udp, icmp)
  • --sport: Source port
  • --dport: Destination port
  • -i: Inbound interface (like -i eth0)
  • -o: Outbound interface
  • -m state --state: Connection state detection

Actions (Target)

  • ACCEPT: Accept packet
  • DROP: Silently drop (return nothing)
  • REJECT: Reject and return error message
  • LOG: Log (doesn’t block, continues matching later rules)
  • RETURN: Stop current chain, return to upper chain

Practical Configuration: Secure Server Firewall

Here’s a complete production environment configuration flow:

Step 1: Clear Existing Rules

New servers often have default rules, clean them first:

sudo iptables -F        # Clear all rules
sudo iptables -X        # Delete all custom chains
sudo iptables -t nat -F
sudo iptables -t mangle -F

Step 2: Set Default Policies

Like UFW, default deny inbound:

sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

Step 3: Allow Established Connections

This rule is crucial: allow response traffic and established connection data through.

sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

What does this mean? When you visit a website, outgoing request is OUTPUT (default ACCEPT), website’s reply is INPUT. Without this rule, reply packets get DROP, you receive nothing.

ESTABLISHED means connection already established, RELATED means related connections (like FTP data connection).

Step 4: Open Necessary Ports

# SSH
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# HTTP
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT

# HTTPS
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT

Step 5: Restrict ICMP (Optional)

ICMP is ping’s protocol. Some security policies disable ping:

# Allow ping
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Or deny ping
sudo iptables -A INPUT -p icmp -j DROP

Step 6: Logging

Add a LOG rule before DROP for troubleshooting:

sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables denied: " --log-level 4

--limit 5/min prevents log explosion, max 5 entries per minute.

Step 7: Final DROP

Default policy already DROP, but explicitly writing one is clearer:

sudo iptables -A INPUT -j DROP

Step 8: Save Rules

iptables rules default to memory only, lost on reboot. Ubuntu/Debian can use iptables-persistent:

sudo apt install iptables-persistent
sudo netfilter-persistent save

Or manually save:

sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6  # IPv6 rules

Checking Rule Status

sudo iptables -L -n -v --line-numbers
  • -n: Numeric display (don’t resolve domains, faster)
  • -v: Verbose mode (show packet counts)
  • --line-numbers: Show rule numbers

Output example:

Chain INPUT (policy DROP 0 packets, 0 bytes)
num  pkts bytes target     prot opt in     out     source               destination
1      42  2848 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0            state ESTABLISHED,RELATED
2       0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:22
3       0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80
4       0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:443
5       0     0 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            limit: avg 5/min burst 5 LOG flags 0 level 4 prefix "iptables denied: "
6       0     0 DROP       all  --  *      *       0.0.0.0/0            0.0.0.0/0

UFW vs iptables: Which to Choose

After all this, you might still wonder: Should I use UFW or iptables?

Core Difference: Ease vs Flexibility

DimensionUFWiptables
Command SimplicitySuper simple (ufw allow ssh)Complex (iptables -A INPUT -p tcp --dport 22 -j ACCEPT)
Learning CurveHours to masterDays to weeks for deep learning
Underlying MechanismStill iptables/nftablesDirectly operates iptables
PerformanceSame (both rely on Netfilter)Same
NAT/Port ForwardingBasic support, not enough for complexFully supported
Complex Rule ChainsNo custom chainsFully supported, multi-level nesting
App ConfigsHas App Profiles, convenientMust write rules manually
IPv6Auto handledNeed ip6tables separately
Script ManagementFits manual configBetter for scripted batch deployment

Performance Truth

Many think iptables performs better, but underlying mechanism is identical—both are Netfilter working in kernel. Only performance difference comes from rule count: more rules, slower matching. But for medium-small servers, impact is minimal.

Selection Advice

Recommend UFW for:

  • VPS, cloud servers, dedicated servers
  • Web services, API service deployment
  • No complex network needs (no NAT, port forwarding)
  • Non-professional sysadmins (don’t want to learn iptables syntax)
  • Quick security config (like emergency attack response)

Recommend iptables for:

  • Gateways, routers, VPN servers
  • Need NAT, port forwarding, load balancing
  • Complex rule chains, multi-level condition checks
  • Large-scale deployment (scripted management of dozens of servers)
  • Advanced filtering (by packet content, rate, time)
  • Ops teams (dedicated network config personnel)

Can They Mix?

Not recommended. Both operate same Netfilter rules, mixing easily causes conflicts.

Example: You opened SSH with iptables, later denied SSH with UFW, last rule wins—you’re locked out.

If must mix, remember rule order: UFW rules between before.rules and after.rules, iptables rules directly added might get overridden by UFW defaults.


Core Principles of Firewall Security Policy Design

Mastering tools is just first step, more important is designing reasonable security policies. Many add rules casually when configuring firewalls, resulting in holes everywhere.

Principle 1: Default Deny

This is security configuration’s cornerstone.

Core idea: Unless explicitly allowed, deny everything.

Opposite approach is “default allow”—open everything, then block risky ports one by one. This thinking has two problems:

  1. You don’t know all risky ports (attackers scan all 65535 ports)
  2. Missing one port leaves one vulnerability

Correct approach:

# UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing

# iptables
sudo iptables -P INPUT DROP
sudo iptables -P OUTPUT ACCEPT

Then only open ports business needs. For each port opened, ask yourself: What’s this port for? Can source IP be restricted?

Principle 2: Least Privilege

Each rule should do one thing, open minimal scope.

Port Opening:

  • ufw allow 3306 (whole world can connect MySQL)
  • ufw allow from 192.168.1.100 to any port 3306 (only allow specific IP)

Service Access:

  • ❌ Open all internal service ports
  • ✅ Only open public-facing services (Web, API), internal services via internal network or VPN

SSH Management:

  • ufw allow ssh (anyone can try login)
  • ufw allow from company_IP to any port 22 + ufw limit ssh

Principle 3: Defense-in-Depth

Firewall isn’t everything, it’s just first defense layer. Complete security system needs multiple layers:

  1. Network Layer Firewall (UFW/iptables): Block malicious traffic
  2. Application Layer Firewall (WAF): Filter SQL injection, XSS at HTTP layer
  3. Host Layer Protection (SELinux/AppArmor): Restrict process permissions
  4. Intrusion Detection (IDS/IPS): Real-time monitor abnormal behavior
  5. Regular Audits: Log analysis, vulnerability scanning

Example: Firewall opens HTTP port 80, WAF checks malicious payloads in HTTP requests, SELinux restricts web server file access. All three layers pass, attacker reaches application layer, but application has code security (input validation, permission checks).

Principle 4: Network Segmentation

Large networks can’t be one pot, must divide into zones.

Typical segmentation model:

  • DMZ (Demilitarized Zone): Public-facing services (web servers, mail servers)
  • Internal Zone: Databases, internal services, office network
  • Management Zone: Operations management, monitoring, logs

Segmentation benefits:

  1. Fault Isolation: DMZ breached, attacker must break another line to enter internal network
  2. Limit Spread: Worm virus spreads in one zone, firewall blocks cross-zone
  3. Refined Permissions: Users in different zones have different access rights

iptables config segmentation, FORWARD chain is key:

# DMZ to internal: only allow database access
iptables -A FORWARD -s dmz_network -d internal_network -p tcp --dport 3306 -j ACCEPT
iptables -A FORWARD -s dmz_network -d internal_network -j DROP

Principle 5: Regular Audit and Update

Firewall config isn’t once-and-done.

Rule Review:

  • Monthly check: Any expired rules? (test ports forgotten)
  • Quarterly assessment: After business changes, port openings reasonable?
  • Annual refactor: Clean redundant rules, optimize performance

Log Analysis:

  • Weekly check firewall logs: Which IPs blocked? Why?
  • Abnormal traffic alerts: Set thresholds, auto-notify when exceeded
  • Attack tracing: Find attack sources from logs, targeted hardening

Respond to Changes:

  • New service launch: Assess security risks before opening ports
  • Attack events: Adjust rules, block malicious IPs, add rate limits
  • Business adjustments: Remove unnecessary rules, reduce exposure

Production Environment Practical: Avoiding Pitfalls

Safe Steps in Configuration Flow

Step 1: Verify in Test Environment

Never try new rules directly on production servers. First configure in test VM or dev environment, confirm okay then go production.

Step 2: Keep SSH Backdoor

Before config, check SSH port already open. If using custom port, remember:

# UFW
ufw allow 2222/tcp  # Custom SSH port

# iptables
iptables -A INPUT -p tcp --dport 2222 -j ACCEPT

Step 3: Gradually Open Ports

Don’t open all ports at once. First open core ones (SSH), verify can login, then open Web ports, then other services.

Step 4: Record Configuration Changes

Record every firewall rule modification:

  • Modification time
  • Content changed
  • Reason for change
  • Verification result

Can use Git to manage rule config files, or document records.

Common Errors and Solutions

Error 1: SSH Lockout

Symptom: After enabling firewall, SSH disconnects, can’t login anymore.

Cause: Didn’t open SSH port first, or rule order wrong (DROP before ACCEPT).

Prevention:

  1. Check existing SSH port before config
  2. First ufw allow ssh, then ufw enable
  3. If using iptables, ensure SSH rule before DROP

Emergency Solution:

  • VPS: Login via provider console (bypass SSH)
  • Cloud server: Provider offers “Recovery Mode” or “Rescue System”
  • Physical server: Local login

Error 2: Rule Order Chaos

Symptom: Port clearly has ACCEPT rule, still can’t connect.

Cause: Rule order problem, earlier DROP matched first.

Troubleshoot:

iptables -L -n -v --line-numbers

Check rule numbers, confirm ACCEPT before DROP.

Solution:

# Delete wrongly positioned rule
iptables -D INPUT 3

# Insert at correct position
iptables -I INPUT 2 -p tcp --dport 80 -j ACCEPT

Error 3: Config Not Persisted

Symptom: After reboot, firewall rules all gone.

Cause: iptables rules default to memory only, cleared on reboot.

Solution:

# Ubuntu/Debian
sudo apt install iptables-persistent
sudo netfilter-persistent save

# CentOS/RHEL
sudo service iptables save

UFW defaults to persistent, no extra handling.

Error 4: IPv6 Ignored

Symptom: IPv4 normal, IPv6 can’t access.

Cause: iptables only configured IPv4, IPv6 needs ip6tables.

Solution:

# IPv6 rules (similar to IPv4)
sudo ip6tables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT

# Save
sudo ip6tables-save > /etc/iptables/rules.v6

UFW auto handles IPv6, no separate config needed.

Troubleshooting Techniques

When firewall config has issues, troubleshoot in this order:

1. Check Firewall Status

# UFW
sudo ufw status verbose

# iptables
sudo iptables -L -n -v

Confirm firewall enabled, rules correct.

2. Test Port Connectivity

# From outside test
telnet server_ip 22
nc -zv server_ip 80

# Local test
sudo netstat -tulnp | grep :22

3. Check Firewall Logs

# UFW
tail -f /var/log/ufw.log

# iptables
tail -f /var/log/kern.log | grep "iptables"

See if requests got blocked.

4. Temporarily Disable for Check

# UFW
sudo ufw disable

# iptables
sudo iptables -F

After disabling test connectivity, confirm if firewall issue or service itself issue.

Note: After disabling firewall, server completely exposed—restore immediately after troubleshooting!


Summary: Building Your Firewall Security System

After all this discussion, let’s summarize core points.

Tool Selection

  • Simple scenarios: UFW enough, config in minutes, worry-free
  • Complex scenarios: iptables more flexible, fits gateways, NAT, advanced filtering
  • Don’t mix: Choose one tool for unified management, avoid rule conflicts

Configuration Principles

  • Default deny: Deny all inbound, only open necessary ports
  • Least privilege: Each rule scope minimal, restrict source IP
  • Layered defense: Firewall is first layer, combine with WAF, SELinux multiple protection
  • Network segmentation: DMZ, internal, management zones isolated
  • Regular audit: Monthly check rules, quarterly assess, annual refactor

Practical Points

  • Open SSH first: Ensure SSH port accessible before firewall config
  • Rule order: iptables rules from specific to general, order matters
  • Persistent save: iptables rules need saving, auto-load after reboot
  • IPv6 config: iptables needs separate ip6tables, UFW auto handles
  • Test environment verify: Try in test environment before production config
  • Keep logs: Enable firewall logs, regularly analyze abnormal traffic

Next Steps Learning

If you want to deepen firewall and server security knowledge, explore:

  • nftables: iptables’ modern replacement, more unified syntax, better performance
  • firewalld: Dynamic firewall management, supports runtime modification
  • WAF config: Nginx ModSecurity, Cloudflare WAF
  • Intrusion detection: Fail2ban (auto-block brute force), OSSEC
  • SELinux/AppArmor: Host-level permission control

Firewall configuration is server security’s foundation. Master UFW and iptables usage, understand security policy design principles, your server won’t be a house with doors wide open for anyone. 3 AM alert SMS incidents can happen less often.


Complete Linux Firewall Configuration Flow

Configure UFW or iptables firewall from scratch to protect server security

⏱️ Estimated time: 30 min

  1. 1

    Step1: Set Default Policies

    Default deny all inbound connections, allow all outbound:

    • UFW: `sudo ufw default deny incoming` and `sudo ufw default allow outgoing`
    • iptables: `sudo iptables -P INPUT DROP` and `sudo iptables -P OUTPUT ACCEPT`
    • This is security configuration's cornerstone, ensure only necessary ports open
  2. 2

    Step2: Open SSH Port

    Open SSH before configuring firewall to avoid lockouts:

    • UFW: `sudo ufw allow ssh` or `sudo ufw allow 22/tcp`
    • iptables: `sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT`
    • Custom ports remember to change to corresponding port (like 2222)
  3. 3

    Step3: Open Service Ports

    Open web services and other necessary ports:

    • HTTP: `sudo ufw allow 80/tcp` or `sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT`
    • HTTPS: `sudo ufw allow 443/tcp` or `sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT`
    • Other services open as needed, try to restrict source IP
  4. 4

    Step4: Enable Firewall and Verify

    Enable firewall and check status:

    • UFW: `sudo ufw enable` then `sudo ufw status verbose`
    • iptables: Check rules `sudo iptables -L -n -v --line-numbers`
    • Confirm rules correct and firewall in active state
  5. 5

    Step5: Persistently Save Rules

    iptables rules default not persistent, lost on reboot:

    • Ubuntu/Debian: `sudo apt install iptables-persistent` then `sudo netfilter-persistent save`
    • Manual save: `sudo iptables-save > /etc/iptables/rules.v4`
    • UFW defaults to persistent, no extra operation needed

FAQ

Can UFW and iptables be used together?
Not recommended to mix. Both operate same Netfilter rules, easily causes conflicts. Example: opened SSH with iptables, later denied SSH with UFW, last rule wins—might get locked out. Choose one tool for unified management.
Is there a performance difference between UFW and iptables?
Performance is identical. UFW still uses iptables/nftables underneath, both are Netfilter working in kernel. Only performance difference comes from rule count: more rules, slower matching. But for medium-small servers, impact is minimal.
What to do if locked out when configuring firewall?
Emergency solution depends on server type:

• VPS/Cloud server: Login via provider console (bypass SSH)
• Physical server: Local login
• Prevention: Before config run `ufw allow ssh`, then `ufw enable`; iptables ensure SSH rule before DROP
iptables rules disappeared after reboot?
iptables rules default only in memory, cleared on reboot. Solution: Ubuntu/Debian install `iptables-persistent`, run `netfilter-persistent save`; or manually `iptables-save > /etc/iptables/rules.v4`. UFW defaults to persistent.
What does UFW's limit command mean?
Rate limiting feature, prevents brute force. Like `sudo ufw limit ssh`: if an IP tries connecting more than 6 times within 30 seconds, temporarily bans it. Much safer than plain `allow ssh`.
When should I use iptables instead of UFW?
Use iptables for these scenarios:

• NAT, port forwarding, load balancing
• Complex rule chains, multi-level condition checks
• Gateways, routers, VPN servers
• Large-scale deployment (scripted management of dozens of servers)
• Advanced filtering (by packet content, rate, time)

Other scenarios (VPS, web services) UFW is enough and simpler.
What are the best security principles for firewall configuration?
Core principles:

• Default deny: Deny all inbound, only open necessary ports
• Least privilege: Each rule scope minimal, restrict source IP
• Layered defense: Firewall + WAF + SELinux multiple protection
• Regular audit: Monthly check rules, quarterly assess, annual refactor

References

15 min read · Published on: Apr 3, 2026 · Modified on: Apr 5, 2026

Comments

Sign in with GitHub to leave a comment

Related Posts