1. Overview

iptables is a command-line firewall program that uses several policy chains to allow or block network traffic.

There might be cases where we need to specify multiple source IP addresses for filtering packets. In this tutorial, we’ll discuss how to specify multiple source IP addresses in a single rule.

2. Introduction to the Problem

We can use the -s option of iptables for specifying a source IP address that we’re interested in. Let’s examine setting a single source IP address using an example:

$ iptables –A INPUT –p icmp –s 192.16.22.41 –j REJECT

The -A INPUT part of the above command specified that we’re interested in the incoming traffic. The -p icmp part was for examining ICMP packets. The -s 192.16.22.41 part specified that we’re interested in packets with the source IP address 192.16.22.41. The -j option applied the REJECT rule to the filtered traffic. So, in summary, we specified that we want to apply the REJECT rule to the incoming ICMP packets from the host having the IP address 192.16.22.41.

What if we want to specify multiple source IP addresses in a single rule? We’ll find answers to this question in the following sections.

We’ll use four hosts while examining the usage of a single rule for specifying multiple source IP addresses. The names of the hosts are host1, host2, host3, and host4. The corresponding IP addresses are 192.16.22.40, 192.16.22.41, 192.16.22.42, and 192.16.22.43, respectively.

We need root privileges to use iptables.

3. The -s Option of iptables

We can use the -s option of iptables also for setting multiple source IP addresses. We just need to pass the source IP addresses to the -s option with commas between them.

Let’s apply the previous rule for source IP addresses 192.16.22.41 and 192.16.22.43 on host1:

$ iptables –A INPUT –s 192.16.22.41,192.16.22.43 –p icmp –j REJECT

We added the rule for multiple source IP addresses using -s 192.16.22.41,192.16.22.43 in the above command.

Now, let’s test whether we can ping host1 from host2:

$ ping –c 1 192.16.22.40
PING 192.16.22.40 (192.16.22.40) 56(84) bytes of data.
From 192.16.22.40 icmp_seq=1 Destination Port Unreachable

--- 192.16.22.40 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

We sent only one ICMP echo request from host2 to host1, but we got an immediate Destination Port Unreachable error. Similarly, pinging host1 from host4 will give the same error.

But, we must be able to ping host1 from host3 as we didn’t pass 192.16.22.42 to the -s option:

$ ping –c 1 192.16.22.40
PING 192.16.22.40 (192.16.22.40) 56(84) bytes of data.
64 bytes from 192.16.22.40: icmp_seq=1 ttl=63 time=0.572 ms

--- 192.16.22.40 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.572/0.572/0.572/0.000 ms

So, we were successful in specifying multiple source IP addresses in a single rule.

If the IP addresses are contiguous, then we can use subnets in the specification of source IP addresses:

$ iptables –A INPUT –s 192.16.22.40/30 –p icmp –j REJECT

In this case, we specified the IP addresses 192.16.22.40 to 192.16.22.43 as the source IP addresses using the CIDR notation 192.16.22.40/30.

4. The -m Option of iptables

It’s also possible to give a set of IP addresses to iptables using its -m option. But, we must first create the set using the ipset command:

$ ipset create my_ip_set iphash

We used the create option of ipset for creating a set named my_ip_set. The iphash argument is the set type. It uses a hash for storing the IP addresses. We can also use hash:ip instead of iphash.

Having created the set, we can add IP addresses to the set using the add option of ipset:

$ ipset add my_ip_set 192.16.22.41
$ ipset add my_ip_set 192.16.22.43

Here, we added two IP addresses to my_ip_set. Those IP addresses were 192.16.22.41 and 192.16.22.43.

Now, it’s time to apply this set using iptables:

$ iptables –D INPUT –s 192.16.22.41,192.16.22.43 –p icmp –j REJECT
$ iptables –A INPUT –p icmp –m set –-match-set my_ip_set src –j REJECT

First, we deleted the previously added rule. Then, we used the -m option of iptables for applying the set my_ip_set. The -m option extends iptables for using several packet matching modules. set is one of those modules. It matches IP sets that we define using ipset. –match-set is the set module’s option used for specifying sources and destinations. The –match-set my_ip_set src part of the command specified that we want to use the IP addresses in the set my_ip_set as source IP addresses.

Having applied the rule, let’s try to ping host1 from host2:

$ ping –c 1 192.16.22.40
PING 192.16.22.40 (192.16.22.40) 56(84) bytes of data.
From 192.16.22.40 icmp_seq=1 Destination Port Unreachable

--- 192.16.22.40 ping statistics ---
1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms

Similarly, pinging host1 from host4 will give the same error. However, pinging host1 from host3 will be successful as we didn’t add host3 to the set my_ip_set using ipset.

If the source IP addresses are in a contiguous block, we can use the iprange module of the option -m:

$ iptables –A INPUT –p icmp –m iprange –-src-range 192.16.22.41-192.16.22.43 –j REJECT

The IP addresses following the –src-range option of the iprange module specify that we’re interested in those IP addresses as the source. In our example, we specified that we want to reject all the ICMP packets from the hosts in the range 192.16.22-41192.16.22.43, including host2, host3, and host4.

5. Conclusion

In this article, we discussed how to specify multiple source IP addresses using a single rule.

First, we discussed the -s option of iptables. We can pass multiple IP addresses to the -s option by simply separating the IP addresses with commas.

If the source IP addresses are contiguous, we can pass a network IP address to the -s option.

Then, we examined the -m option of iptables. We saw that creating a set and then adding IP addresses to that set are possible using the create and add options of ipset. We must apply the set to iptables using the set module of the -m option.

Finally, we learned that it’s possible to use the iprange module of the -m option for specifying a contiguous range of IP addresses.