From fc97f6d00e40775df10c8aa8f90fe78028634c42 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 24 May 2012 13:54:59 -0700 Subject: [PATCH] Implement LOG target option control. Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 34 +++++++++----- Shorewall/Perl/Shorewall/Config.pm | 49 +++++++++++++++++-- Shorewall/manpages/shorewall-rules.xml | 5 +- Shorewall6/manpages/shorewall6-rules.xml | 3 ++ docs/shorewall_logging.xml | 60 +++++++++++++++++++++++- 5 files changed, 134 insertions(+), 17 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index c7a682505..4b3a68d03 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -759,9 +759,9 @@ sub set_rule_option( $$$ ) { } } -sub transform_rule( $;$ ) { - my ( $input, $partial ) = @_; - my $ruleref = $partial ? {} : { mode => CAT_MODE, target => '' }; +sub transform_rule( $ ) { + my $input = $_[0]; + my $ruleref = { mode => CAT_MODE, target => '' }; my $simple = 1; $input =~ s/^\s*//; @@ -818,11 +818,7 @@ sub transform_rule( $;$ ) { set_rule_option( $ruleref, $option, $params ); } - if ( $partial ) { - delete $ruleref->{simple}; - } else { - $ruleref->{simple} = $simple unless $partial; - } + $ruleref->{simple} = $simple; $ruleref; } @@ -2534,7 +2530,7 @@ sub initialize_chain_table($) { new_standard_chain 'reject'; } - my $ruleref = transform_rule( $globals{LOGLIMIT}, 1 ); + my $ruleref = transform_rule( $globals{LOGLIMIT} ); $globals{iLOGLIMIT} = ( $ruleref->{hashlimit} ? [ hashlimit => $ruleref->{hashlimit} ] : @@ -5179,7 +5175,15 @@ sub log_rule_limit( $$$$$$$$ ) { } elsif ( $level =~ /^NFLOG/ ) { $prefix = "-j $level "; } else { - $prefix = "-j LOG $globals{LOGPARMS}--log-level $level "; + my $flags = $globals{LOGPARMS}; + + if ( $level =~ /^(.+)\((.*)\)$/ ) { + $level = $1; + $flags = join( ' ', $flags, $2 ) . ' '; + $flags =~ s/,/ /g; + } + + $prefix = "-j LOG ${flags}--log-level $level "; } } else { if ( $tag ) { @@ -5214,7 +5218,15 @@ sub log_rule_limit( $$$$$$$$ ) { $prefix = join( '', substr( $prefix, 0, 12 ) , ':' ) if length $prefix > 13; $prefix = "-j $level --log-prefix \"$prefix\" "; } else { - $prefix = "-j LOG $globals{LOGPARMS}--log-level $level --log-prefix \"$prefix\" "; + my $options = $globals{LOGPARMS}; + + if ( $level =~ /^(.+)\((.*)\)$/ ) { + $level = $1; + $options = join( ' ', $options, $2 ) . ' '; + $options =~ s/,/ /g; + } + + $prefix = "-j LOG ${options}--log-level $level --log-prefix \"$prefix\" "; } } diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index b0bf81323..5ae163381 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -2455,6 +2455,22 @@ sub level_error( $ ) { fatal_error "Invalid log level ($_[0])"; } +my %logoptions = ( tcp_sequence => '--log-tcp-sequence', + ip_options => '--log-ip-options', + tcp_options => '--log-tcp-options', + uid => '--log-uid', + macdecode => '--log-macdecode', + # + # Because a level can pass through validate_level() more than once, + # the full option names are also included here. + # + '--log-tcp-sequence' => '--log-tcp-sequence', + '--log-ip-options' => '--log-ip-options', + '--log-tcp-options' => '--log-tcp-options', + '--log-uid' => '--log-uid', + '--log-macdecode' => '--log-macdecode', + ); + sub validate_level( $ ) { my $rawlevel = $_[0]; my $level = uc $rawlevel; @@ -2465,17 +2481,44 @@ sub validate_level( $ ) { my $qualifier; unless ( $value =~ /^[0-7]$/ ) { - level_error( $level ) unless $level =~ /^([A-Za-z0-7]+)(.*)$/ && defined( $value = $validlevels{$1} ); - $qualifier = $2; + } if ( $value =~ /^([0-7])(.*)$/ ) { + $value = $1; + $qualifier = $2; + } elsif ( $value =~ /^([A-Za-z0-7]+)(.*)$/ ) { + level_error( $level) unless defined( $value = $validlevels{$1} ); + $qualifier = $2; } if ( $value =~ /^[0-7]$/ ) { # # Syslog Level # - level_error( $rawlevel ) if supplied $qualifier; + if ( supplied $qualifier ) { + my $options = ''; + my %options; + + level_error ( $rawlevel ) unless $qualifier =~ /^\((.*)\)$/; + + for ( split_list lc $1, "log options" ) { + my $option = $logoptions{$_}; + fatal_error "Unknown LOG option ($_)" unless $option; + + unless ( $options{$option} ) { + if ( $options ) { + $options = join( ',', $options, $option ); + } else { + $options = $option; + } + + $options{$option} = 1; + } + } + + $value .= "($options)" if $options; + } require_capability ( 'LOG_TARGET' , "Log level $level", 's' ); + return $value; } diff --git a/Shorewall/manpages/shorewall-rules.xml b/Shorewall/manpages/shorewall-rules.xml index cb64c9594..76732f735 100644 --- a/Shorewall/manpages/shorewall-rules.xml +++ b/Shorewall/manpages/shorewall-rules.xml @@ -1588,7 +1588,10 @@ url="http://www.shorewall.net/ipsets.html">http://www.shorewall.net/ipsets.html http://shorewall.net/configuration_file_basics.htm#Pairs + url="http://shorewall.net/configuration_file_basics.htm#Pairs">http://www.shorewall.net/configuration_file_basics.htm#Pairs + + http://www.shorewall.net/shorewall_logging.html shorewall(8), shorewall-accounting(5), shorewall-actions(5), shorewall-blacklist(5), shorweall-blrules(5), shorewall-hosts(5), diff --git a/Shorewall6/manpages/shorewall6-rules.xml b/Shorewall6/manpages/shorewall6-rules.xml index 60f4b1bcc..f3656afb2 100644 --- a/Shorewall6/manpages/shorewall6-rules.xml +++ b/Shorewall6/manpages/shorewall6-rules.xml @@ -1264,6 +1264,9 @@ See ALSO + http://www.shorewall.net/shorewall_logging.html + http://shorewall.net/configuration_file_basics.htm#Pairs diff --git a/docs/shorewall_logging.xml b/docs/shorewall_logging.xml index 615ef953e..ec81e1996 100644 --- a/docs/shorewall_logging.xml +++ b/docs/shorewall_logging.xml @@ -155,6 +155,61 @@ If you are unsure of the level to choose, 6 (info) is a safe bet. You may specify levels by name or by number. + Beginning with Shorewall 4.5.5, the + level name or number may be optionally + followed by a comma-separated list of one or more log + options. The list is enclosed in parentheses. Log options + cause additional information to be included in each log message. + + Valid log options are: + + + + ip_options + + + Log messages will include the option settings from the IP + header. + + + + + macdecode + + + Decode the MAC address and protocol. + + + + + tcp_sequence + + + Include TCP sequence numbers. + + + + + tcp_options + + + Include options from the TCP header. + + + + + uid + + + Include the UID of the sending program; only valid for + packets originating on the firewall itself. + + + + + Example: info(tcp_options,tcp_sequence) + Syslogd writes log messages to files (typically in /var/log/*) based on their facility and level. The mapping of these facility/level pairs to log files is done in @@ -278,10 +333,11 @@ ACCEPT:NFLOG(1,0,1) vpn fw tcp ssh,time,631,8080 Understanding the Contents of Shorewall Log Messages - + For general information on the contents of Netfilter log messages, see http://www.net.co.at/doc/howto/docs/iptables_netfilter_howto_de/docs/netfilter_log_format/index.html. + url="http://www.net.co.at/doc/howto/docs/iptables_netfilter_howto_de/docs/netfilter_log_format/index.html">http://www.net.co.at/doc/howto/docs/iptables_netfilter_howto_de/docs/netfilter_log_format/index.html. + For Shorewall-specific information, see FAQ #17.