
How to Implement a Basic Firewall Template with iptables on Ubuntu 24
Setting up a firewall is one of those essential security practices that every developer and sysadmin should have in their toolkit, yet it’s often overlooked until something goes wrong. With Ubuntu 24’s latest release, implementing a solid iptables-based firewall template has become more straightforward, but there are still plenty of gotchas that can trip you up. In this post, we’ll walk through building a practical, production-ready firewall configuration that you can adapt to your specific needs, covering everything from basic rule creation to advanced traffic filtering and common troubleshooting scenarios.
How iptables Works Under the Hood
Before diving into implementation, it’s worth understanding what iptables actually does. Think of iptables as a sophisticated traffic controller that sits between your network interface and your applications. It operates using chains (INPUT, OUTPUT, FORWARD) and tables (filter, nat, mangle, raw) to process packets at different stages of the network stack.
The key concept is that iptables processes rules sequentially within each chain until it finds a match, then applies the specified action (ACCEPT, DROP, REJECT, or jump to another chain). This sequential processing is both powerful and potentially problematic if you’re not careful with rule ordering.
Here’s how the basic packet flow works:
- Incoming packets hit the INPUT chain for local processes
- Outgoing packets from local processes go through OUTPUT chain
- Packets being routed through the system use the FORWARD chain
- Each chain has a default policy (usually ACCEPT or DROP)
Step-by-Step Firewall Implementation
Let’s build a comprehensive firewall template that covers most common scenarios. First, we’ll create a backup of any existing rules and set up our basic structure.
Initial Setup and Safety Measures
# Save current rules (if any)
sudo iptables-save > ~/iptables-backup-$(date +%Y%m%d).rules
# Clear existing rules
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
Always set up a safety mechanism when working with remote servers. This script will flush all rules after 5 minutes, giving you time to test and make permanent:
# Safety net - will flush rules in 5 minutes
echo "sudo iptables -F && sudo iptables -P INPUT ACCEPT && sudo iptables -P OUTPUT ACCEPT" | at now + 5 minutes
Basic Firewall Template
Here’s our comprehensive firewall template that handles most common scenarios:
#!/bin/bash
# Ubuntu 24 iptables firewall template
# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
# Allow loopback traffic
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Allow established and related connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Allow SSH (change port as needed)
iptables -A INPUT -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT
# Allow HTTP and HTTPS
iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
# Allow ping (ICMP)
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
# Log dropped packets (optional, but useful for debugging)
iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "iptables DROP: " --log-level 7
# Save rules
iptables-save > /etc/iptables/rules.v4
Making Rules Persistent
Ubuntu 24 doesn’t automatically save iptables rules across reboots. Install and configure the persistence package:
# Install iptables-persistent
sudo apt update
sudo apt install iptables-persistent
# During installation, it will ask to save current rules
# If you want to save rules later:
sudo netfilter-persistent save
sudo netfilter-persistent reload
Advanced Configuration Examples
Let’s expand our template with more sophisticated rules for real-world scenarios:
Rate Limiting and DDoS Protection
# Limit SSH connections to prevent brute force
iptables -A INPUT -p tcp --dport 22 -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m recent --update --seconds 60 --hitcount 4 --name SSH -j DROP
# Rate limit HTTP requests
iptables -A INPUT -p tcp --dport 80 -m limit --limit 100/minute --limit-burst 200 -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j DROP
# Protect against SYN flood attacks
iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT
iptables -A INPUT -p tcp --syn -j DROP
Application-Specific Rules
# Database servers (MySQL/MariaDB) - restrict to specific IPs
iptables -A INPUT -p tcp -s 192.168.1.100 --dport 3306 -j ACCEPT
iptables -A INPUT -p tcp -s 192.168.1.101 --dport 3306 -j ACCEPT
# Redis (restrict to localhost and specific subnet)
iptables -A INPUT -p tcp -s 127.0.0.1 --dport 6379 -j ACCEPT
iptables -A INPUT -p tcp -s 10.0.0.0/24 --dport 6379 -j ACCEPT
# Node.js application on custom port
iptables -A INPUT -p tcp --dport 3000 -m state --state NEW,ESTABLISHED -j ACCEPT
# Docker containers (if using Docker)
iptables -A INPUT -i docker0 -j ACCEPT
iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT
Real-World Use Cases and Examples
Here are some practical scenarios where you’d customize this template:
Web Server Configuration
For a typical LAMP/LEMP stack server hosting multiple websites:
# Web server with SSL termination
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# Allow FTP (if needed, though SFTP is preferred)
iptables -A INPUT -p tcp --dport 21 -j ACCEPT
iptables -A INPUT -p tcp --dport 20 -j ACCEPT
# Allow passive FTP range
iptables -A INPUT -p tcp --dport 10000:10100 -j ACCEPT
# Block common attack ports
iptables -A INPUT -p tcp --dport 23 -j DROP # Telnet
iptables -A INPUT -p tcp --dport 135 -j DROP # RPC
iptables -A INPUT -p tcp --dport 445 -j DROP # SMB
Development Server Setup
For development environments where you need more flexibility:
# Allow common development ports
iptables -A INPUT -p tcp --dport 3000:3010 -j ACCEPT # Node.js apps
iptables -A INPUT -p tcp --dport 8000:8080 -j ACCEPT # Python/Django, alternative HTTP
iptables -A INPUT -p tcp --dport 5000 -j ACCEPT # Flask default
iptables -A INPUT -p tcp --dport 4200 -j ACCEPT # Angular dev server
iptables -A INPUT -p tcp --dport 3001 -j ACCEPT # React dev server
# Allow database access from development subnet
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 5432 -j ACCEPT # PostgreSQL
iptables -A INPUT -p tcp -s 192.168.1.0/24 --dport 3306 -j ACCEPT # MySQL
Firewall Solutions Comparison
While iptables is powerful, it’s worth understanding how it compares to other firewall solutions available on Ubuntu 24:
Solution | Ease of Use | Performance | Flexibility | Best For |
---|---|---|---|---|
iptables | Complex | Excellent | Maximum | Advanced users, custom setups |
ufw | Simple | Good | Limited | Basic setups, beginners |
firewalld | Moderate | Good | High | Enterprise environments |
nftables | Complex | Excellent | Maximum | Modern replacement for iptables |
Performance Considerations and Optimization
Rule ordering significantly impacts performance. iptables processes rules sequentially, so place frequently matched rules first:
# Good: Most common traffic first
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Use specific interfaces when possible
iptables -A INPUT -i eth0 -p tcp --dport 80 -j ACCEPT
# Combine related rules
iptables -A INPUT -p tcp -m multiport --dports 80,443 -j ACCEPT
Here are some performance benchmarks for rule processing on a typical VPS:
Number of Rules | Processing Time (ΞΌs) | Memory Usage (KB) | Impact |
---|---|---|---|
10-50 | < 1 | < 100 | Negligible |
100-500 | 1-5 | 200-500 | Minimal |
1000+ | 10+ | 1000+ | Noticeable on high traffic |
Common Issues and Troubleshooting
Here are the most frequent problems you’ll encounter and how to solve them:
Locked Out of SSH
This is the classic mistake. Always test SSH access before making rules permanent:
# Test in a new terminal window
ssh user@your-server
# If you get locked out and have console access:
sudo iptables -P INPUT ACCEPT
sudo iptables -F
# Or restore from backup
sudo iptables-restore < ~/iptables-backup-20241201.rules
Rules Not Persisting
If rules disappear after reboot:
# Check if iptables-persistent is installed
systemctl status netfilter-persistent
# If not installed:
sudo apt install iptables-persistent
# Save current rules:
sudo netfilter-persistent save
# Verify rules are saved:
cat /etc/iptables/rules.v4
Debugging Connection Issues
Use these commands to diagnose problems:
# Watch packets in real-time
sudo iptables -L -n -v --line-numbers
# Check logs for dropped packets
sudo tail -f /var/log/kern.log | grep "iptables DROP"
# Test specific ports
nmap -p 80,443,22 your-server-ip
# Check if service is actually listening
sudo netstat -tlnp | grep :80
Performance Issues
If you notice network performance degradation:
# Check rule hit counts
sudo iptables -L -n -v
# Identify bottleneck rules (high packet counts with no matches)
# Move frequently matched rules higher in the chain
# Consider using ipsets for large IP lists
sudo apt install ipset
sudo ipset create whitelist hash:ip
sudo ipset add whitelist 192.168.1.100
sudo iptables -A INPUT -m set --match-set whitelist src -j ACCEPT
Best Practices and Security Considerations
Follow these guidelines to maintain a secure and manageable firewall:
- Always use the principle of least privilege - only open ports you actually need
- Implement logging for security monitoring, but be mindful of log rotation
- Use connection state tracking (ESTABLISHED,RELATED) to improve both security and performance
- Regularly audit your rules and remove unused ones
- Consider implementing fail2ban alongside iptables for dynamic blocking
- Test rule changes in a staging environment when possible
- Document your custom rules and their purposes
- Monitor firewall logs for unusual patterns
Integration with Modern Tools
Your iptables setup should work well with containerization and orchestration tools:
# Docker integration
# Docker automatically manages some iptables rules
# Add this to ensure compatibility:
iptables -A INPUT -i docker0 -j ACCEPT
iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT
# For Kubernetes clusters
# Allow kubelet API
iptables -A INPUT -p tcp --dport 10250 -s 10.0.0.0/8 -j ACCEPT
# Allow NodePort range
iptables -A INPUT -p tcp --dport 30000:32767 -j ACCEPT
Managing iptables rules becomes much easier when you create reusable scripts. Store your firewall configuration in version control and use configuration management tools like Ansible or simple bash scripts to deploy consistently across multiple servers.
For more advanced scenarios, consider exploring the official iptables documentation and Ubuntu's firewall guide for additional configuration options and security considerations.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.