diff --git a/modules/pike/doc/pike_admin.xml b/modules/pike/doc/pike_admin.xml index e992b91b6fd..6a9837eedf0 100644 --- a/modules/pike/doc/pike_admin.xml +++ b/modules/pike/doc/pike_admin.xml @@ -1,15 +1,15 @@ - + &adminguide; - +
Overview The module provides a simple mechanism for DOS protection - DOS based - on floods at network level. The module keeps trace of all (or selected - ones) IPs of incoming SIP traffic (as source IP) and blocks the ones + on floods at network level. The module keeps trace of all (or selected + ones) IPs of incoming SIP traffic (as source IP) and blocks the ones that exceeded some limit. Works simultaneous for IPv4 and IPv6 addresses. @@ -38,13 +38,13 @@ - automatic - the module will install + automatic - the module will install internal hooks to catch all incoming requests and replies (even if not well formed from SIP point of view) - more or less the module will monitor all incoming packages (from the network) on - the SIP sockets. Each time the source IP of a package needs to + the SIP sockets. Each time the source IP of a package needs to be analyse (to see if trusted or not), the module will run a - script route - see "check_route" module parameter -, where, + script route - see "check_route" module parameter -, where, based on custom logic, you can decide if that IP needs to be monitored for flooding or not. As action, when flood is detected, the module will automatically drop the packages. @@ -72,7 +72,7 @@
External Libraries or Applications - The following libraries or applications must be installed before + The following libraries or applications must be installed before running &osips; with this module loaded: @@ -89,14 +89,14 @@
<varname>sampling_time_unit</varname> (integer) - Time period used for sampling (or the sampling accuracy ;-) ). The - smaller the better, but slower. If you want to detect peaks, use a - small one. To limit the access (like total number of requests on a - long period of time) to a proxy resource (a gateway for ex), use + Time period used for sampling (or the sampling accuracy ;-) ). The + smaller the better, but slower. If you want to detect peaks, use a + small one. To limit the access (like total number of requests on a + long period of time) to a proxy resource (a gateway for ex), use a bigger value of this parameter. - IMPORTANT: a too small value may lead to performance penalties due + IMPORTANT: a too small value may lead to performance penalties due timer process overloading. @@ -116,9 +116,9 @@ modparam("pike", "sampling_time_unit", 10)
<varname>reqs_density_per_unit</varname> (integer) - How many requests should be allowed per sampling_time_unit before - blocking all the incoming request from that IP. Practically, the - blocking limit is between ( let's have x=reqs_density_per_unit) x + How many requests should be allowed per sampling_time_unit before + blocking all the incoming request from that IP. Practically, the + blocking limit is between ( let's have x=reqs_density_per_unit) x and 3*x for IPv4 addresses and between x and 8*x for ipv6 addresses. @@ -138,7 +138,7 @@ modparam("pike", "reqs_density_per_unit", 30)
<varname>remove_latency</varname> (integer) - For how long the IP address will be kept in memory after the last + For how long the IP address will be kept in memory after the last request from that IP address. It's a sort of timeout value. @@ -219,7 +219,7 @@ modparam("pike", "pike_log_level", -1) pike_check_req() - Process the source IP of the current request and returns false if + Process the source IP of the current request and returns false if the IP was exceeding the blocking limit. @@ -227,7 +227,7 @@ modparam("pike", "pike_log_level", -1) - 1 (true) - IP is not to be blocked or + 1 (true) - IP is not to be blocked or internal error occured. @@ -243,7 +243,7 @@ modparam("pike", "pike_log_level", -1) - -2 (false) - IP is detected as a new + -2 (false) - IP is detected as a new source of flooding - first time detection @@ -275,6 +275,30 @@ if (!pike_check_req()) { exit; }; Name: pike_list + Parameters: + + + IP - IP address currently blocked. + + + + MI FIFO Command Format: + + + :pike_list:_reply_fifo_file_ + _empty_line_ + +
+
+ + <function moreinfo="none">pike_rm</function> + + + Remove a node from the pike tree by IP address. + + + Name: pike_rm + Parameters: none MI FIFO Command Format: diff --git a/modules/pike/pike.c b/modules/pike/pike.c index 878c7182427..ff37df0ffd8 100644 --- a/modules/pike/pike.c +++ b/modules/pike/pike.c @@ -93,6 +93,8 @@ static param_export_t params[]={ static mi_export_t mi_cmds [] = { {MI_PIKE_LIST, "lists the nodes in the pike tree", mi_pike_list, MI_NO_INPUT_FLAG, 0, 0 }, + {MI_PIKE_RM, "remove a node from the tree", + mi_pike_rm, 0, 0, 0 }, {0,0,0,0,0,0} }; diff --git a/modules/pike/pike_mi.c b/modules/pike/pike_mi.c index 1f7bee7dafc..b56245eccca 100644 --- a/modules/pike/pike_mi.c +++ b/modules/pike/pike_mi.c @@ -24,6 +24,10 @@ * 2006-12-05 created (bogdan) */ +#include + +#include "../../resolve.h" + #include "ip_tree.h" #include "pike_mi.h" @@ -32,7 +36,8 @@ #define MAX_IP_LEN IPv6_LEN -static struct ip_node *ip_stack[MAX_IP_LEN]; +static struct ip_node *ip_stack[MAX_IP_LEN]; +extern int pike_log_level; static inline void print_ip_stack( int level, struct mi_node *node) @@ -86,6 +91,62 @@ static void print_red_ips( struct ip_node *ip, int level, struct mi_node *node) } +struct mi_root* mi_pike_rm(struct mi_root *cmd, void *param) +{ + struct mi_node *mn; + struct ip_node *node; + struct ip_node *kid; + struct ip_addr *ip; + int byte_pos; + + mn = cmd->node.kids; + if (mn==NULL) + return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); + + ip = str2ip(&mn->value); + if (ip==0) + return init_mi_tree( 500, "Bad IP", 6); + + node = 0; + byte_pos = 0; + + kid = get_tree_branch((unsigned char)ip->u.addr[byte_pos]); + + /* pilfered from ip_tree.c:mark_node(..) */ + while (kid && byte_pos < ip->len) { + while (kid && kid->byte!=(unsigned char)ip->u.addr[byte_pos]) { + kid = kid->next; + } + if (kid) { + node = kid; + kid = kid->kids; + byte_pos++; + } + } + + /* If all octets weren't matched, 404 */ + if (byte_pos!=ip->len) { + return init_mi_tree( 404, "Match not found", 15); + } + + /* If the node exists, check to see if it's really blocked */ + if (!(node->flags&NODE_ISRED_FLAG)) { + return init_mi_tree( 400, "IP not blocked", 14); + } + + /* reset the node block flag and counters */ + node->flags &= ~(NODE_ISRED_FLAG); + + node->hits[PREV_POS] = 0; + node->hits[CURR_POS] = 0; + node->leaf_hits[PREV_POS] = 0; + node->leaf_hits[CURR_POS] = 0; + + LM_GEN1(pike_log_level, + "PIKE - UNBLOCKing ip %s, node=%p\n",ip_addr2a(ip),node); + + return init_mi_tree( 200, MI_OK_S, MI_OK_LEN); +} /* diff --git a/modules/pike/pike_mi.h b/modules/pike/pike_mi.h index 56fe849d64a..e1f11faf9b2 100644 --- a/modules/pike/pike_mi.h +++ b/modules/pike/pike_mi.h @@ -31,8 +31,10 @@ #include "../../mi/mi.h" #define MI_PIKE_LIST "pike_list" +#define MI_PIKE_RM "pike_rm" struct mi_root* mi_pike_list(struct mi_root* cmd_tree, void* param); +struct mi_root* mi_pike_rm(struct mi_root *cmd, void *param); #endif