
September 09, 2026
11 min read
By Kokil Thapa | Last reviewed: September 2026
Your Laravel app can run perfectly on Ubuntu, yet still be wide open to SSH brute force and port scans if the host firewall is wrong. A complete iptables firewall rules explained guide starts with Netfilter hooks, not random copy-paste snippets. On production servers I maintain with Linux system administration, iptables remains the engine behind UFW, Docker publish rules, and many cloud images. This page walks through tables, chains, rule syntax, and a safe web-server baseline you can persist after reboot.
What are iptables firewall rules and how do they work?
iptables is the classic userspace tool that configures Linux Netfilter. The kernel inspects every packet at fixed hook points. Your rules decide whether traffic is accepted, dropped, rejected, translated, or marked for later handling.
Think of iptables as a rule engine, not a daemon. When you run iptables, you load rule sets into kernel memory. No background service is required for the firewall itself to keep working. That design is why a misconfigured INPUT chain can lock you out instantly over SSH.
On a typical domain and hosting stack—Apache or Nginx, PHP-FPM 8.3+, MySQL 9.7 or PostgreSQL 18—most engineers touch the filter table daily. NAT tables matter when you run Docker, VPN gateways, or SNAT from private subnets. For a single public web server, filter is where you spend 90% of your time.
Tables you will actually use
- filter — default for allow/deny decisions on local and forwarded traffic.
- nat — rewrites source or destination addresses; common with Docker and VPNs.
- mangle — packet marking and header tweaks; used in advanced routing and QoS.
- raw — early connection tracking bypass; niche on web servers.
- security — SELinux context labels; rarely edited manually on Ubuntu.
The official Netfilter project documentation at netfilter.org remains the authoritative reference for hook ordering and table behaviour. Ubuntu packages ship the legacy iptables front end alongside nftables; both talk to the same kernel subsystem.
How do you read iptables rule syntax?
Every iptables command follows a predictable pattern: table, operation, chain, match criteria, and target. Once you can read one line, you can audit an entire host in minutes.
A typical append looks like this:
iptables -t filter -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT Break it down piece by piece:
-t filter— select the filter table (default if omitted).-A INPUT— append to the INPUT chain for traffic destined to this host.-p tcp— match TCP protocol only.--dport 443— match destination port 443.-m conntrack --ctstate NEW,ESTABLISHED— use connection tracking module.-j ACCEPT— jump target: accept the packet.
List rules with line numbers before you delete anything:
sudo iptables -L -n -v --line-numbers
sudo iptables -t nat -L -n -v --line-numbers The -n flag shows numeric ports and IPs. The -v flag adds packet counters— invaluable when you suspect a rule never matches. I use a regex tester when building complex string or comment matches, though most web-server rules are port-based.
Common match modules
| Module | Example flag | Typical use |
|---|---|---|
| conntrack | --ctstate ESTABLISHED,RELATED | Allow return traffic for existing sessions |
| multiport | --dports 80,443 | Match several ports in one rule |
| limit | --limit 5/min | Rate-limit log or drop bursts |
| comment | --comment "allow ssh" | Document rules in output |
| iprange | --src-range 10.0.0.0/8 | Office IP allowlists |
Targets beyond ACCEPT and DROP include REJECT (sends ICMP unreachable), LOG, and custom chains via -j MYCHAIN. Jumping to a user-defined chain keeps complex policies readable— the same pattern I apply when hardening travel booking servers that expose HTTP, HTTPS, and admin SSH.
Which iptables chains and tables should a web server use?
For a public-facing web server running Laravel 13, WordPress 7.1, or WooCommerce 11.1, your baseline lives in filter:INPUT and filter:OUTPUT. Default-deny inbound, permissive outbound, and explicit allows for SSH, HTTP, and HTTPS cover most cases.
Order matters. The kernel evaluates rules top to bottom until the first match. Put broad ESTABLISHED rules early. Put narrow NEW port allows next. End with a default DROP or REJECT on INPUT.
Recommended INPUT chain pattern
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -m limit --limit 3/min -j ACCEPT
sudo iptables -A INPUT -p tcp -m multiport --dports 80,443 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/sec -j ACCEPT That SSH rate limit reduces brute-force noise. It does not replace key-based auth or fail2ban, but it cuts log volume. On sister sites I deploy with Deployer 7 and GitLab CI, the same pattern protects shared EC2 hosts running multiple PHP-FPM pools.
If you run Redis 8.10 or MySQL only on localhost, do not publish those ports in iptables at all. Binding services to 127.0.0.1 is the first line of defence. Firewall rules are the second.
Read the companion piece on iptables vs nftables on Linux before migrating production. For quick Ubuntu setups, configure a firewall with UFW first, then inspect the generated iptables rules with iptables-save to learn the mapping.
How do you create persistent iptables rules on Ubuntu?
iptables rules vanish on reboot unless you persist them. Ubuntu does not save rules automatically. That surprise has caused many post-reboot exposure incidents on client servers I inherited during support and maintenance engagements.
Save and restore with iptables-persistent
- Install the persistence package:
sudo apt install iptables-persistent netfilter-persistent. - Apply your live rules and verify connectivity in a second SSH session.
- Save IPv4 rules:
sudo netfilter-persistent save. - Confirm files exist:
/etc/iptables/rules.v4andrules.v6. - Reboot test on a staging VM before touching production.
Export current rules manually anytime:
sudo iptables-save > /tmp/iptables.backup
sudo iptables-restore < /tmp/iptables.backup Store backups in version control or your Ansible playbooks for PHP server provisioning. Automation beats hand-editing live firewalls at 2 a.m.
IPv6 requires ip6tables
Many hosts expose services over IPv6 whether you planned for it or not. Mirror your IPv4 policy with ip6tables. An open IPv6 INPUT chain while IPv4 is locked down is a common audit finding. Use ip6tables-save alongside IPv4 exports.
Ubuntu server guides at documentation.ubuntu.com document UFW and nftables paths. The concepts map directly when you drop to raw iptables.
How do iptables compare to UFW and nftables on production hosts?
Choose the tool that matches your team and stack. None of them replaces sound network design or application-level security.
| Criterion | iptables | UFW | nftables |
|---|---|---|---|
| Syntax complexity | High; full Netfilter vocabulary | Low; profiles and numbered rules | Medium; unified grammar, sets, maps |
| Docker interaction | Direct visibility into DOCKER chains | Same backend; harder to debug NAT inserts | Docker still may insert iptables rules on some versions |
| Persistence | iptables-persistent / manual save | Built-in with UFW enable | nft list ruleset > file + systemd unit |
| Best fit | Custom chains, legacy scripts, debugging | Single-server LAMP/LEMP stacks | New automation, multi-table atomic updates |
| Learning value | Teaches kernel behaviour directly | Good starting point; hides details | Future-facing; read if starting fresh in 2026 |
On legal-tech portals such as Notary Nepal, I combine UFW for day-to-day edits with occasional iptables -L -n -v audits after package upgrades. After Docker or Kubernetes installs, always re-check effective rules— publish flags can bypass your intended INPUT policy via FORWARD and nat tables.
Pair host firewalls with application hardening from testing and optimization and web development best practices. A firewall cannot fix SQL injection or exposed .env files.
Debugging mistakes I see repeatedly
- Flushing rules remotely without a console fallback— lockout risk is real.
- Allowing NEW on port 22 but forgetting ESTABLISHED first— breaks existing sessions on reload.
- Editing filter rules while Docker rewrites nat FORWARD chains on every container start.
- Testing only IPv4 while IPv6 listens publicly on the same services.
- Assuming fail2ban replaces a default-drop INPUT policy— it does not.
When auditing, log dropped packets temporarily:
sudo iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPT DROP: "
sudo iptables -A INPUT -j DROP Remove LOG rules after diagnosis. Excessive kernel logging fills disks on busy sites. For JSON log pipelines, a JSON formatter helps normalise exported syslog entries during review.
Advanced readers should study the kernel Netfilter FAQ at netfilter.org FAQ for corner cases around bridge filtering and mark-based routing. Most PHP/Laravel deployments never need that depth.
Related reading: UFW firewall rules for web servers, alerting with Prometheus Alertmanager for correlating traffic spikes with firewall logs, and speed optimization to ensure security middleware does not undo your Core Web Vitals work.
Key Takeaways
- iptables configures Netfilter through tables (filter, nat, mangle) and chains (INPUT, OUTPUT, FORWARD, plus nat hooks).
- Rule order is first-match-wins— place ESTABLISHED,RELATED before narrow NEW port allows on INPUT.
- Web servers need explicit TCP 80/443 and rate-limited SSH; bind databases to localhost instead of exposing ports.
- Persist rules with iptables-persistent or automation; reboot without save equals open or broken firewall.
- Mirror policy in ip6tables; IPv6 bypass is a frequent production gap.
- UFW and nftables sit on the same kernel— learn iptables to debug what those tools actually install.
People Also Ask
What is the difference between iptables and firewalld?
firewalld is a dynamic zone-based daemon used heavily on RHEL-family distros. iptables is the lower-level rule tool (or backend) on many systems. Ubuntu servers more often use UFW or raw iptables/nftables than firewalld. Both ultimately program Netfilter hooks in the kernel.
Does Docker bypass iptables rules?
Docker inserts its own iptables rules in the nat and filter tables, especially FORWARD chains. Your INPUT policy may look strict while published container ports remain reachable. Always run iptables-save | grep DOCKER after deploying containers on a hardened host.
Should I use DROP or REJECT as the default INPUT policy?
DROP silently discards packets; REJECT sends an ICMP response. DROP is slower to scan but can hang clients until timeout. REJECT reveals that a firewall exists. For public web servers, DROP on INPUT is the common hardening choice; REJECT on internal lab VMs aids debugging.
Are iptables rules enough to secure a Laravel application?
No. Host firewalls protect the network edge. You still need TLS, patched PHP 8.3+, queue worker isolation, and WAF or rate limits at the application layer. iptables shrinks the attack surface; it does not validate HTTP input or authorisation logic.
Ship a hardened stack with confidence
A clear iptables firewall rules explained mental model saves hours when Docker, CI deploys, or package upgrades shift effective policy under your feet. Start with default-drop INPUT, document rules with comments, persist across reboots, and audit IPv6 alongside IPv4. When you want hands-on help on Ubuntu production hosts, contact us for firewall review bundled with Linux administration, or explore recent work on the portfolio and home page. Solid network rules plus sane application defaults beat any single shiny security product.
Frequently Asked Questions
0 Comments
Leave a comment
Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

