Currently using Centos6.7 and looking to put some limits in place to stop say user x from ip y from making more than say 5 connections. Say he logs in 5 times, those 5 will establish but the 6th will be rejected.

Looking in to using connlimit to do this but feel like I'm missing something and I'm slightly gun shy around putting the rule in place as I've inadvertently locked myself out of the server in the past putting a rule in the wrong spot (oops).

Notes: Not looking to specify a port. x.x.x.1 and x.x.x.2 are IP's with higher limits of 50 so I put those rules first, I believe that's correct?

I have the below:

-A INPUT -p tcp -s x.x.x.1 --syn -m connlimit --connlimit-above 50 -j REJECT
-A INPUT -p tcp -s x.x.x.2 --syn -m connlimit --connlimit-above 50 -j REJECT
-A INPUT -p tcp --syn -m connlimit --connlimit-above 5 -j REJECT

Does this look correct? Is there a different way to go about this? I don't want to limit to a pool of only 5 connections total but 5 per IP address.


Almost, but not quite there. The rules you created would first reject connections above 50 from x.1 and x.2, and then reject any connections above 5 from anywhere, including x.1 and x.2. You need to have an ACCEPT rule for those two sources before the common limiter.

It may be easiest to invert the match on the connlimit:

-A INPUT -p tcp -s x.x.x.1 --syn -m connlimit --connlimit-upto 50 -j ACCEPT
-A INPUT -p tcp -s x.x.x.2 --syn -m connlimit --connlimit-upto 50 -j ACCEPT
-A INPUT -p tcp --syn -m connlimit --connlimit-upto 5 -j ACCEPT
-A INPUT -p tcp --syn -j REJECT

You might want to put those rules in a chain of their own so you don't need to repeat the common parts (-p tcp --syn), and with a separate chain you can also replace ACCEPT with RETURN if you want to do other filtering after those rules. The accepting rule would need to appear somewhere else, then.

The default for connlimit is to work per source address, so it should be what you want. Though note that iptables doesn't have any concept of "logging in", so if you actually want to limit logins on an application level, you'll need to do it there.

To prevent yourself from getting locked out, you might want to make sure you have a separate rule very first to allow administrative access from your machine (SSH perhaps, at least already established connections). Another possibility would be to use cron or at to reset the firewall rules to some known-good configuration after a moment, so even if you do get locked out, it won't last. You'll just have to remember to remove that safeguard when you're done.

| improve this answer | |
  • That makes sense for sure. I went ahead and threw a rule in early to allow my address (and a separate VPN as a backup) ssh access. I had originally limited to 5, had myself locked out, and needed to wait on active connections to drop below 5 to log back in -_-. So I should just look at it kinda backwards as you suggested, my x.1 and x.2 addresses should accept up to 50, accept up to 5 for everything else, then a flat reject to cover the remaining? (assuming I'm reading that correct). – Hollyw00d Aug 27 '16 at 16:03
  • @Hollyw00d, yeah, that would seem simplest in this case. In any case you need to somehow make the connections from x.1 and x.2 go around the common rule. An ACCEPT or RETURN before it seems easiest, since iptables doesn't have an "if ... else if ... else ..." construct. – ilkkachu Aug 27 '16 at 16:15
  • @ikkachu Much appreciated, thanks for the help! – Hollyw00d Aug 27 '16 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.