This is a discussion on very slow client/ how should server close before request? within the Linux Web Servers forums, part of the Web Server and Related Forums category; So I've got a not-very-hypothetical situation where a client makes a connection to my (modified apache) web ...
|
|||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
|
|||
|
So I've got a not-very-hypothetical situation where a client makes a
connection to my (modified apache) web server, and then is very slow about sending a request). The hypothetical part is that it might be part of a DOS attack trying to use up connections etc, or it might really just be a slow client/network... So sometime between the tcp connection and when the http request would theoretically be made, the server decides that it's done, and can't spend any more resources and wants to close and move on with it's life... I know that you can limit max connections to stop excess resource usage from clients like this but for a variety of reasons, in my application, it would be nice have the server close the connection before it has ever recieved a request. The rfc2068 isn't really clear about what the proper thing to do in this case is, and the two most popular browsers respond differently to the remote shudtown. Ideally it'd be nice to send some sort of 503, but I expect that the browsers aren't really ready for a response and logically you can't send a 503 RESPONSE to a query you haven't recieved yet. So is there a canonical, proper thing to do in this situation? a suggested best practice? something else I could do that will not break browsers too terribly? I've deliberately left out some details above, but here is a more full explanation of what I'm doing. I've got a custom apache module to go along with some custom kernel hacks to allow a single apache to more fully isolate different virtual hosts in a shared-web-hosting application. Apache does 95% of the work for each connection under the UID of the user/IP the request came in from - custom process scheduling makes it so that each user can't dominate the system resources that count - cpu/ram/disk-io etc. Each user has other services besides http running (as that uid) as well. Right now we have process limits in place for each account - e.g. this account can't have more than 30 processes running... It woud be nice to tell apache to not use more than say, 25 or 28 of those processes so that at least a trickle of email and or shell-access are possible under heavy or abusive web load. Currently, the apache module, once it finds out who the connection is coming in for, changes UID and handles the connection. So, a DOS 'connection' attack to apache will take a user very far over their process limit because the processes are not being created by the user, but by apache, and then apache suid's to the user. Just before the switch, we have a nice system call that can return in O(1) time the number of processes the target user currently has and decide to continue with the connection or drop it. We have to wait till the connection is established because otherwise we dont know who it was for... It would be nice to find a graceful way to do a 503 or something similar so that the end user knows the server (account) is overloaded rather than just fail with IE's "The page cannont be displayed" or Firefox's empty html document. (And yes, I know there is a small race condition here... where you could still go over the limit - at least the rest of the accounts on the server would be modestly protected from an abusive or attacked other account) I do understand that a technically more correct, but much more expensive way of handling this is to monitor every user's process limit and conditionally remove them from the select set when they are over their limit so that browsers will not be able to connect to that particular IP/virtual host. This is also not very user-friendly, but I could live with it - it's just a complicated way of fixing things, and even harder to maintain going forward. A 3rd option would be to do the process check for the connection and if the target UID is already over limit then just dont switch uid and wait for any request at all and then send a 503 or timeout very early if no request arrives. This might cover the user-friendlyness and DOS-resistance somewhat but then a DOS attack could still run apache out of processes removing service for all virtual hosts on the box... So, suggestions? how can I politely say "uh, nevermind" and close a connection before a client sends an initial request? Fred |
|
|||
|
minektur wrote:
> So I've got a not-very-hypothetical situation where a client makes a > connection to my (modified apache) web server, and then is very slow > about sending a request). The hypothetical part is that it might be > part of a DOS attack trying to use up connections etc, or it might > really just be a slow client/network... This has been discussed on dev@httpd quite a few times. Recent apaches use Accept filters (where supported by the operating system) to deal with it. If you're interested in the details, browse svn and the archives at marc.theaimsgroup.com -- Nick Kew |