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