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;