// Blog

How to Configure and Secure a Linux VPS with iptables: Complete Guide — CLIQHOST

November 10, 2026 · by Alex M.

How to Configure and Secure a Linux VPS with iptables: Complete Guide — CLIQHOST

Among all Linux server protection tools, iptables holds a special place — it is a powerful, flexible, and time-tested firewall built directly into the Linux kernel. Despite the emergence of friendlier wrappers like UFW and firewalld, a deep understanding of iptables gives system administrators complete control over network traffic — which is especially critical on any NVMe VPS or dedicated server exposed to the internet.

In this guide you will learn how to install, configure, and manage iptables on a Ubuntu or Debian VPS — starting from scratch and arriving at a robust security ruleset.


What is iptables and How Does it Work

iptables is a user-space utility that allows administrators to configure IP packet filtering rules in the Linux kernel (via the Netfilter subsystem). It operates on tables, chains, and rules:

  • Tables: filter (default), nat, mangle, raw
  • Chains in the filter table: INPUT (traffic to the server), OUTPUT (traffic from the server), FORWARD (forwarded traffic)
  • Actions (targets): ACCEPT, DROP, REJECT, LOG

Each network packet traverses the rules in order; the first matching rule determines the packet's fate.


Prerequisites

Before you begin, make sure you have:

  • An SSD VPS or NVMe VPS running Ubuntu 20.04/22.04 or Debian 11/12
  • Root access or a user with sudo privileges
  • An active SSH connection (do not close the current session until you've tested the rules!)
  • Optionally: a second open SSH session as a safety net

Step 1: Check the Current iptables State

On most distributions, iptables comes pre-installed. Check the current state:

sudo iptables -L -v -n

If it is not installed:

# Ubuntu/Debian
sudo apt update && sudo apt install iptables -y

To also view IPv6 rules:

sudo ip6tables -L -v -n

Step 2: Core Strategy — Default Policies

Before adding rules, set the default policies for the chains. There are two approaches:

  1. Permissive (default ACCEPT) — explicitly block what you don't want
  2. Restrictive (default DROP) — explicitly allow only what you need ✅ (recommended for production)

⚠️ Critical warning: Do not set the INPUT policy to DROP before adding the rule that allows SSH! You risk locking yourself out of the server.

The correct order of commands:

# 1. Allow SSH BEFORE anything else
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# 2. Allow loopback (essential for system operation)
sudo iptables -A INPUT -i lo -j ACCEPT
sudo iptables -A OUTPUT -o lo -j ACCEPT

# 3. Allow already established connections
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# 4. Now you can safely set the DROP policy
sudo iptables -P INPUT DROP
sudo iptables -P FORWARD DROP
sudo iptables -P OUTPUT ACCEPT

Step 3: Essential Rules for a Web Server

If you are running a web server (Apache, Nginx) on cPanel shared hosting or on a VPS, add:

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

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

# DNS (if the server performs DNS resolution)
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT

# ICMP (ping) — useful for monitoring
sudo iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

For mail servers that also need SSL certificates:

# SMTP, SMTPS, IMAP, IMAPS, POP3S
sudo iptables -A INPUT -p tcp -m multiport --dports 25,465,587,143,993,110,995 -j ACCEPT

Step 4: Protection Against Common Attacks

4.1 Basic Anti-DDoS with Rate Limiting

# Limit new SSH connections to 5 per minute per IP
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --set --name SSH
sudo iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --update --seconds 60 --hitcount 5 --name SSH -j DROP

# Limit new HTTP connections (anti-DoS)
sudo iptables -A INPUT -p tcp --dport 80 -m limit \
  --limit 25/minute --limit-burst 100 -j ACCEPT

4.2 Blocking Invalid Packets (Stealth Scan Protection)

# Drop INVALID state packets
sudo iptables -A INPUT -m state --state INVALID -j DROP

# SYN flood protection
sudo iptables -A INPUT -p tcp --syn -m limit \
  --limit 1/s --limit-burst 4 -j ACCEPT

# Block Null scan
sudo iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP

# Block XMAS scan
sudo iptables -A INPUT -p tcp --tcp-flags ALL ALL -j DROP

4.3 Protection Against IP Spoofing

# Block private addresses coming from outside (on interface eth0)
sudo iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
sudo iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
sudo iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
sudo iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP

Check your network interface name with ip addr show and replace eth0 if necessary (e.g., ens3, enp1s0).


Step 5: Blocking Specific IP Addresses

If you notice attacks from specific IPs (visible in logs or via netstat), block them directly:

# Block a specific IP
sudo iptables -A INPUT -s 203.0.113.100 -j DROP

# Block an entire subnet
sudo iptables -A INPUT -s 203.0.113.0/24 -j DROP

# Unblock an IP
sudo iptables -D INPUT -s 203.0.113.100 -j DROP

On a managed dedicated server, the administration team can configure automated and more advanced block lists.


Step 6: Logging Blocked Traffic

To monitor what traffic is being blocked (useful for debugging and security auditing):

# Add a logging rule BEFORE the implicit DROP
sudo iptables -A INPUT -j LOG --log-prefix "[IPTABLES DROP] " --log-level 4

Logs appear in /var/log/syslog or /var/log/kern.log:

sudo tail -f /var/log/kern.log | grep "IPTABLES DROP"

⚠️ Intensive logging can fill your disk quickly. Use the limit module to restrict log entries:

sudo iptables -A INPUT -m limit --limit 5/min -j LOG \
  --log-prefix "[IPTABLES DROP] " --log-level 4

Step 7: Saving and Restoring iptables Rules

iptables rules are volatile — they are cleared on reboot. For persistence:

Ubuntu/Debian with iptables-persistent:

sudo apt install iptables-persistent -y

# Save current rules
sudo netfilter-persistent save

# Or manually:
sudo iptables-save > /etc/iptables/rules.v4
sudo ip6tables-save > /etc/iptables/rules.v6

Manual restore:

sudo iptables-restore < /etc/iptables/rules.v4

Verify boot-time loading:

sudo systemctl enable netfilter-persistent
sudo systemctl status netfilter-persistent

Step 8: Managing and Viewing Rules

# List rules with numbering (useful for deletion)
sudo iptables -L INPUT --line-numbers -v -n

# Delete a rule by number (e.g., rule 3 from INPUT)
sudo iptables -D INPUT 3

# Insert a rule at a specific position (e.g., position 1)
sudo iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT

# Flush all rules (WARNING — may lock you out!)
sudo iptables -F

# Reset policies to ACCEPT before flushing
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -F

Step 9: Complete iptables Setup Script

Here is a complete, ordered script you can run on a fresh server:

#!/bin/bash
# firewall-setup.sh — CLIQHOST iptables Script

# Reset
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X

# Default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

# Loopback
iptables -A INPUT -i lo -j ACCEPT

# Established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Invalid packets
iptables -A INPUT -m state --state INVALID -j DROP

# SSH with rate limiting
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW \
  -m recent --update --seconds 60 --hitcount 5 --name SSH -j DROP
iptables -A INPUT -p tcp --dport 22 -j ACCEPT

# Web
iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT

# ICMP
iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

# Anti-spoofing
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP

# Logging
iptables -A INPUT -m limit --limit 5/min -j LOG \
  --log-prefix "[IPTABLES DROP] " --log-level 4

echo "Firewall configured successfully!"

Save the script and execute it:

chmod +x firewall-setup.sh
sudo ./firewall-setup.sh
sudo netfilter-persistent save

Step 10: Testing Your Configuration

After applying the rules, test from outside:

# Test SSH connectivity
ssh -v user@SERVER_IP

# Check open ports with nmap (from another machine)
nmap -sS -p 22,80,443 SERVER_IP

# Verify active rules
sudo iptables -L -v -n

If you use server management services, you can request an external security verification from their specialists.


iptables vs. UFW vs. firewalld — When to Use What?

Criterion iptables UFW firewalld
Complexity High Low Medium
Granular control Maximum Limited Medium
Ubuntu/Debian ✅ ✅ Optional
CentOS/RHEL ✅ Optional ✅
Automation scripts ✅ Partial ✅

For complex production servers (such as an Intel dedicated server running multiple services), iptables provides the greatest control. UFW is better suited for simple VPS setups.


Common Mistakes and How to Avoid Them

  1. Locked yourself out of the server — Solution: contact CLIQHOST support for VNC/IPMI console access or use the VPS control panel.
  2. Rules don't persist after reboot — Install iptables-persistent and run netfilter-persistent save.
  3. Forgot to allow SSH before DROP — Always add the SSH rule FIRST.
  4. Wrong network interface name — Verify with ip addr and use the correct name (ens3, eth0, etc.).
  5. Rules applied in the wrong order — Use -I (insert) instead of -A (append) for high-priority rules.

Conclusion

iptables is an indispensable tool for any serious Linux server administrator. Although it has a steeper learning curve compared to UFW, it provides the complete control needed to protect a Linux VPS or a dedicated server against modern threats.

Approach iptables methodically: set default policies, explicitly allow needed services, block known attacks and scans, and save rules for persistence.

If you would rather focus on your business and leave server security to professionals, the CLIQHOST team offers comprehensive server management services — from firewall configuration to continuous monitoring. Contact us for a free consultation.

SHARE
// what clients say

What Our Clients Say

Real reviews from customers who trust CLIQHOST for performance, reliability and expert technical support.

★★★★★

"We moved our online shop from a foreign host and the difference is night and day — pages load instantly and support replies in minutes, in Romanian."

AM
Andrei M.
eCommerce owner · Chișinău
★★★★★

"Migrated 12 client sites to CLIQHOST. Free migration, zero downtime, and the cPanel setup is exactly what my team needed. Highly recommend."

EV
Elena V.
Web agency · Bălți
★★★★★

"Our NVMe VPS handles traffic spikes without a sweat. Full root, local datacenter, and billing in MDL — everything we wanted from a provider."

DC
Dmitri C.
SaaS founder · Chișinău