From bd5facda3081c59d43c293f3ef0ebdabdae29ebd Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 25 Jul 2010 12:42:39 -0700 Subject: [PATCH] Implement per-IP log rate limiting --- Shorewall/Perl/Shorewall/Config.pm | 39 +++++++++++++++++++++++++++++- Shorewall/changelog.txt | 2 ++ Shorewall/releasenotes.txt | 18 +++++++++++++- manpages/shorewall-rules.xml | 4 ++- manpages/shorewall.conf.xml | 27 +++++++++++++++++++++ manpages6/shorewall6-rules.xml | 4 ++- manpages6/shorewall6.conf.xml | 27 +++++++++++++++++++++ 7 files changed, 117 insertions(+), 4 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index acab463fb..476993788 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -362,6 +362,7 @@ sub initialize( $ ) { LOGFILE => undef, LOGFORMAT => undef, LOGTAGONLY => undef, + LOGLIMIT => undef, LOGRATE => undef, LOGBURST => undef, LOGALLNEW => undef, @@ -509,6 +510,7 @@ sub initialize( $ ) { LOGFILE => undef, LOGFORMAT => undef, LOGTAGONLY => undef, + LOGLIMIT => undef, LOGRATE => undef, LOGBURST => undef, LOGALLNEW => undef, @@ -2847,7 +2849,42 @@ sub get_configuration( $ ) { $globals{STATEMATCH} = '-m conntrack --ctstate' if have_capability 'CONNTRACK_MATCH'; - if ( $config{LOGRATE} || $config{LOGBURST} ) { + if ( my $rate = $config{LOGLIMIT} ) { + require_capability 'HASHLIMIT_MATCH', 'Per-ip log rate limiting' , 's'; + + my $limit = "-m hashlimit "; + my $match = have_capability( 'OLD_HL_MATCH' ) ? 'hashlimit' : 'hashlimit-upto'; + my $units; + + if ( $rate =~ /^[sd]:(\d+(\/(sec|min|hour|day))?):(\d+)$/ ) { + $limit .= "--hashlimit $1 --hashlimit-burst $4 --hashlimit-name lograte --hashlimit-mode "; + $units = $3; + } elsif ( $rate =~ /^[sd]:(\d+(\/(sec|min|hour|day))?)$/ ) { + $limit .= "--$match $1 --hashlimit-name lograte --hashlimit-mode "; + $units = $3; + } else { + fatal_error "Invalid rate ($rate)"; + } + + $limit .= $rate =~ /^s:/ ? 'srcip ' : 'dstip '; + + if ( $units && $units ne 'sec' ) { + my $expire = 60000; # 1 minute in milliseconds + + if ( $units ne 'min' ) { + $expire *= 60; #At least an hour + $expire *= 24 if $units eq 'day'; + } + + $limit .= "--hashlimit-htable-expire $expire "; + } + + $globals{LOGLIMIT} = $limit; + + warning_message "LOGRATE Ignored when LOGLIMIT is specified" if $config{LOGRATE}; + warning_message "LOGBURST Ignored when LOGLIMIT is specified" if $config{LOGBURST}; + + } elsif ( $config{LOGRATE} || $config{LOGBURST} ) { if ( defined $config{LOGRATE} ) { fatal_error"Invalid LOGRATE ($config{LOGRATE})" unless $config{LOGRATE} =~ /^\d+\/(second|minute)$/; } diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt index 61a98abe8..5b6e9cc9b 100644 --- a/Shorewall/changelog.txt +++ b/Shorewall/changelog.txt @@ -8,6 +8,8 @@ Changes in Shorewall 4.4.12 4) Allow :random to work with REDIRECT +5) Add per-ip log rate limiting. + Changes in Shorewall 4.4.11 1) Apply patch from Gabriel. diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt index 7333b5d16..daefc0707 100644 --- a/Shorewall/releasenotes.txt +++ b/Shorewall/releasenotes.txt @@ -252,8 +252,24 @@ None. 1) Support has been added for ADD and DEL rules in /etc/shorewall/rules. ADD allows either the SOURCE or DESTINATION IP address to be added to an ipset; DEL deletes an address - previously added. + previously added. +2) Per-ip log rate limiting has been added in the form of the LOGLIMIT + option in shorewall.conf. When LOGLIMIT is specified, LOGRATE and + LOGBURST are ignored. + + LOGRATE and LOGBURST are now deprecated. + + LOGLIMIT value format is [sd:][/][:] + + If the value starts with 's:' then logging is limited per source + IP. If the value starts with 'd:', then logging is limited per + destination IP. Otherwise, the overall logging rate is limited. + + is one of sec, min, hour, day. + + If is not specified, then a value of 5 is assumed. + ---------------------------------------------------------------------------- V I. P R O B L E M S C O R R E C T E D A N D N E W F E A T U R E S I N P R I O R R E L E A S E S diff --git a/manpages/shorewall-rules.xml b/manpages/shorewall-rules.xml index 19cae2552..39f4e0cf0 100644 --- a/manpages/shorewall-rules.xml +++ b/manpages/shorewall-rules.xml @@ -898,7 +898,9 @@ role="bold">d}:[[name]:]]]rate/{sec|min}[:burst] + role="bold">min|hour|day}[:burst] You may rate-limit the rule by placing a value in this diff --git a/manpages/shorewall.conf.xml b/manpages/shorewall.conf.xml index b1ab237c6..5eacd4271 100644 --- a/manpages/shorewall.conf.xml +++ b/manpages/shorewall.conf.xml @@ -932,6 +932,30 @@ net all DROP infothen the chain name is 'net2all' + + LOGLIMIT=[[{s|d}:]rate/{sec|min|hour|day}[:burst]] + + + Added in Shorewall 4.4.12. Limits the logging rate, either + overall, or by source or destination IP address. + + If the value starts with 's:' then logging is limited per + source IP. If the value starts with 'd:', then logging is limited + per destination IP. Otherwise, the overall logging rate is limited. + + + If burst is not specified, then a + value of 5 is assumed. + + + LOGBURST=[burst] @@ -948,6 +972,9 @@ net all DROP infothen the chain name is 'net2all' role="bold">second}] + Deprecated in Shorewall 4.4.12. These options are ignored when + LOGLIMIT is specified. + These parameters set the match rate and initial burst size for logged packets. Please see iptables(8) for a description of the behavior of these parameters (the iptables option --limit is set by diff --git a/manpages6/shorewall6-rules.xml b/manpages6/shorewall6-rules.xml index d5b02368d..42ff2aa36 100644 --- a/manpages6/shorewall6-rules.xml +++ b/manpages6/shorewall6-rules.xml @@ -668,7 +668,9 @@ role="bold">d}:[[name]:]]]rate/{sec|min}[:burst] + role="bold">min|hour|day}[:burst] You may rate-limit the rule by placing a value in this diff --git a/manpages6/shorewall6.conf.xml b/manpages6/shorewall6.conf.xml index 96ebe6251..d0a5bcab0 100644 --- a/manpages6/shorewall6.conf.xml +++ b/manpages6/shorewall6.conf.xml @@ -809,6 +809,30 @@ net all DROP infothen the chain name is 'net2all' + + LOGLIMIT=[[{s|d}:]rate/{sec|min|hour|day}[:burst]] + + + Added in Shorewall 4.4.12. Limits the logging rate, either + overall, or by source or destination IP address. + + If the value starts with 's:' then logging is limited per + source IP. If the value starts with 'd:', then logging is limited + per destination IP. Otherwise, the overall logging rate is + limited. + + If burst is not specified, then a + value of 5 is assumed. + + + LOGBURST=[burst] @@ -825,6 +849,9 @@ net all DROP infothen the chain name is 'net2all' role="bold">second}] + As of Shorewall 4.4.12, these parameters are + deprecated. + These parameters set the match rate and initial burst size for logged packets. Please see ip6tables(8) for a description of the behavior of these parameters (the ip6tables option --limit is set by