mirror of
https://gitlab.com/shorewall/code.git
synced 2025-06-21 10:18:58 +02:00
Order matches in rules.
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
6950cd2576
commit
0da38cc38e
@ -513,7 +513,7 @@ our $mode;
|
|||||||
#
|
#
|
||||||
# A reference to this rule is returned when we try to push a rule onto a 'complete' chain
|
# A reference to this rule is returned when we try to push a rule onto a 'complete' chain
|
||||||
#
|
#
|
||||||
our $dummyrule = { simple => 1, mode => CAT_MODE };
|
our $dummyrule = { simple => 1, matches => [], mode => CAT_MODE };
|
||||||
|
|
||||||
#
|
#
|
||||||
# Address Family
|
# Address Family
|
||||||
@ -619,6 +619,7 @@ our %opttype = ( rule => CONTROL,
|
|||||||
mode => CONTROL,
|
mode => CONTROL,
|
||||||
cmdlevel => CONTROL,
|
cmdlevel => CONTROL,
|
||||||
simple => CONTROL,
|
simple => CONTROL,
|
||||||
|
matches => CONTROL,
|
||||||
|
|
||||||
i => UNIQUE,
|
i => UNIQUE,
|
||||||
s => UNIQUE,
|
s => UNIQUE,
|
||||||
@ -634,6 +635,8 @@ our %opttype = ( rule => CONTROL,
|
|||||||
|
|
||||||
policy => MATCH,
|
policy => MATCH,
|
||||||
state => EXCLUSIVE,
|
state => EXCLUSIVE,
|
||||||
|
'conntrack --ctstate' =>
|
||||||
|
EXCLUSIVE,
|
||||||
|
|
||||||
conntrack => COMPLEX,
|
conntrack => COMPLEX,
|
||||||
|
|
||||||
@ -831,12 +834,13 @@ sub set_rule_option( $$$ ) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$ruleref->{$option} = $value;
|
$ruleref->{$option} = $value;
|
||||||
|
push @{$ruleref->{matches}}, $option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sub transform_rule( $;\$ ) {
|
sub transform_rule( $;\$ ) {
|
||||||
my ( $input, $completeref ) = @_;
|
my ( $input, $completeref ) = @_;
|
||||||
my $ruleref = { mode => CAT_MODE, target => '' };
|
my $ruleref = { mode => CAT_MODE, matches => [], target => '' };
|
||||||
my $simple = 1;
|
my $simple = 1;
|
||||||
my $target = '';
|
my $target = '';
|
||||||
my $jump = '';
|
my $jump = '';
|
||||||
@ -950,11 +954,17 @@ sub format_option( $$ ) {
|
|||||||
$rule;
|
$rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub debug() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
sub format_rule( $$;$ ) {
|
sub format_rule( $$;$ ) {
|
||||||
my ( $chainref, $ruleref, $suppresshdr ) = @_;
|
my ( $chainref, $ruleref, $suppresshdr ) = @_;
|
||||||
|
|
||||||
return $ruleref->{cmd} if exists $ruleref->{cmd};
|
return $ruleref->{cmd} if exists $ruleref->{cmd};
|
||||||
|
|
||||||
|
debug if $chainref->{name} eq 'drct-net';
|
||||||
|
|
||||||
my $rule = $suppresshdr ? '' : "-A $chainref->{name}";
|
my $rule = $suppresshdr ? '' : "-A $chainref->{name}";
|
||||||
|
|
||||||
for ( @unique_options ) {
|
for ( @unique_options ) {
|
||||||
@ -971,10 +981,19 @@ sub format_rule( $$;$ ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rule .= format_option( 'state', $ruleref->{state} ) if defined $ruleref->{state};
|
|
||||||
$rule .= format_option( 'policy', $ruleref->{policy} ) if defined $ruleref->{policy};
|
$rule .= format_option( 'policy', $ruleref->{policy} ) if defined $ruleref->{policy};
|
||||||
|
|
||||||
$rule .= format_option( $_, $ruleref->{$_} ) for sort ( grep ! $opttype{$_}, keys %{$ruleref} );
|
if ( defined ( my $state = $ruleref->{'conntrack --ctstate'} ) ) {
|
||||||
|
$rule .= format_option( 'conntrack --ctstate' , $state );
|
||||||
|
} elsif ( defined $ruleref->{state} ) {
|
||||||
|
$rule .= format_option( 'state', $ruleref->{state} );
|
||||||
|
}
|
||||||
|
|
||||||
|
my %done;
|
||||||
|
|
||||||
|
for ( grep ! $opttype{$_}, @{$ruleref->{matches}} ) {
|
||||||
|
$rule .= format_option( $_, $ruleref->{$_} ) unless $done{$_}++;
|
||||||
|
}
|
||||||
|
|
||||||
if ( $ruleref->{target} ) {
|
if ( $ruleref->{target} ) {
|
||||||
$rule .= join( ' ', " -$ruleref->{jump}", $ruleref->{target} );
|
$rule .= join( ' ', " -$ruleref->{jump}", $ruleref->{target} );
|
||||||
@ -1041,6 +1060,12 @@ sub merge_rules( $$$ ) {
|
|||||||
set_rule_option ( $toref, 'state', $fromref->{state} ) if $fromref->{state};
|
set_rule_option ( $toref, 'state', $fromref->{state} ) if $fromref->{state};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unless ( $toref->{'conntrack --ctstate'} ) {
|
||||||
|
set_rule_option( $toref,
|
||||||
|
'conntrack --ctstate',
|
||||||
|
$fromref->{'conntrack --ctstate'} ) if $fromref->{'conntrack --ctstate'};
|
||||||
|
}
|
||||||
|
|
||||||
set_rule_option( $toref, 'policy', $fromref->{policy} ) if exists $fromref->{policy};
|
set_rule_option( $toref, 'policy', $fromref->{policy} ) if exists $fromref->{policy};
|
||||||
|
|
||||||
unless ( $toref->{comment} ) {
|
unless ( $toref->{comment} ) {
|
||||||
@ -1302,6 +1327,7 @@ sub push_matches {
|
|||||||
} else {
|
} else {
|
||||||
$ruleref->{$option} = $value;
|
$ruleref->{$option} = $value;
|
||||||
$dont_optimize ||= $option =~ /^[piosd]$/ && $value =~ /^!/;
|
$dont_optimize ||= $option =~ /^[piosd]$/ && $value =~ /^!/;
|
||||||
|
push @{$ruleref->{matches}}, $option;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1313,7 +1339,7 @@ sub push_irule( $$$;@ ) {
|
|||||||
|
|
||||||
( $target, my $targetopts ) = split ' ', $target, 2;
|
( $target, my $targetopts ) = split ' ', $target, 2;
|
||||||
|
|
||||||
my $ruleref = {};
|
my $ruleref = { matches => [] };
|
||||||
|
|
||||||
$ruleref->{mode} = ( $ruleref->{cmdlevel} = $chainref->{cmdlevel} ) ? CMD_MODE : CAT_MODE;
|
$ruleref->{mode} = ( $ruleref->{cmdlevel} = $chainref->{cmdlevel} ) ? CMD_MODE : CAT_MODE;
|
||||||
|
|
||||||
@ -1476,8 +1502,13 @@ sub clone_rule( $ ) {
|
|||||||
my $newruleref = {};
|
my $newruleref = {};
|
||||||
|
|
||||||
while ( my ( $key, $value ) = each %$oldruleref ) {
|
while ( my ( $key, $value ) = each %$oldruleref ) {
|
||||||
|
if ( reftype $value ) {
|
||||||
|
my @array = @$value;
|
||||||
|
$newruleref->{$key} = \@array;
|
||||||
|
} else {
|
||||||
$newruleref->{$key} = $value;
|
$newruleref->{$key} = $value;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$newruleref;
|
$newruleref;
|
||||||
}
|
}
|
||||||
@ -3548,6 +3579,20 @@ sub combine_dports {
|
|||||||
$baseref->{'multiport'} = '--dports ' . join( ',' , @ports );
|
$baseref->{'multiport'} = '--dports ' . join( ',' , @ports );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my @matches = @{$baseref->{matches}};
|
||||||
|
|
||||||
|
$baseref->{matches} = [];
|
||||||
|
|
||||||
|
my $switched = 0;
|
||||||
|
|
||||||
|
for ( @matches ) {
|
||||||
|
if ( $_ eq 'dport' || $_ eq 'sport' ) {
|
||||||
|
push @{$baseref->{matches}}, 'multiport' unless $switched++;
|
||||||
|
} else {
|
||||||
|
push @{$baseref->{matches}}, $_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$baseref->{comment} = $comment if $comment;
|
$baseref->{comment} = $comment if $comment;
|
||||||
|
|
||||||
trace ( $chainref, 'R', $basenum, $baseref ) if $debug;
|
trace ( $chainref, 'R', $basenum, $baseref ) if $debug;
|
||||||
|
@ -1965,12 +1965,14 @@ sub handle_stickiness( $ ) {
|
|||||||
$rule2 = clone_rule( $_ );
|
$rule2 = clone_rule( $_ );
|
||||||
|
|
||||||
clear_rule_target( $rule2 );
|
clear_rule_target( $rule2 );
|
||||||
set_rule_option( $rule2, 'mark', "--mark 0/$mask -m recent --name $list --remove" );
|
set_rule_option( $rule2, 'mark', "--mark 0\/$mask" );
|
||||||
|
set_rule_option( $rule2, 'recent', "--name $list --remove" );
|
||||||
} else {
|
} else {
|
||||||
$rule1 = clone_rule( $_ );
|
$rule1 = clone_rule( $_ );
|
||||||
|
|
||||||
clear_rule_target( $rule1 );
|
clear_rule_target( $rule1 );
|
||||||
set_rule_option( $rule1, 'mark', "--mark $mark\/$mask -m recent --name $list --set" );
|
set_rule_option( $rule1, 'mark', "--mark $mark\/$mask" );
|
||||||
|
set_rule_option( $rule1, 'recent', "--name $list --set" );
|
||||||
|
|
||||||
$rule2 = '';
|
$rule2 = '';
|
||||||
}
|
}
|
||||||
@ -1990,32 +1992,22 @@ sub handle_stickiness( $ ) {
|
|||||||
|
|
||||||
for my $chainref ( $stickoref, $setstickoref ) {
|
for my $chainref ( $stickoref, $setstickoref ) {
|
||||||
if ( $chainref->{name} eq 'sticko' ) {
|
if ( $chainref->{name} eq 'sticko' ) {
|
||||||
$rule1 = {};
|
$rule1 = clone_rule $_;
|
||||||
|
|
||||||
while ( my ( $key, $value ) = each %$_ ) {
|
|
||||||
$rule1->{$key} = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_rule_target( $rule1, 'MARK', "--set-mark $mark" );
|
set_rule_target( $rule1, 'MARK', "--set-mark $mark" );
|
||||||
set_rule_option( $rule1, 'recent', " --name $list --rdest --update --seconds 300" );
|
set_rule_option( $rule1, 'recent', " --name $list --rdest --update --seconds 300" );
|
||||||
|
|
||||||
$rule2 = {};
|
$rule2 = clone_rule $_;
|
||||||
|
|
||||||
while ( my ( $key, $value ) = each %$_ ) {
|
|
||||||
$rule2->{$key} = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_rule_target( $rule2 );
|
clear_rule_target( $rule2 );
|
||||||
set_rule_option ( $rule2, 'mark', "--mark 0\/$mask -m recent --name $list --rdest --remove" );
|
set_rule_option ( $rule2, 'mark', "--mark 0\/$mask" );
|
||||||
|
set_rule_option ( $rule2, 'recent', "--name $list --rdest --remove" );
|
||||||
} else {
|
} else {
|
||||||
$rule1 = {};
|
$rule1 = clone_rule $_;
|
||||||
|
|
||||||
while ( my ( $key, $value ) = each %$_ ) {
|
|
||||||
$rule1->{$key} = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
clear_rule_target( $rule1 );
|
clear_rule_target( $rule1 );
|
||||||
set_rule_option ( $rule1, 'mark', "--mark $mark -m recent --name $list --rdest --set" );
|
set_rule_option ( $rule1, 'mark', "--mark $mark" );
|
||||||
|
set_rule_option ( $rule1, 'recent', "--name $list --rdest --set" );
|
||||||
|
|
||||||
$rule2 = '';
|
$rule2 = '';
|
||||||
}
|
}
|
||||||
|
@ -2082,6 +2082,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
my $normalized_action;
|
my $normalized_action;
|
||||||
my $blacklist = ( $section == BLACKLIST_SECTION );
|
my $blacklist = ( $section == BLACKLIST_SECTION );
|
||||||
my $matches = $rule;
|
my $matches = $rule;
|
||||||
|
my $raw_matches = '';
|
||||||
|
|
||||||
if ( $inchain = defined $chainref ) {
|
if ( $inchain = defined $chainref ) {
|
||||||
( $inaction, undef, undef, undef ) = split /:/, $normalized_action = $chainref->{action}, 4 if $chainref->{action};
|
( $inaction, undef, undef, undef ) = split /:/, $normalized_action = $chainref->{action}, 4 if $chainref->{action};
|
||||||
@ -2093,13 +2094,13 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
my $inline_matches = get_inline_matches;
|
my $inline_matches = get_inline_matches;
|
||||||
|
|
||||||
if ( $inline_matches =~ /^(.*\s+)-j\s+(.+)$/ ) {
|
if ( $inline_matches =~ /^(.*\s+)-j\s+(.+)$/ ) {
|
||||||
$matches .= $1;
|
$raw_matches .= $1;
|
||||||
$action = $2;
|
$action = $2;
|
||||||
my ( $target ) = split ' ', $action;
|
my ( $target ) = split ' ', $action;
|
||||||
fatal_error "Unknown jump target ($action)" unless $targets{$target};
|
fatal_error "Unknown jump target ($action)" unless $targets{$target};
|
||||||
fatal_error "INLINE may not have a parameter when '-j' is specified in the free-form area" if $param ne '';
|
fatal_error "INLINE may not have a parameter when '-j' is specified in the free-form area" if $param ne '';
|
||||||
} else {
|
} else {
|
||||||
$matches .= "$inline_matches ";
|
$raw_matches .= "$inline_matches ";
|
||||||
|
|
||||||
if ( $param eq '' ) {
|
if ( $param eq '' ) {
|
||||||
$action = $loglevel ? 'LOG' : '';
|
$action = $loglevel ? 'LOG' : '';
|
||||||
@ -2109,8 +2110,6 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
$param = '' unless defined $param;
|
$param = '' unless defined $param;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rule = $matches;
|
|
||||||
}
|
}
|
||||||
#
|
#
|
||||||
# Determine the validity of the action
|
# Determine the validity of the action
|
||||||
@ -2133,7 +2132,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
|
|
||||||
my $generated = process_macro( $basictarget,
|
my $generated = process_macro( $basictarget,
|
||||||
$chainref,
|
$chainref,
|
||||||
$rule,
|
$rule . $raw_matches,
|
||||||
$target,
|
$target,
|
||||||
$current_param,
|
$current_param,
|
||||||
$source,
|
$source,
|
||||||
@ -2477,7 +2476,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
|
|
||||||
my $generated = process_inline( $basictarget,
|
my $generated = process_inline( $basictarget,
|
||||||
$chainref,
|
$chainref,
|
||||||
$rule,
|
$rule . $raw_matches,
|
||||||
$loglevel,
|
$loglevel,
|
||||||
$target,
|
$target,
|
||||||
$current_param,
|
$current_param,
|
||||||
@ -2519,6 +2518,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
do_time( $time ) ,
|
do_time( $time ) ,
|
||||||
do_headers( $headers ) ,
|
do_headers( $headers ) ,
|
||||||
do_condition( $condition , $chain ) ,
|
do_condition( $condition , $chain ) ,
|
||||||
|
$raw_matches ,
|
||||||
);
|
);
|
||||||
} elsif ( $section & ( ESTABLISHED_SECTION | INVALID_SECTION | RELATED_SECTION | UNTRACKED_SECTION ) ) {
|
} elsif ( $section & ( ESTABLISHED_SECTION | INVALID_SECTION | RELATED_SECTION | UNTRACKED_SECTION ) ) {
|
||||||
$rule .= join( '',
|
$rule .= join( '',
|
||||||
@ -2531,6 +2531,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
do_headers( $headers ) ,
|
do_headers( $headers ) ,
|
||||||
do_condition( $condition , $chain ) ,
|
do_condition( $condition , $chain ) ,
|
||||||
do_helper( $helper ) ,
|
do_helper( $helper ) ,
|
||||||
|
$raw_matches ,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$rule .= join( '',
|
$rule .= join( '',
|
||||||
@ -2542,6 +2543,7 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
do_time( $time ) ,
|
do_time( $time ) ,
|
||||||
do_headers( $headers ) ,
|
do_headers( $headers ) ,
|
||||||
do_condition( $condition , $chain ) ,
|
do_condition( $condition , $chain ) ,
|
||||||
|
$raw_matches ,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2615,7 +2617,8 @@ sub process_rule ( $$$$$$$$$$$$$$$$$$$ ) {
|
|||||||
do_ratelimit( $ratelimit, 'ACCEPT' ),
|
do_ratelimit( $ratelimit, 'ACCEPT' ),
|
||||||
do_user $user,
|
do_user $user,
|
||||||
do_test( $mark , $globals{TC_MASK} ),
|
do_test( $mark , $globals{TC_MASK} ),
|
||||||
do_condition( $condition , $chain )
|
do_condition( $condition , $chain ),
|
||||||
|
$raw_matches,
|
||||||
);
|
);
|
||||||
$loglevel = '';
|
$loglevel = '';
|
||||||
$action = 'ACCEPT';
|
$action = 'ACCEPT';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user