Learn through the super-clean Baeldung Pro experience:
>> Membership and Baeldung Pro.
No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.
Last updated: March 14, 2024
As network administrators, we quite often find ourselves in situations where we need to control the number of connections to a particular server. This could be to prevent overload, ensure fair resource allocation, or protect against certain types of attacks, like denial-of-service (DoS) attacks.
Fortunately, iptables, a powerful firewall utility for Linux, provides us with a solution for this. By using iptables, we can easily set rules to limit the maximum number of connections allowed to a server, effectively managing and controlling incoming traffic.
In this tutorial, we’ll dive into how to use iptables to accomplish this task. We’ll explore the various options and parameters available, as well as provide practical examples to demonstrate their usage.
In iptables, a module or extension is a small program that extends the functionality of the firewall. It provides additional features and options that can be used to customize the behavior of iptables. Using the -m or –match option, we can use various useful modules such as bpf, cgroup, conntrack, and others.
One such module is connlimit, which is used to limit the number of parallel connections that can be made to a specific server or port. It helps us by setting a maximum threshold for incoming connections, preventing a single source from overwhelming the server with too many connections. By using the connlimit module in iptables, we can effectively control and manage the incoming traffic to our server, ensuring that it doesn’t exceed a certain limit.
Before we delve into using connlimit, it’s important to note that while it can be effective in limiting incoming connections, it may not always be a perfect solution for every scenario.
Let’s consider cases like DoS attacks, where the attacker may use techniques such as IP spoofing or botnets with multiple distributed IP addresses. They could potentially bypass the iptables rules by distributing their attack across multiple IP addresses.
In addition, iptables rules may not be effective against application-layer attacks where the attacker manipulates the connection in a way that doesn’t trigger the firewall rule. Also, limiting connections based on protocols used may backfire, since certain protocols (such as ICMP) are essential for troubleshooting and checking network health.
Therefore, while connlimit can be a valuable option in our iptables toolkit, it’s essential to carefully consider its limitations and deploy firewall rules with care and utmost consideration.
Let’s see the general syntax of using iptables with the connlimit extension and its various options that might be relevant to connection control:
$ iptables -A INPUT -p $protocol --dport $port -m connlimit --connlimit-above N --connlimit-mask M -j [REJECT --reject-with tcp-reset | DROP]
Since there are lots of options, let’s explain them one by one:
Since there are lots of options, we can tweak iptables rules to the particular scenario we want to achieve.
Let’s now see some particular use cases of the connlimit extension in iptables with practical examples.
When managing network traffic, we often encounter situations where we need to restrict the number of connections for a specific protocol. In such cases, we can utilize the connlimit module in iptables to impose connection limits. Let’s look at an example for setting limits on TCP connections to the HTTP port (80) so that no more than 30 connections can be established at a time:
$ iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 30 -j REJECT --reject-with tcp-reset
Here’s a breakdown of the options used:
We send the TCP reset to inform the connecting host that their connection attempt has been rejected due to exceeding the specified connection limit. This helps in maintaining network integrity.
Cases may arise where we want to specify rules per IP address or limit connections for an entire class of IP addresses altogether. We can achieve this using the connlimit module as well. Let’s adjust the previous rule to limit TCP connections per IP address to 20 parallel connections:
$ iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 32 -j REJECT --reject-with tcp-reset
Let’s see another example of how to limit TCP connections for an entire class of IP addresses to destination port 80:
$ iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 20 --connlimit-mask 24 -j DROP
Now, we’re setting the prefix mask to 24, so only the last eight bits of the network bitmask can change. Therefore, this indicates that we’re limiting the entire range of class C IP addresses to 20 connections in total. So, each subnet of 254 hosts in a particular class C IP block are limited to 20 connections. Furthermore, here, we’re dropping the packet using -j DROP instead of REJECT. This allows for a smoother experience on the user side.
Sometimes, we might need to control the rate at which connections are accepted. This is to ensure optimal network performance and to protect against potential threats such as DoS attacks. This can be achieved by using the iptables command to limit the number of connections per second:
$ iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -m limit --limit 150/second -j ACCEPT
Here the –ctstate RELATED,ESTABLISHED option matches packets that are related to an existing connection or part of an established connection. This rule ensures that only packets related to existing connections or part of established connections are processed.
The -m limit option is another extension with iptables that allows us to set packet limits. Using –limit 150/second, we specify the maximum average rate. In this case, it limits the rate to 150 packets per second. Finally, -j ACCEPT means that if the packet matches the criteria and passes the rate limit, it’s accepted and allowed to continue by jumping to the ACCEPT target.
When configuring iptables rules, we have the option to use either REJECT or DROP for processing packets. The choice between the two depends on how we want the client to behave in response to the blocked connection. Using REJECT immediately notifies the client that the service is unavailable, resulting in an instant “Not available” status.
On the other hand, DROP causes the client to wait and retry multiple times before reporting the site as unavailable. Therefore, the behavior appears more like a bad connection than an offline server.
Also, REJECT may result in slightly less traffic to the site, while DROP can cause the client to send additional packets while retrying. Additionally, if the connection limit drops back down while the client is still retrying, it’ll eventually get through to the server.
However, using REJECT can be beneficial in scenarios where port 80 traffic is part of a cluster. In such cases, it informs the cluster controller that the server is temporarily down and shouldn’t receive traffic.
Understanding how to effectively manage and control incoming traffic is crucial for maintaining the stability and security of our servers. By learning about connlimit, we can now set rules and restrict the number of connections to specific servers or ports.
In this article, we’ve learned about the options in iptables that are relevant to controlling the maximum number of connections to a host. Additionally, we discussed the challenges and considerations when limiting connections. We also discussed the choice between using REJECT or DROP for processing packets. By exploring example scenarios, we gained practical insights into applying these concepts in real-world network configurations.