From 82d6a00c9e6b4a181256b3050499f485653d39e4 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sat, 21 May 2011 09:25:58 -0700 Subject: [PATCH] Implement some extentions to AUDIT Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Config.pm | 10 ++- Shorewall/Perl/Shorewall/Misc.pm | 52 ++++++++++++---- Shorewall/Perl/Shorewall/Rules.pm | 97 ++++++++++++++++++++---------- 3 files changed, 115 insertions(+), 44 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 06ea8e348..e4f8502a9 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -3345,10 +3345,12 @@ sub get_configuration( $ ) { default 'BLACKLIST_DISPOSITION' , 'DROP'; - unless ( $config{BLACKLIST_DISPOSITION} =~ /^(?:A_)?DROP$/ || $config{BLACKLIST_DISPOSITION} =~ /^(?:A_)?REJECT/ ) { + unless ( ( $val = $config{BLACKLIST_DISPOSITION} ) =~ /^(?:A_)?DROP$/ || $config{BLACKLIST_DISPOSITION} =~ /^(?:A_)?REJECT/ ) { fatal_error q(BLACKLIST_DISPOSITION must be 'DROP', 'A_DROP', 'REJECT' or 'A_REJECT'); } + require_capability 'AUDIT_TARGET', "BLACKLIST_DISPOSITION=$val", 's' if $val =~ /^A_/; + default_log_level 'BLACKLIST_LOGLEVEL', ''; default_log_level 'MACLIST_LOG_LEVEL', ''; default_log_level 'TCP_FLAGS_LOG_LEVEL', ''; @@ -3371,6 +3373,8 @@ sub get_configuration( $ ) { } else { fatal_error "Invalid value ($config{MACLIST_DISPOSITION}) for MACLIST_DISPOSITION" } + + require_capability 'AUDIT_TARGET' , "MACLIST_DISPOSITION=$val", 's' if $val =~ /^A_/; } else { $config{MACLIST_DISPOSITION} = 'reject'; } @@ -3386,11 +3390,13 @@ sub get_configuration( $ ) { } if ( $val = $config{TCP_FLAGS_DISPOSITION} ) { - fatal_error "Invalid value ($config{TCP_FLAGS_DISPOSITION}) for TCP_FLAGS_DISPOSITION" unless $val =~ /^(?:A_)?(REJECT|ACCEPT|DROP)$/; + fatal_error "Invalid value ($config{TCP_FLAGS_DISPOSITION}) for TCP_FLAGS_DISPOSITION" unless $val =~ /^(?:(?:A_)?(?:REJECT|DROP)|ACCEPT)$/; } else { $config{TCP_FLAGS_DISPOSITION} = 'DROP'; } + require_capability 'AUDIT_TARGET' , "TCP_FLAGS_DISPOSITION=$val", 's' if $val =~ /^A_/; + default 'TC_ENABLED' , $family == F_IPV4 ? 'Internal' : 'no'; $val = "\L$config{TC_ENABLED}"; diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm index f8077e733..f007b604e 100644 --- a/Shorewall/Perl/Shorewall/Misc.pm +++ b/Shorewall/Perl/Shorewall/Misc.pm @@ -203,7 +203,9 @@ sub setup_blacklist() { my $chainref; my $chainref1; my ( $level, $disposition ) = @config{'BLACKLIST_LOGLEVEL', 'BLACKLIST_DISPOSITION' }; + my $audit = $disposition =~ s/^A_//; my $target = $disposition eq 'REJECT' ? 'reject' : $disposition; + my $auditref; # # We go ahead and generate the blacklist chains and jump to them, even if they turn out to be empty. That is necessary # for 'refresh' to work properly. @@ -212,11 +214,13 @@ sub setup_blacklist() { $chainref = dont_delete new_standard_chain 'blacklst' if @$zones; $chainref1 = dont_delete new_standard_chain 'blackout' if @$zones1; - if ( defined $level && $level ne '' ) { + if ( $audit || ( defined $level && $level ne '' ) ) { my $logchainref = new_standard_chain 'blacklog'; log_rule_limit( $level , $logchainref , 'blacklst' , $disposition , "$globals{LOGLIMIT}" , '', 'add', '' ); + add_rule( $logchainref, '-j AUDIT --type ' . lc $target ) if $audit; + add_jump $logchainref, $target, 1; $target = 'blacklog'; @@ -247,18 +251,37 @@ sub setup_blacklist() { $options = 'src' if $options eq '-'; - my ( $to, $from, $whitelist ) = ( 0, 0, 0 ); + my ( $to, $from, $whitelist, $auditone ) = ( 0, 0, 0, 0 ); my @options = split_list $options, 'option'; for ( @options ) { $whitelist++ if $_ eq 'whitelist'; + $auditone++ if $_ eq 'audit'; } warning_message "Duplicate 'whitelist' option ignored" if $whitelist > 1; my $tgt = $whitelist ? 'RETURN' : $target; + if ( $auditone ) { + fatal_error "'audit' not allowed in whitelist entries" if $whitelist; + + if ( $audit ) { + warning_message "Superfluous 'audit' option ignored"; + } else { + warning_message "Duplicate 'audit' option ignored" if $auditone > 1; + + unless ( $auditref ) { + $auditref = new_standard_chain 'blackaud'; + add_rule $auditref, '-j AUDIT --type ' . lc $target; + add_jump $auditref, $target, 1; + } + + $tgt = 'blackaud'; + } + } + for ( @options ) { if ( $_ =~ /^(?:src|from)$/ ) { if ( $from++ ) { @@ -301,7 +324,7 @@ sub setup_blacklist() { } } } else { - fatal_error "Invalid blacklist option($_)" unless $_ eq 'whitelist'; + fatal_error "Invalid blacklist option($_)" unless $_ eq 'whitelist' || $_ eq 'audit'; } } @@ -604,22 +627,28 @@ sub add_common_rules() { $list = find_hosts_by_option 'tcpflags'; if ( @$list ) { - my $disposition; + my $level = $config{TCP_FLAGS_LOG_LEVEL}; + my $disposition = $config{TCP_FLAGS_DISPOSITION}; + my $audit = $disposition =~ s/^A_//; progress_message2 "$doing TCP Flags filtering..."; $chainref = new_standard_chain 'tcpflags'; - if ( $config{TCP_FLAGS_LOG_LEVEL} ne '' ) { + if ( $audit || $level ) { my $logflagsref = new_standard_chain 'logflags'; - my $savelogparms = $globals{LOGPARMS}; + if ( $level ) { + my $savelogparms = $globals{LOGPARMS}; - $globals{LOGPARMS} = "$globals{LOGPARMS}--log-ip-options "; + $globals{LOGPARMS} = "$globals{LOGPARMS}--log-ip-options "; - log_rule $config{TCP_FLAGS_LOG_LEVEL} , $logflagsref , $config{TCP_FLAGS_DISPOSITION}, ''; + log_rule $level , $logflagsref , $config{TCP_FLAGS_DISPOSITION}, ''; - $globals{LOGPARMS} = $savelogparms; + $globals{LOGPARMS} = $savelogparms; + } + + add_rule( $logflagsref, '-j AUDIT --type ' . lc $disposition ) if $audit; if ( $config{TCP_FLAGS_DISPOSITION} eq 'REJECT' ) { add_rule $logflagsref , '-p 6 -j REJECT --reject-with tcp-reset'; @@ -628,8 +657,6 @@ sub add_common_rules() { } $disposition = 'logflags'; - } else { - $disposition = $config{TCP_FLAGS_DISPOSITION}; } add_jump $chainref , $disposition, 1, '-p tcp --tcp-flags ALL FIN,URG,PSH '; @@ -713,6 +740,7 @@ sub setup_mac_lists( $ ) { my $target = $globals{MACLIST_TARGET}; my $level = $config{MACLIST_LOG_LEVEL}; my $disposition = $config{MACLIST_DISPOSITION}; + my $audit = $disposition =~ /^A_/; my $ttl = $config{MACLIST_TTL}; progress_message2 "$doing MAC Filtration -- Phase $phase..."; @@ -790,11 +818,13 @@ sub setup_mac_lists( $ ) { my $source = match_source_net $address; log_rule_limit $level, $chainref , mac_chain( $interface) , $disposition, '', '', 'add' , "${mac}${source}" if defined $level && $level ne ''; + add_rule( $chainref , '-j AUDIT --type ' . lc $disposition ) if $audit && $disposition ne 'ACCEPT'; add_jump $chainref , $targetref->{target}, 0, "${mac}${source}"; } } else { log_rule_limit $level, $chainref , mac_chain( $interface) , $disposition, '', '', 'add' , $mac if defined $level && $level ne ''; + add_rule( $chainref , '-j AUDIT --type ' . lc $disposition ) if $audit && $disposition ne 'ACCEPT'; add_jump $chainref , $targetref->{target}, 0, "$mac"; } diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index b7050dce8..29060747c 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -1139,8 +1139,13 @@ sub map_old_actions( $ ) { # # The following small functions generate rules for the builtin actions of the same name # -sub dropBcast( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub dropBcast( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } if ( have_capability( 'ADDRTYPE' ) ) { if ( $level ne '' ) { @@ -1151,7 +1156,8 @@ sub dropBcast( $$$ ) { log_rule_limit $level, $chainref, 'dropBcast' , 'DROP', '', $tag, 'add', join( ' ', ' -d' , IPv6_MULTICAST , '-j DROP ' ); } } - + + add_rule $chainref, '-m addrtype --dst-type BROADCAST -j AUDIT --type drop' if $audit; add_rule $chainref, '-m addrtype --dst-type BROADCAST -j DROP'; } else { if ( $family == F_IPV4 ) { @@ -1170,14 +1176,21 @@ sub dropBcast( $$$ ) { } if ( $family == F_IPV4 ) { + add_rule $chainref, '-d 224.0.0.0/4 -j AUDIT --type drop' if $audit; add_rule $chainref, '-d 224.0.0.0/4 -j DROP'; } else { + add_rule $chainref, join( ' ', '-d', IPv6_MULTICAST, '-j AUDIT --type drop' ); add_rule $chainref, join( ' ', '-d', IPv6_MULTICAST, '-j DROP' ); } } -sub allowBcast( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub allowBcast( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } if ( $family == F_IPV4 && have_capability( 'ADDRTYPE' ) ) { if ( $level ne '' ) { @@ -1185,7 +1198,9 @@ sub allowBcast( $$$ ) { log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 '; } + add_rule $chainref, '-m addrtype --dst-type BROADCAST -j AUDIT --type accept' if $audit; add_rule $chainref, '-m addrtype --dst-type BROADCAST -j ACCEPT'; + add_rule $chainref, '-d 224.0.0.0/4 -j AUDIT --type accept' if $audit; add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; } else { if ( $family == F_IPV4 ) { @@ -1196,62 +1211,97 @@ sub allowBcast( $$$ ) { incr_cmd_level $chainref; log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d $address ' if $level ne ''; + add_rule $chainref, '-d $address -j AUDIT --type accept' if $audit; add_rule $chainref, '-d $address -j ACCEPT'; decr_cmd_level $chainref; add_commands $chainref, 'done'; if ( $family == F_IPV4 ) { log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d 224.0.0.0/4 ' if $level ne ''; + add_rule $chainref, '-d 224.0.0.0/4 -j AUDIT --type accept' if $audit; add_rule $chainref, '-d 224.0.0.0/4 -j ACCEPT'; } else { log_rule_limit $level, $chainref, 'allowBcast' , 'ACCEPT', '', $tag, 'add', ' -d ' . IPv6_MULTICAST . ' ' if $level ne ''; + add_rule $chainref, join ( ' ', '-d', IPv6_MULTICAST, '-j AUDIT --type accept' ) if $audit; add_rule $chainref, join ( ' ', '-d', IPv6_MULTICAST, '-j ACCEPT' ); } } } -sub dropNotSyn ( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub dropNotSyn ( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } log_rule_limit $level, $chainref, 'dropNotSyn' , 'DROP', '', $tag, 'add', '-p 6 ! --syn ' if $level ne ''; + add_rule $chainref , '-p 6 ! --syn -j AUDIT --type drop' if $audit; add_rule $chainref , '-p 6 ! --syn -j DROP'; } -sub rejNotSyn ( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub rejNotSyn ( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } log_rule_limit $level, $chainref, 'rejNotSyn' , 'REJECT', '', $tag, 'add', '-p 6 ! --syn ' if $level ne ''; + add_rule $chainref , '-p 6 ! --syn -j AUDIT --type reject' if $audit; add_rule $chainref , '-p 6 ! --syn -j REJECT --reject-with tcp-reset'; } -sub dropInvalid ( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub dropInvalid ( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } log_rule_limit $level, $chainref, 'dropInvalid' , 'DROP', '', $tag, 'add', "$globals{STATEMATCH} INVALID " if $level ne ''; + add_rule $chainref , "$globals{STATEMATCH} INVALID -j AUDIT --type drop" if $audit; add_rule $chainref , "$globals{STATEMATCH} INVALID -j DROP"; } -sub allowInvalid ( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub allowInvalid ( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } log_rule_limit $level, $chainref, 'allowInvalid' , 'ACCEPT', '', $tag, 'add', "$globals{STATEMATCH} INVALID " if $level ne ''; + add_rule $chainref , "$globals{STATEMATCH} INVALID -j AUDIT --type accept" if $audit; add_rule $chainref , "$globals{STATEMATCH} INVALID -j ACCEPT"; } -sub forwardUPnP ( $$$ ) { +sub forwardUPnP ( $$$$ ) { my $chainref = dont_optimize 'forwardUPnP'; + add_commands( $chainref , '[ -f ${VARDIR}/.forwardUPnP ] && cat ${VARDIR}/.forwardUPnP >&3' ); } -sub allowinUPnP ( $$$ ) { - my ($chainref, $level, $tag) = @_; +sub allowinUPnP ( $$$$ ) { + my ($chainref, $level, $tag, $audit) = @_; + + if ( defined $audit && $audit ne '' ) { + fatal_error "Invalid parameter ($audit)" unless $audit eq 'audit'; + require_capability 'AUDIT_TARGET', 'audit', 's'; + } if ( $level ne '' ) { log_rule_limit $level, $chainref, 'allowinUPnP' , 'ACCEPT', '', $tag, 'add', '-p 17 --dport 1900 '; log_rule_limit $level, $chainref, 'allowinUPnP' , 'ACCEPT', '', $tag, 'add', '-p 6 --dport 49152 '; } + add_rule $chainref, '-p 17 --dport 1900 -j AUDIT --type accept' if $audit; add_rule $chainref, '-p 17 --dport 1900 -j ACCEPT'; + add_rule $chainref, '-p 6 --dport 49152 -j AUDIT --type accept' if $audit; add_rule $chainref, '-p 6 --dport 49152 -j ACCEPT'; } @@ -1344,7 +1394,6 @@ my %builtinops = ( 'dropBcast' => \&dropBcast, # - Reads actions.std and actions (in that order) and for each entry: # o Adds the action to the target table # o Verifies that the corresponding action file exists -# o Creates action chains for config options that have audited settings. # sub process_actions() { @@ -1385,10 +1434,6 @@ sub process_actions() { my $ref; - for ( map normalize_action_name $_ , ( grep $auditactions{$_}, ( map $config{$_}, @auditoptions ) ) ) { - process_action( $ref ) if $ref = use_action($_); - } - } sub process_rule1 ( $$$$$$$$$$$$$$$$ ); @@ -1480,16 +1525,6 @@ sub use_policy_action( $ ) { process_action( $ref ) if $ref; } - - -# -# This function creates and populates the chains for config options with audited settings. -# -sub process_actions2 () { - my $ref; - -} - ################################################################################ # End of functions moved from the Actions module in 4.4.16 ################################################################################