From: Alexander Barton Date: Wed, 5 Nov 2003 21:41:01 +0000 (+0000) Subject: New configuration option "MaxConnectionsIP". X-Git-Tag: rel-0-8-0-pre1~74 X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=commitdiff_plain;h=2981fe9eb707b340107b5131018805ee2a469950 New configuration option "MaxConnectionsIP". --- diff --git a/ChangeLog b/ChangeLog index 904d609a..7e173e3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,10 @@ ngIRCd CVS-HEAD + - New configuration variable "MaxConnectionsIP" to limit the number of + simultaneous connections from a single IP that the server will accept. + This configuration options lowers the risk of denial of service attacks + (DoS), the default is 5 connections per client IP. - Fixed build problems under Mac OS X 10.3. - Use "-pipe" when compiling with gcc, speeds things up a little :-) - Added new configuration variable "Listen" to bind all listening @@ -468,4 +472,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: ChangeLog,v 1.213 2003/11/04 00:41:06 alex Exp $ +$Id: ChangeLog,v 1.214 2003/11/05 21:41:01 alex Exp $ diff --git a/NEWS b/NEWS index c55b2b4e..20f861c5 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,10 @@ ngIRCd CVS-HEAD + - New configuration variable "MaxConnectionsIP" to limit the number of + simultaneous connections from a single IP that the server will accept. + This configuration options lowers the risk of denial of service attacks + (DoS), the default is 5 connections per client IP. - Added new configuration variable "Listen" to bind all listening sockets of the server to a single IP address. @@ -170,4 +174,4 @@ ngIRCd 0.0.1, 31.12.2001 -- -$Id: NEWS,v 1.58 2003/09/11 12:05:28 alex Exp $ +$Id: NEWS,v 1.59 2003/11/05 21:41:01 alex Exp $ diff --git a/doc/sample-ngircd.conf b/doc/sample-ngircd.conf index 354b54ef..0e443930 100644 --- a/doc/sample-ngircd.conf +++ b/doc/sample-ngircd.conf @@ -1,4 +1,4 @@ -# $Id: sample-ngircd.conf,v 1.23 2003/09/11 12:05:28 alex Exp $ +# $Id: sample-ngircd.conf,v 1.24 2003/11/05 21:41:02 alex Exp $ # # This is a sample configuration file for the ngIRCd, which must adept to @@ -76,6 +76,10 @@ # Maximum number of simultaneous connection the server is allowed # to accept (<=0: unlimited): ;MaxConnections = -1 + + # Maximum number of simultaneous connections from a single IP address + # the server will accept (<=0: unlimited): + ;MaxConnectionsIP = 5 # Maximum number of channels a user can be member of (<=0: no limit): ;MaxJoins = 10 diff --git a/man/ngircd.conf.5 b/man/ngircd.conf.5 index 773287a7..d1cf47e2 100644 --- a/man/ngircd.conf.5 +++ b/man/ngircd.conf.5 @@ -1,5 +1,5 @@ .\" -.\" $Id: ngircd.conf.5,v 1.11 2003/09/11 12:05:28 alex Exp $ +.\" $Id: ngircd.conf.5,v 1.12 2003/11/05 21:41:02 alex Exp $ .\" .TH ngircd.conf 5 "Mai 2003" ngircd "ngIRCd Manual" .SH NAME @@ -118,6 +118,11 @@ not(!) channel-operators? Default: no. Maximum number of simultaneous connection the server is allowed to accept (<=0: unlimited). Default: -1. .TP +\fBMaxConnectionsIP\fR +Maximum number of simultaneous connections from a single IP address that +the server will accept (<=0: unlimited). This configuration options lowers +the risk of denial of service attacks (DoS). Default: 5. +.TP \fBMaxJoins\fR Maximum number of channels a user can be member of (<=0: no limit). Default: 10. diff --git a/src/ngircd/conf.c b/src/ngircd/conf.c index 0abb3c81..d17168c3 100644 --- a/src/ngircd/conf.c +++ b/src/ngircd/conf.c @@ -14,7 +14,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conf.c,v 1.60 2003/09/11 12:05:28 alex Exp $"; +static char UNUSED id[] = "$Id: conf.c,v 1.61 2003/11/05 21:41:02 alex Exp $"; #include "imp.h" #include @@ -133,6 +133,8 @@ Conf_Test( VOID ) printf( " OperCanUseMode = %s\n", Conf_OperCanMode == TRUE ? "yes" : "no" ); if( Conf_MaxConnections > 0 ) printf( " MaxConnections = %ld\n", Conf_MaxConnections ); else printf( " MaxConnections = -1\n" ); + if( Conf_MaxConnectionsIP > 0 ) printf( " MaxConnectionsIP = %d\n", Conf_MaxConnectionsIP ); + else printf( " MaxConnectionsIP = -1\n" ); if( Conf_MaxJoins > 0 ) printf( " MaxJoins = %d\n", Conf_MaxJoins ); else printf( " MaxJoins = -1\n" ); puts( "" ); @@ -356,6 +358,7 @@ Set_Defaults( BOOLEAN InitServers ) Conf_OperCanMode = FALSE; Conf_MaxConnections = -1; + Conf_MaxConnectionsIP = 5; Conf_MaxJoins = 10; /* Initialize server configuration structures */ @@ -691,6 +694,16 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg ) Conf_MaxConnections = atol( Arg ); return; } + if( strcasecmp( Var, "MaxConnectionsIP" ) == 0 ) + { + /* Maximum number of simoultanous connections from one IP. Values <= 0 are equal to "no limit". */ +#ifdef HAVE_ISDIGIT + if( ! isdigit( *Arg )) Config_Error( LOG_WARNING, "%s, line %d: Value of \"MaxConnectionsIP\" is not a number!", NGIRCd_ConfFile, Line ); + else +#endif + Conf_MaxConnectionsIP = atoi( Arg ); + return; + } if( strcasecmp( Var, "MaxJoins" ) == 0 ) { /* Maximum number of channels a user can join. Values <= 0 are equal to "no limit". */ @@ -707,8 +720,8 @@ Handle_GLOBAL( INT Line, CHAR *Var, CHAR *Arg ) if( strlcpy( Conf_ListenAddress, Arg, sizeof( Conf_ListenAddress )) >= sizeof( Conf_ListenAddress )) { Config_Error( LOG_WARNING, "%s, line %d: Value of \"Listen\" too long!", NGIRCd_ConfFile, Line ); - return; } + return; } Config_Error( LOG_ERR, "%s, line %d (section \"Global\"): Unknown variable \"%s\"!", NGIRCd_ConfFile, Line, Var ); diff --git a/src/ngircd/conf.h b/src/ngircd/conf.h index 15a7093d..b900610b 100644 --- a/src/ngircd/conf.h +++ b/src/ngircd/conf.h @@ -8,7 +8,7 @@ * (at your option) any later version. * Please read the file COPYING, README and AUTHORS for more information. * - * $Id: conf.h,v 1.27 2003/09/11 12:05:28 alex Exp $ + * $Id: conf.h,v 1.28 2003/11/05 21:41:02 alex Exp $ * * Configuration management (header) */ @@ -110,6 +110,9 @@ GLOBAL LONG Conf_MaxConnections; /* Maximum number of channels a user can join */ GLOBAL INT Conf_MaxJoins; +/* Maximum number of connections per IP address */ +GLOBAL INT Conf_MaxConnectionsIP; + GLOBAL VOID Conf_Init PARAMS((VOID )); GLOBAL VOID Conf_Rehash PARAMS((VOID )); diff --git a/src/ngircd/conn.c b/src/ngircd/conn.c index 56824594..2c65f26e 100644 --- a/src/ngircd/conn.c +++ b/src/ngircd/conn.c @@ -16,7 +16,7 @@ #include "portab.h" -static char UNUSED id[] = "$Id: conn.c,v 1.125 2003/09/11 12:05:28 alex Exp $"; +static char UNUSED id[] = "$Id: conn.c,v 1.126 2003/11/05 21:41:02 alex Exp $"; #include "imp.h" #include @@ -87,6 +87,7 @@ LOCAL BOOLEAN Init_Socket PARAMS(( INT Sock )); LOCAL VOID New_Server PARAMS(( INT Server, CONN_ID Idx )); LOCAL VOID Read_Resolver_Result PARAMS(( INT r_fd )); LOCAL VOID Simple_Message PARAMS(( INT Sock, CHAR *Msg )); +LOCAL INT Count_Connections PARAMS(( struct sockaddr_in addr )); LOCAL fd_set My_Listeners; LOCAL fd_set My_Sockets; @@ -904,7 +905,7 @@ New_Connection( INT Sock ) CONN_ID idx; CLIENT *c; POINTER *ptr; - LONG new_size; + LONG new_size, cnt; assert( Sock > NONE ); @@ -932,6 +933,17 @@ New_Connection( INT Sock ) /* Socket initialisieren */ Init_Socket( new_sock ); + + /* Check IP-based connection limit */ + cnt = Count_Connections( new_addr ); + if(( Conf_MaxConnectionsIP > 0 ) && ( cnt >= Conf_MaxConnectionsIP )) + { + /* Access denied, too many connections from this IP! */ + Log( LOG_ERR, "Refused connection from %s: too may connections (%ld) from this IP!", inet_ntoa( new_addr.sin_addr ), cnt); + Simple_Message( new_sock, "ERROR :Connection refused, too many connections from your IP!" ); + close( new_sock ); + return; + } /* Freie Connection-Struktur suchen */ for( idx = 0; idx < Pool_Size; idx++ ) if( My_Connections[idx].sock == NONE ) break; @@ -1599,4 +1611,18 @@ Simple_Message( INT Sock, CHAR *Msg ) } /* Simple_Error */ +LOCAL INT +Count_Connections( struct sockaddr_in addr_in ) +{ + INT i, cnt; + + cnt = 0; + for( i = 0; i < Pool_Size; i++ ) + { + if(( My_Connections[i].sock > NONE ) && ( My_Connections[i].addr.sin_addr.s_addr == addr_in.sin_addr.s_addr )) cnt++; + } + return cnt; +} /* Count_Connections */ + + /* -eof- */