4

Update:

I have tried sudo iptables -A INPUT -p tcp --dport 22 ! -s 1.2.3.4,11.22.33.44 -j DROP, Not working and it gives me an error

iptables v1.8.2 (nf_tables): ! not allowed with multiple source or destination IP addresses


For example, My goal is Only allow allow only 1.2.3.4 and 11.22.33.44 to connect the ssh(port 22) of my server.

And I prefer this approach/command rather than others.

sudo iptables -A INPUT -p tcp --dport 22 ! -s 1.2.3.4 -j DROP

But I don't know how to add another Allowed IP 11.22.33.44 in this command,

Could you give me a little bit help or tips?

Thanks.

rm -rf
  • 55
  • 4

2 Answers2

6

You can use an IP set.

Depending on your distro you may need to install the ipset utility first.

#(For Debian and Debian-derived distros)
sudo apt install ipset-persistent

Then you create a set with a friendly name.

sudo ipset create ssh_friends iphash

Once you have a set, you can add IPs to it.

sudo ipset add ssh_friends 1.2.3.4
sudo ipset add ssh_friends 11.22.33.44

Now you can use the set you created in an iptables rule instead of individual IPs.

sudo iptables -A INPUT -p tcp --destination-port 22 -m set ! --match-set ssh_friends src -j DROP
ThatGraemeGuy
  • 15,314
  • 12
  • 51
  • 78
-1

Defining multiple addresses using only one iptables command using ! --source is not possible.

A Address can be either a network name, a hostname (probably a really bad idea to use hostnames), a network IP address (with /mask), or a plain IP address. The mask can be either a network mask or a plain number.

You could consider to change the default ruleset from allow to drop. This would allow you to define based on only what should be allowed, i.e. similar like this:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
... your other rules goes here ...
iptables -A INPUT -m state --state NEW -p tcp --dport 22 -s 1.2.3.4,11.22.33.44 -j ACCEPT
iptables -P INPUT DROP

The benefit/beauty is that such a rule set would be much more performant, as the state of the packages is considered. Plus it allows the desired syntax. Plus is also the recommended way to define firewall rules.

However, please keep in mind that if using a syntax as shown above: -s 1.2.3.4,11.22.33.44 still creates 2 individual table entries, as you can see using the command iptables -L INPUT. In addition it does not work with all versions of iptables. In addition personally I find it hard to read or to maintain. That's the reason why I try to avoid it, in favour of using 2 separate commands.

In case your desire is to minimize the amount of rules, the closest you could do is to use one iptables rule using --match instead --source. However, you still have to define the match, using additional commands. How this works has been explained perfectly in the other comment which deals with ipset.

Lutz Willek
  • 653
  • 1
  • 10