SysTutorials

Opening Ports with iptables: A Practical Guide

· updated April 11, 2026

iptables remains the standard firewall interface across most Linux distributions, though it’s technically a compatibility layer over nftables. Whether you’re managing legacy systems or prefer the familiar syntax, here’s what you need to know.

Basic Command to Open a Port

The fundamental syntax to allow inbound traffic on a specific port:

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

Breaking this down:

Common Port-Opening Scenarios

Allow HTTP traffic:

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

Allow HTTPS traffic:

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

Allow SSH (test before saving to avoid locking yourself out):

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

Allow a port range:

sudo iptables -A INPUT -p tcp --dport 8000:8100 -j ACCEPT

Allow traffic from a specific source IP:

sudo iptables -A INPUT -p tcp --dport 80 -s 192.168.1.100 -j ACCEPT

Allow traffic on all interfaces except one:

sudo iptables -A INPUT -p tcp --dport 80 ! -i docker0 -j ACCEPT

Allow both TCP and UDP on the same port:

sudo iptables -A INPUT -p tcp --dport 53 -j ACCEPT
sudo iptables -A INPUT -p udp --dport 53 -j ACCEPT

Making Rules Persistent

iptables rules exist only in memory and flush on reboot. Choose the method that matches your distribution:

Debian/Ubuntu with iptables-persistent

sudo apt install iptables-persistent
sudo iptables-save > /etc/iptables/rules.v4
sudo netfilter-persistent save

RHEL/CentOS/Fedora with iptables-services

sudo dnf install iptables-services
sudo iptables-save > /etc/sysconfig/iptables
sudo systemctl enable iptables
sudo systemctl restart iptables

Modern RHEL 8+/Fedora with firewalld

sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --reload

Ubuntu 18.04+ with ufw

sudo ufw allow 80/tcp
sudo ufw enable

Viewing and Managing Rules

List all current rules:

sudo iptables -L -n

List rules with line numbers:

sudo iptables -L -n --line-numbers

Delete a specific rule by line number:

sudo iptables -D INPUT 3

Delete a rule by specification:

sudo iptables -D INPUT -p tcp --dport 80 -j ACCEPT

Show rule counts and packet statistics:

sudo iptables -L -n -v

Flush all rules (dangerous on remote systems):

sudo iptables -F

Advanced Rule Management

Insert a rule at a specific position instead of appending:

sudo iptables -I INPUT 1 -p tcp --dport 443 -j ACCEPT

This places the rule at position 1, pushing other rules down. Useful when you need a rule to take precedence.

Add rules with connection state tracking (more efficient):

sudo iptables -A INPUT -p tcp --dport 80 -m state --state NEW,ESTABLISHED -j ACCEPT
sudo iptables -A OUTPUT -p tcp --sport 80 -m state --state ESTABLISHED -j ACCEPT

Allow traffic from a subnet:

sudo iptables -A INPUT -p tcp --dport 3306 -s 10.0.0.0/24 -j ACCEPT

Create a rule that logs before accepting:

sudo iptables -A INPUT -p tcp --dport 22 -m limit --limit 5/min --limit-burst 10 -j LOG --log-prefix "SSH_ATTEMPT: "
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT

Modern Alternatives

For new systems or if you have flexibility:

firewalld offers a user-friendly zone-based system and is standard on RHEL 8+, CentOS 8+, and recent Fedora versions. Rules are persistent by default and can be modified without reloading:

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload

ufw is simpler and recommended for Ubuntu/Debian systems. Install with apt install ufw, then enable and manage rules through straightforward commands:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw enable

nftables is the kernel successor to iptables, offering better performance and cleaner syntax. Most systems still ship iptables compatibility, but nftables is becoming the default:

sudo nft add rule inet filter input tcp dport 80 accept
sudo nft list ruleset

Important Considerations

Order matters — iptables processes rules top-to-bottom. A REJECT rule placed early will block traffic before a later ACCEPT rule sees it.

Always test SSH rules on remote systems before saving. Open the port, verify connectivity, then persist the rules. If you lock yourself out, console access or out-of-band management is your only option.

Use --dport for destination port (incoming traffic) and --sport for source port (less common, used for outbound filtering).

Combine -A to append rules or -I to insert at a specific line number. Use -R to replace an existing rule.

Check your distribution’s default policy. If INPUT is set to DROP, you need explicit ACCEPT rules. If it’s set to ACCEPT, you need explicit DROP/REJECT rules to restrict traffic.

For production systems, consider whether firewalld or ufw better matches your workflow. iptables is powerful but less forgiving than zone-based firewalls.

← All posts