Return-Path: Delivered-To: apmail-httpd-dev-archive@www.apache.org Received: (qmail 39813 invoked from network); 23 Jun 2009 04:07:33 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 23 Jun 2009 04:07:33 -0000 Received: (qmail 45016 invoked by uid 500); 23 Jun 2009 04:07:42 -0000 Delivered-To: apmail-httpd-dev-archive@httpd.apache.org Received: (qmail 44941 invoked by uid 500); 23 Jun 2009 04:07:42 -0000 Mailing-List: contact dev-help@httpd.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@httpd.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list dev@httpd.apache.org Received: (qmail 44932 invoked by uid 99); 23 Jun 2009 04:07:41 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jun 2009 04:07:41 +0000 X-ASF-Spam-Status: No, hits=-0.0 required=10.0 tests=SPF_PASS X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: domain of graham.dumpleton@gmail.com designates 209.85.222.197 as permitted sender) Received: from [209.85.222.197] (HELO mail-pz0-f197.google.com) (209.85.222.197) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 23 Jun 2009 04:07:30 +0000 Received: by pzk35 with SMTP id 35so649500pzk.10 for ; Mon, 22 Jun 2009 21:07:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:content-type :content-transfer-encoding; bh=J+xi+X3+E3BVB0bXm6NFrFeJoyVILy4yx+kmMeZlmAw=; b=jrvRJjbPYYiDtQnD+tMz+KQERNr57OumxK7lhnA3kPIYZPhvAs9q4k4erPIYaGg8md lGjvikm9dPwWreRWzeFgK5O0aldpQ+lCKiKcbjDcdAlVKN9ll/7hnUvmhdfnx5CFX4s6 AY5na1K/ddVpEfp8olhA/HHJRx20hol+ygbt8= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; b=jbO9fN/cnapNItIzUrDj4/igLcHQ9O6CI85wm/YQeJRg9uRwvRbpHEssZ04E6TC348 8zZ3jFvAiv2WgAvZp796UFecCxWrIE7gfDxCqk5nA1FCC9oBHJXxollEt9RtSMJloVS0 pRdaEinvfNX0r5wqP+P3nj1hLeCevWjqr3Vfk= MIME-Version: 1.0 Received: by 10.114.167.2 with SMTP id p2mr6333479wae.54.1245730029481; Mon, 22 Jun 2009 21:07:09 -0700 (PDT) In-Reply-To: <4A4040BB.8050306@gmail.com> References: <20090621111038.GA5742@synflood.at> <4A3EEC04.10503@apache.org> <20090622063657.GB5742@synflood.at> <4A3FC6B9.8060902@rowe-clan.net> <4A4040BB.8050306@gmail.com> Date: Tue, 23 Jun 2009 14:07:09 +1000 Message-ID: <88e286470906222107q8e63bffp23ac9c0043df757@mail.gmail.com> Subject: Re: Mitigating the Slowloris DoS attack From: Graham Dumpleton To: dev@httpd.apache.org Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Virus-Checked: Checked by ClamAV on apache.org 2009/6/23 Weibin Yao : > William A. Rowe, Jr. at 2009-6-23 2:00 wrote: >> >> Andreas Krennmair wrote: >> >>> >>> * Guenter Knauf [2009-06-22 04:30]: >>> >>>> >>>> wouldnt limiting the number of simultanous connections from one IP >>>> already help? F.e. something like: >>>> http://gpl.net.ua/modipcount/downloads.html >>>> >>> >>> Not only would this be futile against the Slowloris attack (imagine n >>> connections from n hosts instead of n connections from 1 host), it woul= d >>> also potentially lock out groups of people behind the same NAT gateway. >>> >> >> FWIW mod_remoteip can be used to partially mitigate the weakness of this >> class of solutions. >> >> However, it only works for known, trusted proxies, and can only be safel= y >> used for those with public IP's. =A0Where the same 10.0.0.5 on your priv= ate >> NAT backed becomes the same 10.0.0.5 within the apache server's DMZ, the >> issues like Allow from 10.0.0.0/8 become painfully obvious. =A0I haven't >> found a good solution, but mod_remoteip still needs one, eventually. >> >> > > I have an idea to mitigate the problem: put the Nginx as a reverse proxy > server in the front of apache. Although your comment is perhaps heresy here, it does highlight one of the things that nginx is good at, even if you don't use it to serve static files with Apache handling just the dynamic web application. That is, that it can isolate Apache from slow clients, whether that be an attack as in this case, or just normal users using slow networks. The proxy module of nginx in the way it will buffer up request content to disk before actually sending the request onto the backend also helps by not tying up Apache's limited request handler threads until the request content is completely available, although, nginx does have an upper limit on this at some point and will still stream when the post content is large enough. The nginx server works better at avoiding problems with slow clients because it is event driven rather than threaded and so can handle more connections without needing to tie up expensive threads. Unfortunately, trying to make socket accept handling in Apache be event driven and for requests to only be handed off to a thread for processing when ready can introduce its own problems. This is because an event driven system can tend to greedily accept new socket connections. In a multiprocess server configuration this can mean that a single process may accept more than its fair share of socket connections and by the time it has read the initial request headers, may not have enough available threads to handle the requests. In the mean time, another server process, which did not get in quick enough to accept some of the connections could be sitting their idle. How you mediate between multiple servers to avoid this sort of problem would be tricky if it can be done. Anyway, now for a hair brained suggestion that could bring some of this nginx goodness to Apache. Although no doubt it would have various limitations which to solve properly and be integrated seamlessly into Apache would require some changes in the core. The idea here is to have an Apache module which spawns off its own child process which implements a very small lightweight event driven proxy that listens on the real listener sockets you want to expose. This processes sole job would then be to handle reading in the request headers, and perhaps optionally buffering up request content, and then squirt it across to real Apache child server processes to be handled when it has all the information it needs. To that end, it wouldn't be a general purpose proxy but quite customised. As such, it could even perhaps be made more efficient than nginx in the way it is used to protect Apache from such things as slow clients. For HTTP at least, this probably wouldn't be too hard to do and wouldn't likely need any changes to the core. You could even have whether you use it be optional to the extent of it only applying to certain virtual hosts. Where it does though all get a lot harder is virtual hosts which use HTTPS. So, that is my crazy thought for the day and am sure that it will be derided for what is is worth. I still find the thought interesting though and it falls into that class of things I find interesting due to the challenge it presents. :-) Graham