diff options
-rw-r--r-- | network/mod_limitipconn/README | 66 | ||||
-rw-r--r-- | network/mod_limitipconn/mod_limitipconn.SlackBuild | 20 | ||||
-rw-r--r-- | network/mod_limitipconn/mod_limitipconn.c | 320 | ||||
-rw-r--r-- | network/mod_limitipconn/mod_limitipconn.info | 10 | ||||
-rw-r--r-- | network/mod_limitipconn/slack-desc | 2 |
5 files changed, 17 insertions, 401 deletions
diff --git a/network/mod_limitipconn/README b/network/mod_limitipconn/README index 34bf2a7aab..572ce02f33 100644 --- a/network/mod_limitipconn/README +++ b/network/mod_limitipconn/README @@ -1,63 +1,6 @@ -From: -http://www.mail-archive.com/dev@httpd.apache.org/msg37189.html - -Hi! - - -Attached is a version of mod_limitipconn.c that works in conjunction with -mod_cache and httpd-2.2. We've been using this on ftp.acc.umu.se for some -time now without any unwanted issues. - -The main problem with mod_limitipconn-0.22 was that since mod_cache runs as -a quick handler, mod_limitipconn also must run as a quick handler with all -those benefits and drawbacks. - -Download the tarball from http://dominia.org/djao/limitipconn2.html , extract -it, and replace mod_limitipconn.c with this version and follow the build -instructions. - -I would really wish that this was made part of httpd, it's really needed when -running a file-download site due to the scarily large amount of demented -download manager clients out there. - -However, I have not received any response from the original author on the -matter. From what I have understood of the license it should be OK to merge -into httpd if you want though, but I think that you guys are way more clued -in that matter than me. - -This is a summary of the changes made: -* Rewritten to run as a Quick Handler, before mod_cache. -* Configuration directives are now set per VHost (Directory/Location - are available after the Quick Handler has been run). This means that - any <Location> containers has to be deleted in existing configs. -* Fixed configuration merging, so per-vhost settings use defaults set - at the server level. -* By running as a Quick Handler we don't go through the entire lookup - phase (resolve path, stat file, etc) before we get the possibility - to block a request. This gives a clear performance enhancement. -* Made the handler exit as soon as possible, doing the "easy" checks - first. -* Don't do subrequest to lookup MIME type if we don't have mime-type - specific config. -* Count connections in closing and logging state too, we don't want to - be DOS'd by clients behind buggy firewalls and so on. -* Added debug messages for easy debugging. -* Reduced loglevel from ERR to INFO for reject-logging. - -In any case, I hope that this can be of use for others than us. - - -/Nikke --- --=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- - Niklas Edmundsson, Admin @ {acc,hpc2n}.umu.se | [EMAIL PROTECTED] ---------------------------------------------------------------------------- - We are AT&T of Borg, MCI will be assimilated -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - -(FWIW: copied without explicit permission) - --- +mod_limitipconn is an Apache which allows web server administrators +to limit the number of simultaneous downloads permitted from a single +IP address. The module can be loaded with the following in /etc/httpd/httpd.conf @@ -66,4 +9,7 @@ ExtendedStatus On MaxConnPerIP 5 To test the 'test.pl' utility from mod_evasive is included in the doc dir. +Which when run multiple simultainus sessions of should similate accessive +connectivity; e.g. with MaxConnPerIP set to ``1'' +while true; do (perl ./test.pl &); perl ./test.pl; done diff --git a/network/mod_limitipconn/mod_limitipconn.SlackBuild b/network/mod_limitipconn/mod_limitipconn.SlackBuild index 916d0475da..cd91e2be00 100644 --- a/network/mod_limitipconn/mod_limitipconn.SlackBuild +++ b/network/mod_limitipconn/mod_limitipconn.SlackBuild @@ -2,7 +2,7 @@ # Slackware build script for mod_limitipconn (an Apache limit module) -# Written by Menno E. Duursma +# Written by Menno Duursma # This program is free software. It comes without any warranty. # Granted WTFPL, Version 2, as published by Sam Hocevar. See @@ -11,7 +11,7 @@ # Modified by SlackBuilds.org PRGNAM=mod_limitipconn -VERSION=${VERSION:-0.22} +VERSION=${VERSION:-0.23} ARCH=${ARCH:-i486} BUILD=${BUILD:-1} TAG=${TAG:-_SBo} @@ -35,30 +35,20 @@ rm -rf $PKG mkdir -p $TMP $PKG $OUTPUT cd $TMP rm -rf $PRGNAM-$VERSION -tar xvf $CWD/$PRGNAM-$VERSION.tar.gz +tar jxvf $CWD/$PRGNAM-$VERSION.tar.bz2 cd $PRGNAM-$VERSION chown -R root:root . chmod -R a-s,u+w,go+r-w . -# This is patched for Apache v2.2 support so much we might as well replace it -cat $CWD/mod_limitipconn.c > mod_limitipconn.c - -# Create target directory -mkdir -p $PKG/usr/lib/httpd/modules - # Compile module as DSO (dynmically shared object) CFLAGS="$SLACKFLAGS" \ apxs -ca mod_limitipconn.c # copy into place -cp -v .libs/mod_limitipconn.so $PKG/usr/lib/httpd/modules - -( cd $PKG || exit 1 - find . -type f | xargs file | grep -e "executable" -e "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null -) +install -D -m755 -s .libs/mod_limitipconn.so $PKG/usr/lib/httpd/modules/mod_limitipconn.so mkdir -p $PKG/usr/doc/$PRGNAM-$VERSION -cp -a ChangeLog INSTALL README $PKG/usr/doc/$PRGNAM-$VERSION +cp -a ChangeLog INSTALL README LICENSE $PKG/usr/doc/$PRGNAM-$VERSION cat $CWD/test.pl > $PKG/usr/doc/$PRGNAM-$VERSION/test.pl cat $CWD/$PRGNAM.SlackBuild > $PKG/usr/doc/$PRGNAM-$VERSION/$PRGNAM.SlackBuild diff --git a/network/mod_limitipconn/mod_limitipconn.c b/network/mod_limitipconn/mod_limitipconn.c deleted file mode 100644 index a53683c7db..0000000000 --- a/network/mod_limitipconn/mod_limitipconn.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (C) 2000-2002 David Jao <[EMAIL PROTECTED]> - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, copy, - * modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice, this permission notice, and the - * following disclaimer shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - * - */ - -#include "httpd.h" -#include "http_config.h" -#include "http_request.h" -#include "http_protocol.h" -#include "http_core.h" -#include "http_main.h" -#include "http_log.h" -#include "ap_mpm.h" -#include "apr_strings.h" -#include "scoreboard.h" - -#define MODULE_NAME "mod_limitipconn" -#define MODULE_VERSION "0.22" - -module AP_MODULE_DECLARE_DATA limitipconn_module; - -static int server_limit, thread_limit; - -typedef struct { - signed int limit; /* max number of connections per IP */ - - /* array of MIME types exempt from limit checking */ - apr_array_header_t *no_limit; - int no_limit_set; - - /* array of MIME types to limit check; all other types are exempt */ - apr_array_header_t *excl_limit; - int excl_limit_set; -} limitipconn_config; - -static void *limitipconn_create_config(apr_pool_t *p, server_rec *s) -{ - limitipconn_config *cfg = (limitipconn_config *) - apr_pcalloc(p, sizeof (*cfg)); - - /* default configuration: no limit (unset), and both arrays are empty */ - cfg->limit = -1; - cfg->no_limit = apr_array_make(p, 0, sizeof(char *)); - cfg->excl_limit = apr_array_make(p, 0, sizeof(char *)); - - return cfg; -} - -/* Simple merge: Per vhost entries overrides main server entries */ -static void *limitipconn_merge_config(apr_pool_t *p, void *BASE, void *ADD) -{ - limitipconn_config *base = BASE; - limitipconn_config *add = ADD; - - limitipconn_config *cfg = (limitipconn_config *) - apr_pcalloc(p, sizeof (*cfg)); - - cfg->limit = (add->limit == -1) ? base->limit : add->limit; - cfg->no_limit = add->no_limit_set ? add->no_limit : base->no_limit; - cfg->excl_limit = add->excl_limit_set ? add->excl_limit : base->excl_limit; - - return cfg; -} - -/* The handler runs as a quick handler so we can arrange for it to be called - before mod_cache. Being a quick handler means that we have a lot of - limitations, the basic ones are that the only thing we know is the URL and - that if we return OK it means that we handle the entire reply of the - request including populating the brigades with data. */ -static int limitipconn_handler(request_rec *r, int lookup) -{ - /* get configuration information */ - limitipconn_config *cfg = (limitipconn_config *) - ap_get_module_config(r->server->module_config, &limitipconn_module); - - /* convert Apache arrays to normal C arrays */ - char **nolim = (char **) cfg->no_limit->elts; - char **exlim = (char **) cfg->excl_limit->elts; - - const char *address; - - /* loop index variables */ - int i; - int j; - - /* running count of number of connections from this address */ - int ip_count = 0; - - /* Content-type of the current request */ - const char *content_type; - - /* scoreboard data structure */ - worker_score *ws_record; - - /* We decline to handle subrequests: otherwise, in the next step we - * could get into an infinite loop. */ - if (!ap_is_initial_req(r)) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: SKIPPED: Not initial request"); - return DECLINED; - } - - /* A limit value of 0 by convention means no limit, negative means - unset (no limit). */ - if (cfg->limit <= 0) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: OK: No limit"); - return DECLINED; - } - -#ifdef RECORD_FORWARD - if ((address = apr_table_get(r->headers_in, "X-Forwarded-For")) == NULL) -#endif - address = r->connection->remote_ip; - - /* Only check the MIME-type if we have MIME-type stuff in our config. - That extra subreq can be quite expensive. */ - if(cfg->no_limit->nelts > 0 || cfg->excl_limit->nelts > 0) { - /* Look up the Content-type of this request. We need a subrequest - * here since this module might be called before the URI has been - * translated into a MIME type. */ - content_type = ap_sub_req_lookup_uri(r->uri, r, NULL)->content_type; - - /* If there's no Content-type, use the default. */ - if (!content_type) { - content_type = ap_default_type(r); - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: uri: %s Content-Type: %s", - r->uri, content_type); - - /* Cycle through the exempt list; if our content_type is exempt, - * return OK */ - for (i = 0; i < cfg->no_limit->nelts; i++) { - if ((ap_strcasecmp_match(content_type, nolim[i]) == 0) - || (strncmp(nolim[i], content_type, strlen(nolim[i])) == 0)) - { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: OK: %s exempt", content_type); - return DECLINED; - } - } - - /* Cycle through the exclusive list, if it exists; if our MIME type - * is not present, bail out */ - if (cfg->excl_limit->nelts) { - int excused = 1; - for (i = 0; i < cfg->excl_limit->nelts; i++) { - if ((ap_strcasecmp_match(content_type, exlim[i]) == 0) - || - (strncmp(exlim[i], content_type, strlen(exlim[i])) == 0)) - { - excused = 0; - } - } - if (excused) { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: OK: %s not excluded", - content_type); - return DECLINED; - } - } - } - - /* Count up the number of connections we are handling right now from - * this IP address */ - for (i = 0; i < server_limit; ++i) { - for (j = 0; j < thread_limit; ++j) { - ws_record = ap_get_scoreboard_worker(i, j); - switch (ws_record->status) { - case SERVER_BUSY_READ: - case SERVER_BUSY_WRITE: - case SERVER_BUSY_KEEPALIVE: - case SERVER_BUSY_LOG: - case SERVER_BUSY_DNS: - case SERVER_CLOSING: - case SERVER_GRACEFUL: - if ((strcmp(address, ws_record->client) == 0) -#ifdef RECORD_FORWARD - || (strcmp(address, ws_record->fwdclient) == 0) -#endif - ) { - ip_count++; - } - break; - default: - break; - } - } - } - - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: vhost: %s uri: %s current: %d limit: %d", - r->server->server_hostname, r->uri, ip_count, cfg->limit); - - if (ip_count > cfg->limit) { - ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, - "Rejected, too many connections from this host."); - /* set an environment variable */ - apr_table_setn(r->subprocess_env, "LIMITIP", "1"); - /* return 503 */ - return HTTP_SERVICE_UNAVAILABLE; - } else { - ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, - "mod_limitipconn: OK: Passed all checks"); - return DECLINED; - } -} - -/* Parse the MaxConnPerIP directive */ -static const char *limit_config_cmd(cmd_parms *parms, void *dummy, - const char *arg) -{ - limitipconn_config *cfg = (limitipconn_config *) - ap_get_module_config(parms->server->module_config, - &limitipconn_module); - - signed long int limit = strtol(arg, (char **) NULL, 10); - - /* No reasonable person would want more than 2^16. Better would be - to use LONG_MAX but that causes portability problems on win32 */ - if ((limit > 65535) || (limit < 0)) { - return "Integer overflow or invalid number"; - } - - cfg->limit = limit; - return NULL; -} - -/* Parse the NoIPLimit directive */ -static const char *no_limit_config_cmd(cmd_parms *parms, void *dummy, - const char *arg) -{ - limitipconn_config *cfg = (limitipconn_config *) - ap_get_module_config(parms->server->module_config, - &limitipconn_module); - - *(char **) apr_array_push(cfg->no_limit) = apr_pstrdup(parms->pool, arg); - cfg->no_limit_set = 1; - return NULL; -} - -/* Parse the OnlyIPLimit directive */ -static const char *excl_limit_config_cmd(cmd_parms *parms, void *dummy, - const char *arg) -{ - limitipconn_config *cfg = (limitipconn_config *) - ap_get_module_config(parms->server->module_config, - &limitipconn_module); - - *(char **) apr_array_push(cfg->excl_limit) = apr_pstrdup(parms->pool, arg); - cfg->excl_limit_set = 1; - return NULL; -} - -/* Array describing structure of configuration directives */ -static command_rec limitipconn_cmds[] = { - AP_INIT_TAKE1("MaxConnPerIP", limit_config_cmd, NULL, RSRC_CONF, - "maximum simultaneous connections per IP address"), - AP_INIT_ITERATE("NoIPLimit", no_limit_config_cmd, NULL, RSRC_CONF, - "MIME types for which limit checking is disabled"), - AP_INIT_ITERATE("OnlyIPLimit", excl_limit_config_cmd, NULL, RSRC_CONF, - "restrict limit checking to these MIME types only"), - {NULL}, -}; - -/* Set up startup-time initialization */ -static int limitipconn_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, -server_rec *s) -{ - ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, - MODULE_NAME " " MODULE_VERSION " started."); - ap_mpm_query(AP_MPMQ_HARD_LIMIT_THREADS, &thread_limit); - ap_mpm_query(AP_MPMQ_HARD_LIMIT_DAEMONS, &server_limit); - return OK; -} - -static void register_hooks(apr_pool_t *p) -{ - static const char * const after_me[] = { "mod_cache.c", NULL }; - - /* We must run as a quick handle so we can deny connections before - mod_cache gets to serve them */ - ap_hook_quick_handler(limitipconn_handler, NULL, after_me, APR_HOOK_FIRST); - - ap_hook_post_config(limitipconn_init, NULL, NULL, APR_HOOK_MIDDLE); -} - -module AP_MODULE_DECLARE_DATA limitipconn_module = { - STANDARD20_MODULE_STUFF, - NULL, /* create per-dir config structures */ - NULL, /* merge per-dir config structures */ - limitipconn_create_config, /* create per-server config structures */ - limitipconn_merge_config, /* merge per-server config structures */ - limitipconn_cmds, /* table of config file commands */ - register_hooks -}; - diff --git a/network/mod_limitipconn/mod_limitipconn.info b/network/mod_limitipconn/mod_limitipconn.info index 1351784413..9ec443cece 100644 --- a/network/mod_limitipconn/mod_limitipconn.info +++ b/network/mod_limitipconn/mod_limitipconn.info @@ -1,8 +1,8 @@ PRGNAM="mod_limitipconn" -VERSION="0.22" +VERSION="0.23" HOMEPAGE="http://dominia.org/djao/limitipconn2.html" -DOWNLOAD="http://dominia.org/djao/limit/mod_limitipconn-0.22.tar.gz" -MD5SUM="0f4beb9eb4e7b815ca472ccfe11451b3" -MAINTAINER="Menno E. Duursma" +DOWNLOAD="http://dominia.org/djao/limit/mod_limitipconn-0.23.tar.bz2" +MD5SUM="08885977f8e0c50659a54c8e40ddd675" +MAINTAINER="Menno Duursma" EMAIL="druiloor@zonnet.nl" -APPROVED="Erik Hanson" +APPROVED="dsomero" diff --git a/network/mod_limitipconn/slack-desc b/network/mod_limitipconn/slack-desc index a2de81112c..9baa055e08 100644 --- a/network/mod_limitipconn/slack-desc +++ b/network/mod_limitipconn/slack-desc @@ -13,7 +13,7 @@ mod_limitipconn: number of simultaneous downloads permitted from a single mod_limitipconn: IP address. mod_limitipconn: mod_limitipconn: mod_limitipconn was written by David Jao -mod_limitipconn: The Apache 2.2 port by Niklas Edmundsson +mod_limitipconn: and Niklas Edmundsson mod_limitipconn: mod_limitipconn: mod_limitipconn: |