How to Restrict iptables to Allow Only One IP Address on a Specific Port in Ubuntu


2 views

When securing a Linux server, you might need to restrict access to a specific service port to just one trusted IP address. This is a common security practice to minimize attack surfaces, especially for services like SSH (port 22), database ports, or custom application ports.

The solution involves creating two essential rules:

# Allow specific IP
sudo iptables -A INPUT -p tcp --dport [PORT] -s [ALLOWED_IP] -j ACCEPT

# Block all others for this port
sudo iptables -A INPUT -p tcp --dport [PORT] -j DROP

Let's implement this for SSH (port 22), allowing only IP 192.168.1.100:

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

Important: Always test these rules from the allowed IP first, as incorrect implementation can lock you out of your server.

Ubuntu doesn't save iptables rules by default. To make them persistent:

sudo apt-get install iptables-persistent
sudo netfilter-persistent save
sudo netfilter-persistent reload

Check if rules are properly applied:

sudo iptables -L -n --line-numbers

You should see output similar to this:

Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     tcp  --  192.168.1.100        0.0.0.0/0           tcp dpt:22
2    DROP       tcp  --  0.0.0.0/0            0.0.0.0/0           tcp dpt:22

For more complex scenarios, you might want to:

# Allow localhost connections
sudo iptables -I INPUT -i lo -j ACCEPT

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

If you accidentally lock yourself out, you can use the server's console access to:

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
sudo iptables -P INPUT ACCEPT

When securing a server, it's common to need restrictive firewall rules that allow only specific IP addresses to access particular services. With iptables, we can create precise network traffic control rules to achieve this security objective.

The fundamental command structure for our purpose looks like this:

iptables -A INPUT -p tcp --dport [PORT] -s [ALLOWED_IP] -j ACCEPT
iptables -A INPUT -p tcp --dport [PORT] -j DROP

Let's say we want to allow only IP 192.168.1.100 to access SSH (port 22):

# First, flush existing rules to start clean (use with caution)
iptables -F

# Set default policies
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT

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

# Allow localhost
iptables -A INPUT -i lo -j ACCEPT

# Specific rule for our allowed IP and port
iptables -A INPUT -p tcp --dport 22 -s 192.168.1.100 -j ACCEPT

# Explicitly block all other SSH attempts
iptables -A INPUT -p tcp --dport 22 -j DROP

On Ubuntu, you'll want to save these rules to persist across reboots:

# Install persistence package if needed
sudo apt-get install iptables-persistent

# Save current rules
sudo netfilter-persistent save

Check that your rules are properly configured:

iptables -L -n --line-numbers

For more complex scenarios, you might want to:

# Allow multiple IPs (using multiple rules or ipset)
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.100 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -s 192.168.1.101 -j ACCEPT
iptables -A INPUT -p tcp --dport 3306 -j DROP

# Allow IP range (using CIDR notation)
iptables -A INPUT -p tcp --dport 80 -s 192.168.1.0/24 -j ACCEPT