SecurityUpdated Feb 2026

    How to Set Up a Firewall on Your Web Server: Complete Guide

    Your server is scanned by bots within minutes of going online. A properly configured firewall is the first (and most critical ) line of defense. This guide covers UFW, firewalld, iptables, Fail2Ban, and WAF configuration with production-ready commands.

    Mallory Keegan
    Mallory Keegan

    Web hosting enthusiast who tests providers and breaks down features, pricing, and real world speed

    Web server firewall configuration guide showing iptables rules, UFW setup, Fail2Ban protection, and WAF implementation layers
    Complete web server firewall configuration for production security

    Quick Setup Summary

    Ubuntu/Debian Servers

    Use UFW: simplest setup, 3 commands to secure your server. Best for single-server deployments.

    CentOS/RHEL Servers

    Use firewalld: zone-based architecture with runtime/permanent rule separation. Enterprise-ready.

    Advanced Users

    Use iptables/nftables directly for granular control. Required for complex multi-service architectures.

    Cloud Servers

    Layer cloud firewalls (Security Groups, VPC rules) with host-based firewalls for defense-in-depth.

    What Is a Server Firewall?

    A firewall is a network security system that monitors and controls incoming and outgoing traffic based on predefined rules. On a web server, it acts as a gatekeeper, deciding which connections are allowed and which are blocked.

    Without a firewall, every service running on your server is exposed to the internet. A single unpatched service on an open port is all an attacker needs. In 2025, the average unprotected server was compromised within 39 minutes of going online.

    Threat TypeWithout FirewallWith Firewall
    SSH Brute ForceThousands of attempts/dayBlocked after 3 failures
    Port ScanningAll ports visibleOnly 80/443 exposed
    DDoS FloodsServer overwhelmedRate-limited and filtered
    Service ExploitsAll services reachableOnly web traffic allowed
    Data ExfiltrationUnrestricted outboundOutbound rules limit egress

    Types of Firewalls

    Server security uses multiple firewall layers. Understanding each type helps you build a complete defense strategy.

    Packet Filter (iptables/nftables)

    Inspects individual packets at the network layer. Fastest but least context-aware. The foundation of Linux firewalling.

    Stateful Firewall (UFW/firewalld)

    Tracks connection state, knows if a packet is part of an established session. Smarter than packet filtering alone.

    Application Firewall (WAF)

    Inspects HTTP requests for SQL injection, XSS, and application-layer attacks. Essential for web servers.

    Cloud Firewall (Security Groups)

    Provider-level filtering before traffic reaches your server. Zero server CPU overhead. First line of defense.

    UFW Setup (Ubuntu/Debian)

    UFW (Uncomplicated Firewall) is the recommended firewall for Ubuntu and Debian servers. It wraps iptables in a human-friendly interface without sacrificing power.

    Step 1: Install and configure UFW

    # Install UFW (usually pre-installed on Ubuntu)
    sudo apt update && sudo apt install ufw -y
    
    # Set default policies, deny incoming, allow outgoing
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
    
    # Allow SSH BEFORE enabling (critical, don't lock yourself out!)
    sudo ufw allow 22/tcp comment 'SSH access'
    
    # Allow web traffic
    sudo ufw allow 80/tcp comment 'HTTP'
    sudo ufw allow 443/tcp comment 'HTTPS'
    
    # Enable the firewall
    sudo ufw enable
    
    # Verify rules
    sudo ufw status verbose

    Step 2: Advanced UFW rules

    # Allow SSH only from your IP (replace with your IP)
    sudo ufw allow from 203.0.113.50 to any port 22 proto tcp
    
    # Rate-limit SSH to prevent brute force (6 connections/30s)
    sudo ufw limit 22/tcp
    
    # Allow a specific subnet (office network)
    sudo ufw allow from 10.0.0.0/24 to any port 3306 comment 'MySQL from office'
    
    # Deny a specific IP
    sudo ufw deny from 192.168.1.100
    
    # Delete a rule by number
    sudo ufw status numbered
    sudo ufw delete 3
    
    # Enable logging
    sudo ufw logging on

    Warning: Always allow SSH before enabling UFW. If you enable the firewall without an SSH rule, you will be locked out of your server. Recovery requires console access from your hosting provider.

    Firewalld Setup (CentOS/RHEL/AlmaLinux)

    Firewalld uses a zone-based model that separates runtime rules (lost on reboot) from permanent rules. It's the default on RHEL-based distributions.

    # Install firewalld (usually pre-installed)
    sudo dnf install firewalld -y
    
    # Start and enable
    sudo systemctl start firewalld
    sudo systemctl enable firewalld
    
    # Check default zone
    sudo firewall-cmd --get-default-zone
    
    # Allow web services (permanent)
    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    sudo firewall-cmd --permanent --add-service=ssh
    
    # Remove unnecessary services
    sudo firewall-cmd --permanent --remove-service=dhcpv6-client
    sudo firewall-cmd --permanent --remove-service=cockpit
    
    # Allow custom port
    sudo firewall-cmd --permanent --add-port=8443/tcp
    
    # Restrict SSH to specific IP
    sudo firewall-cmd --permanent --add-rich-rule='
      rule family="ipv4"
      source address="203.0.113.50/32"
      service name="ssh" accept'
    
    # Apply changes
    sudo firewall-cmd --reload
    
    # Verify active rules
    sudo firewall-cmd --list-all
    FeatureUFWfirewalld
    DistributionUbuntu/DebianCentOS/RHEL/Alma
    ArchitectureFlat rule listZone-based
    Runtime vs PermanentAll rules persistSeparate concepts
    Learning CurveVery lowModerate
    Rich RulesLimitedFull support
    Best ForSingle-server setupsEnterprise environments

    iptables Deep Dive

    iptables is the underlying packet filtering framework in Linux. While UFW and firewalld are easier, understanding iptables gives you complete control and is essential for debugging.

    Production-ready iptables ruleset

    #!/bin/bash
    # Flush existing rules
    iptables -F
    iptables -X
    
    # Default policies: drop incoming, allow outgoing
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT
    
    # Allow loopback
    iptables -A INPUT -i lo -j ACCEPT
    iptables -A OUTPUT -o lo -j ACCEPT
    
    # Allow established connections
    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
    
    # Allow SSH (rate-limited)
    iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
      -m recent --set --name SSH
    iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW \
      -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
    iptables -A INPUT -p tcp --dport 22 -j ACCEPT
    
    # Allow HTTP and HTTPS
    iptables -A INPUT -p tcp --dport 80 -j ACCEPT
    iptables -A INPUT -p tcp --dport 443 -j ACCEPT
    
    # Allow ICMP (ping), rate-limited
    iptables -A INPUT -p icmp --icmp-type echo-request \
      -m limit --limit 1/s --limit-burst 4 -j ACCEPT
    
    # Drop invalid packets
    iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
    
    # Log dropped packets (last 5/min to avoid log flooding)
    iptables -A INPUT -m limit --limit 5/min -j LOG \
      --log-prefix "iptables-dropped: " --log-level 4
    
    # Save rules (Debian/Ubuntu)
    iptables-save > /etc/iptables/rules.v4

    Note: Modern Linux distributions are migrating from iptables to nftables. The syntax differs, but concepts are identical. Ubuntu 22.04+ uses nftables as the default backend, even when you use UFW.

    Fail2Ban: Automatically Block Attackers

    Fail2Ban monitors log files for signs of brute-force attacks and automatically creates firewall rules to block offending IPs. It's essential for any internet-facing server.

    Install and configure Fail2Ban

    # Install Fail2Ban
    sudo apt install fail2ban -y   # Debian/Ubuntu
    sudo dnf install fail2ban -y   # CentOS/RHEL
    
    # Create local config (never edit jail.conf directly)
    sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
    
    # Edit jail.local
    sudo nano /etc/fail2ban/jail.local

    /etc/fail2ban/jail.local, recommended settings

    [DEFAULT]
    bantime  = 3600      # Ban for 1 hour
    findtime = 600       # Within 10-minute window
    maxretry = 3         # After 3 failures
    banaction = ufw      # Use UFW for banning (or iptables-multiport)
    
    # Whitelist your own IP
    ignoreip = 127.0.0.1/8 ::1 203.0.113.50
    
    [sshd]
    enabled  = true
    port     = ssh
    logpath  = /var/log/auth.log    # Debian/Ubuntu
    # logpath = /var/log/secure     # CentOS/RHEL
    maxretry = 3
    
    [nginx-http-auth]
    enabled  = true
    port     = http,https
    logpath  = /var/log/nginx/error.log
    
    [nginx-botsearch]
    enabled  = true
    port     = http,https
    logpath  = /var/log/nginx/access.log
    maxretry = 2
    
    [nginx-limit-req]
    enabled  = true
    port     = http,https
    logpath  = /var/log/nginx/error.log

    Managing Fail2Ban

    # Start and enable
    sudo systemctl start fail2ban
    sudo systemctl enable fail2ban
    
    # Check status of all jails
    sudo fail2ban-client status
    
    # Check specific jail
    sudo fail2ban-client status sshd
    
    # Unban an IP
    sudo fail2ban-client set sshd unbanip 192.168.1.100
    
    # Test regex against log file
    sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

    Web Application Firewall (WAF)

    Network firewalls control which ports are open. A WAF controls what passes through those ports, inspecting HTTP requests for SQL injection, cross-site scripting, and other application attacks.

    WAF SolutionTypePriceBest For
    ModSecurity + OWASP CRSSelf-hostedFreeNginx/Apache servers
    Cloudflare WAFCloud proxyFree: $200/moAny website
    AWS WAFCloud-native$5/mo + rulesAWS-hosted apps
    SucuriCloud proxy$199/yrWordPress sites
    Imperva (Incapsula)Enterprise$59+/moHigh-traffic sites

    Install ModSecurity with Nginx

    # Install ModSecurity for Nginx (Ubuntu 22.04+)
    sudo apt install libmodsecurity3 libmodsecurity-dev \
      libnginx-mod-http-modsecurity -y
    
    # Download OWASP Core Rule Set
    cd /etc/nginx/modsec
    sudo git clone https://github.com/coreruleset/coreruleset.git
    sudo cp coreruleset/crs-setup.conf.example crs-setup.conf
    
    # Enable in nginx.conf
    # Add inside server block:
    modsecurity on;
    modsecurity_rules_file /etc/nginx/modsec/main.conf;
    
    # Test and reload
    sudo nginx -t && sudo systemctl reload nginx

    Cloud Provider Firewalls

    Cloud firewalls filter traffic at the network edge before it reaches your server, consuming zero server resources. Always use them alongside host-based firewalls.

    ProviderFeature NameStateful?Cost
    AWSSecurity Groups + NACLsSG: Yes, NACL: NoFree
    DigitalOceanCloud FirewallsYesFree
    VultrFirewall GroupsYesFree
    Linode/AkamaiCloud FirewallsYesFree
    HetznerFirewallsYesFree
    Google CloudVPC Firewall RulesYesFree

    Pro tip: Configure your cloud firewall to only allow ports 80, 443, and SSH (from your IP). Then use UFW/firewalld on the server as a second layer. If either fails, the other still protects you.

    Port Management Best Practices

    The fewer ports you expose, the smaller your attack surface. Here's a reference for common services and whether they should face the internet.

    PortServicePublic?Recommendation
    22SSHLimitedRestrict to your IP or VPN only
    80HTTPYesOpen, redirects to HTTPS
    443HTTPSYesOpen, primary web traffic
    3306MySQLNoBind to 127.0.0.1 or private network
    5432PostgreSQLNoBind to 127.0.0.1 or private network
    6379RedisNoBind to 127.0.0.1, never expose
    27017MongoDBNoBind to 127.0.0.1, critical risk
    8080Dev/AdminNoClose or restrict to VPN
    9090MonitoringNoAccess via SSH tunnel only

    Scan your server for open ports

    # From another machine, scan your server
    nmap -sV your-server-ip
    
    # Check listening ports from the server itself
    sudo ss -tlnp
    # or
    sudo netstat -tlnp

    Outbound Filtering

    Most guides focus on inbound rules, but outbound filtering prevents compromised servers from connecting to attacker-controlled infrastructure, blocking data exfiltration and reverse shells.

    Restrict outbound traffic (iptables)

    # Allow DNS lookups
    iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
    iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
    
    # Allow HTTP/HTTPS (for package updates, API calls)
    iptables -A OUTPUT -p tcp --dport 80 -j ACCEPT
    iptables -A OUTPUT -p tcp --dport 443 -j ACCEPT
    
    # Allow SMTP (if server sends email)
    iptables -A OUTPUT -p tcp --dport 587 -j ACCEPT
    
    # Allow NTP (time synchronization)
    iptables -A OUTPUT -p udp --dport 123 -j ACCEPT
    
    # Allow established connections
    iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
    
    # Drop everything else
    iptables -P OUTPUT DROP

    Caution: Strict outbound filtering can break legitimate services. Test thoroughly in a staging environment before applying to production. Start with logging mode to identify what your server normally connects to.

    Logging & Monitoring

    A firewall without logging is flying blind. You need visibility into blocked traffic to detect attack patterns and tune your rules.

    # UFW logging levels
    sudo ufw logging low     # Log blocked packets only
    sudo ufw logging medium  # Log blocked + rate-limited
    sudo ufw logging high    # Log everything (generates large logs)
    
    # View UFW logs
    sudo tail -f /var/log/ufw.log
    sudo grep "UFW BLOCK" /var/log/ufw.log | tail -20
    
    # firewalld logging
    sudo firewall-cmd --set-log-denied=all  # Log all denied traffic
    
    # View firewalld logs
    sudo journalctl -u firewalld -f
    
    # Count blocked IPs (top offenders)
    grep "UFW BLOCK" /var/log/ufw.log | \
      awk '{for(i=1;i<=NF;i++) if($i ~ /SRC=/) print $i}' | \
      sort | uniq -c | sort -rn | head -20

    Grafana + Loki

    Visualize firewall logs with dashboards and alerts

    CrowdSec

    Community-driven threat intelligence with auto-banning

    OSSEC / Wazuh

    Full HIDS with log analysis and real-time alerting

    Common Mistakes to Avoid

    ❌ Enabling the firewall before allowing SSH

    ✅ Always run 'ufw allow 22/tcp' before 'ufw enable'. Test SSH in a second terminal before closing your current session.

    ❌ Leaving database ports open to the internet

    ✅ Bind MySQL/PostgreSQL/Redis to 127.0.0.1 in their configs. Use SSH tunnels or private networks for remote access.

    ❌ Using only a cloud firewall without host-based firewall

    ✅ Cloud firewalls can be misconfigured through the API. Host-based firewalls provide a second layer that requires server access to change.

    ❌ Never reviewing or auditing rules

    ✅ Schedule monthly rule audits. Run 'nmap' against your server quarterly. Remove rules for decommissioned services.

    ❌ Not rate-limiting SSH connections

    ✅ Use 'ufw limit 22/tcp' or Fail2Ban. Without rate-limiting, bots will try thousands of passwords per hour.

    ❌ Forgetting IPv6

    ✅ Ensure your firewall rules apply to both IPv4 and IPv6. UFW handles this automatically; iptables requires separate ip6tables rules.

    ❌ Blocking ICMP entirely

    ✅ Allow ICMP echo-request (ping) with rate-limiting. Blocking all ICMP breaks path MTU discovery and network diagnostics.

    Firewall Security Checklist

    ActionPriorityTool
    Set default deny incoming policyCriticalUFW / firewalld
    Allow only ports 22, 80, 443CriticalUFW / firewalld
    Restrict SSH to known IPsCriticalUFW / cloud firewall
    Install and configure Fail2BanCriticalFail2Ban
    Enable cloud provider firewallHighAWS / DO / Vultr
    Bind databases to localhostHighMySQL / PostgreSQL config
    Enable firewall loggingHighUFW / iptables
    Install WAF (ModSecurity or Cloudflare)HighModSecurity / Cloudflare
    Scan for open ports (nmap)Highnmap
    Configure outbound rulesMediumiptables
    Set up log monitoring / alertsMediumGrafana / CrowdSec
    Disable IPv6 if not usedMediumsysctl / UFW
    Review and audit rules monthlyMediumManual
    Document all firewall rulesMediumWiki / README
    Test firewall after changesLownmap / curl

    Frequently Asked Questions

    What ports should I keep open on a web server?
    For a standard web server, keep ports 22 (SSH, ideally changed to a custom port), 80 (HTTP), and 443 (HTTPS) open. Close everything else. If you run additional services like a database, only allow connections from specific trusted IPs, never the public internet.
    What's the difference between UFW and iptables?
    UFW (Uncomplicated Firewall) is a user-friendly frontend for iptables. It simplifies rule management with intuitive commands like 'ufw allow 443'. Under the hood, UFW translates your commands into iptables rules. For most web servers, UFW is sufficient and recommended.
    Should I use a host-based or cloud firewall?
    Use both. Cloud firewalls (AWS Security Groups, DigitalOcean Firewalls) filter traffic before it reaches your server, reducing load. Host-based firewalls (UFW, firewalld) add a second defense layer. This defense-in-depth approach is the industry standard.
    How do I protect against brute-force SSH attacks?
    Install Fail2Ban, change your SSH port from 22 to a custom number, disable password authentication in favor of SSH keys, and restrict SSH access to specific IP addresses using your firewall. These four steps eliminate 99% of brute-force attempts.
    Can a firewall slow down my website?
    A properly configured firewall has negligible performance impact, typically under 1ms of added latency. In fact, firewalls often improve performance by blocking malicious traffic, bot floods, and DDoS attempts that would otherwise consume server resources.
    What is a WAF and do I need one?
    A Web Application Firewall (WAF) inspects HTTP traffic and blocks attacks like SQL injection, XSS, and path traversal. While a network firewall controls which ports are open, a WAF protects your web application logic. Every public-facing site should use one.
    How often should I review firewall rules?
    Review your firewall rules monthly and after every infrastructure change. Remove rules for decommissioned services, audit access by IP, and verify logging is active. Quarterly, run a port scan against your server to confirm only expected ports are open.
    Does Fail2Ban work with UFW?
    Yes. Fail2Ban detects brute-force attempts from log files and automatically creates UFW (or iptables) rules to block offending IPs. Install both together for automated intrusion prevention. Configure Fail2Ban's 'banaction' to 'ufw' for seamless integration.

    Need Hosting With Built-In Firewall Protection?

    Many managed hosting providers include pre-configured firewalls, DDoS protection, and WAF rules. Find the right one for your needs.

    Find Secure Hosting