How to Use Multiple Source IPs in a Single iptables Rule


2 views

Managing firewall rules efficiently is crucial for system administrators and developers. One common requirement is to apply the same rule to multiple source IP addresses without creating redundant entries. This article explores how to achieve this in iptables.

iptables itself doesn't natively support multiple source IPs in a single rule, but you can use the ipset utility to accomplish this. Here's how:

# First, create an IP set
ipset create allowed_ips hash:ip

# Add multiple IP addresses to the set
ipset add allowed_ips 192.168.1.100
ipset add allowed_ips 192.168.1.101
ipset add allowed_ips 10.0.0.50

# Create an iptables rule using the set
iptables -A INPUT -m set --match-set allowed_ips src -j ACCEPT

If your IPs are in sequential ranges, you can use CIDR notation:

iptables -A INPUT -s 192.168.1.100/31 -j ACCEPT  # Covers .100 and .101

Some older iptables versions support multiple -s parameters, but this is generally not recommended:

iptables -A INPUT -s 192.168.1.100 -s 192.168.1.101 -j ACCEPT

When dealing with large numbers of IPs (50+), ipset significantly outperforms individual rules. The hash-based lookup is much faster than linear rule traversal.

Here's a complete example for whitelisting multiple admin IPs for SSH access:

# Create the IP set
ipset create admin_ips hash:ip

# Add IPs
ipset add admin_ips 203.0.113.42
ipset add admin_ips 198.51.100.17
ipset add admin_ips 192.0.2.99

# Apply the rule
iptables -A INPUT -p tcp --dport 22 -m set --match-set admin_ips src -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

Remember to save your ipset configuration to make it persistent across reboots:

ipset save > /etc/ipset.conf

And restore it at boot by adding to your startup scripts:

ipset restore < /etc/ipset.conf

When working with iptables firewall rules, administrators often need to apply the same rule to multiple source IP addresses. Creating individual rules for each IP quickly becomes inefficient and hard to maintain.

The most efficient approach is to use ipset, which allows creating sets of IP addresses that can be referenced in a single iptables rule.

First, install ipset if not already present:

sudo apt-get install ipset  # For Debian/Ubuntu
sudo yum install ipset      # For CentOS/RHEL

Here's a complete example of creating an IP set and using it in iptables:

# Create an IP set named "allowed_ips" with hash:ip type
sudo ipset create allowed_ips hash:ip

# Add multiple IP addresses to the set
sudo ipset add allowed_ips 192.168.1.100
sudo ipset add allowed_ips 192.168.1.101
sudo ipset add allowed_ips 192.168.1.102

# Reference the set in an iptables rule
sudo iptables -A INPUT -m set --match-set allowed_ips src -j ACCEPT

For consecutive IPs, you can use CIDR notation:

sudo iptables -A INPUT -s 192.168.1.100/30 -j ACCEPT

To make your IP set persistent across reboots:

# Save the current set
sudo ipset save allowed_ips > /etc/ipset.conf

# Restore at boot (add to /etc/rc.local or similar)
ipset restore < /etc/ipset.conf

IP sets offer better performance than multiple individual rules because:

  • They use optimized data structures (hash tables)
  • Reduce the number of rules the kernel needs to evaluate
  • Simplify rule management

You can also create network-based groups:

# Create a network set
sudo ipset create network_group hash:net

# Add networks
sudo ipset add network_group 192.168.1.0/24
sudo ipset add network_group 10.0.0.0/16

# Use in iptables
sudo iptables -A INPUT -m set --match-set network_group src -j ACCEPT