Given some incentive after deep consideration of the slowloris claims. While I still do not believe Squid is vulnerable per-se and some people tested and found no such failures as claimed.

We could provide better administrative controls. This is one such that has been asked about many times and still does not exist.

Its tested immediately after accept() and is request type agnostic, right down to DNS TCP links, so care is warranted in hierarchy situations.

Utilizes the client DB to monitor accepted TCP links. Operates prior to everything so as to eliminate resource usage on the blocking case and close the windows of opportunity for dribble-attacks etc.

Default is to keep the status-quo of no limits.


After some discussion with Robert on IRC, we came to the agreement that prior to receiving the headers there is nothing Squid can do except a per-IP barrier. And post receiving headers it's to hard to tell the difference between a genuine slow request and an attack, so should not care and pass the request anyway.

This limit controls the first case, ACLs already control the second.


Amos
=== modified file 'src/cf.data.pre'
--- src/cf.data.pre	2009-06-25 13:32:03 +0000
+++ src/cf.data.pre	2009-06-26 10:21:17 +0000
@@ -5188,6 +5188,25 @@
 accept_filter data
 DOC_END
 
+NAME: client_max_connections
+TYPE: int
+LOC: Config.client_max_connections
+DEFAULT: -1
+DOC_START
+	Set an absolute limit on the number of connections a single
+	client IP can use. Any more than this and Squid will begin to drop
+	new connections from the client until it closes some links.
+
+	Note that this is a global limit. It affects all inbound connections
+	of any type from the client. For finer control of just HTTP requests
+	use the ACL access controls.
+
+	Requires client_db to be enabled (ON).
+
+	WARNING: This may have a negative effect on traffic received via
+	external proxies.
+DOC_END
+
 NAME: tcp_recv_bufsize
 COMMENT: (bytes)
 TYPE: b_size_t

=== modified file 'src/client_side.cc'
--- src/client_side.cc	2009-06-14 12:18:00 +0000
+++ src/client_side.cc	2009-06-26 10:00:07 +0000
@@ -2844,7 +2844,7 @@
     }
 
     if (!okToAccept())
-        AcceptLimiter::Instance().defer (sock, httpAccept, data);
+        AcceptLimiter::Instance().defer(sock, httpAccept, data);
     else
         /* kick off another one for later */
         comm_accept(sock, httpAccept, data);

=== modified file 'src/comm.cc'
--- src/comm.cc	2009-06-14 12:18:00 +0000
+++ src/comm.cc	2009-06-27 10:03:26 +0000
@@ -48,6 +48,7 @@
 #include "icmp/net_db.h"
 #include "ip/IpAddress.h"
 #include "ip/IpIntercept.h"
+#include "protos.h"
 
 #if defined(_SQUID_CYGWIN_)
 #include <sys/ioctl.h>
@@ -1392,6 +1393,14 @@
 
     details.peer = *gai;
 
+    if ( Config.client_max_connections > 0) {
+        if (clientdbEstablished(details.peer, 0) > Config.client_max_connections) {
+            debugs(50, 1, "NOTICE: " << details.peer << " attempting more than " << Config.client_max_connections << " connections.");
+            details.me.FreeAddrInfo(gai);
+            return COMM_ERROR;
+        }
+    }
+
     details.me.InitAddrInfo(gai);
 
     details.me.SetEmpty();

=== modified file 'src/structs.h'
--- src/structs.h	2009-06-25 13:32:03 +0000
+++ src/structs.h	2009-06-26 10:23:34 +0000
@@ -610,6 +610,8 @@
 #if USE_LOADABLE_MODULES
     wordlist *loadable_module_names;
 #endif
+
+    int client_max_connections;
 };
 
 SQUIDCEXTERN SquidConfig Config;

Reply via email to