1. Introduction
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.
2. Connlimit: an Iptables Module
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.
3. Disclaimer on Limiting Connections
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.
4. General Syntax for Limiting Connections Using iptables
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:
- -A INPUT: The -A option is for appending a rule to a specified chain. Here, we’re adding a rule to the INPUT chain, which is responsible for processing incoming packets.
- -p $protocol: This specifies the protocol for the rule, for example, tcp, ssh, or udp. In this case, we’re substituting it with the value of the protocol variable.
- –dport $port: This specifies the destination port for the rule, where $port is the port number we want to apply the rule to.
- -m connlimit: The -m or –match option helps us specify a particular module or extension to use. Here, we’re using the connlimit module, which allows us to limit the number of connections.
- –connlimit-above N: This option sets the threshold for the maximum number of connections allowed to N. Connections exceeding this limit will trigger the rule action.
- –connlimit-mask M: This option specifies the bitmask of the network address to match, where M is the network mask. The value of M can be 32 (for specific IP addresses), 24 (for class C IP addresses), or anything from 0 to 32 (inclusive).
- -j [REJECT –reject-with tcp-reset | DROP]: This specifies the action to take when the rule is matched. It can either reject the connection with a TCP reset packet (REJECT –reject-with tcp-reset) or drop the packet altogether (DROP).
Since there are lots of options, we can tweak iptables rules to the particular scenario we want to achieve.
5. Example Scenarios
Let’s now see some particular use cases of the connlimit extension in iptables with practical examples.
5.1. Limiting Specific Protocol Connections per Host
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:
- -A INPUT appends a rule to the INPUT chain of iptables
- -p tcp specifies the protocol as TCP, and –syn matches packets with the SYN flag set, indicating a new connection request
- –dport 80 sets the destination port for the incoming TCP connections
- -m connlimit utilizes the connlimit module to limit connections
- –connlimit-above 30 sets the maximum number of allowed connections for the current host
- Finally, the -j REJECT –reject-with tcp-reset rejects any connections exceeding the specified limit with a TCP reset
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.
5.2. Limiting Connections Based on IP Address
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.
5.3. Limiting Connections per Second
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.
5.4. Using REJECT vs. DROP for Processing Packets
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.
6. Conclusion
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.