forked from extern/shorewall_code
Create better rules when a HELPER appears in an action
Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
parent
50dfffec94
commit
b5af6f03fb
@ -101,6 +101,7 @@ our %EXPORT_TAGS = (
|
||||
CHAIN
|
||||
SET
|
||||
AUDIT
|
||||
HELPER
|
||||
NO_RESTRICT
|
||||
PREROUTE_RESTRICT
|
||||
DESTIFACE_DISALLOW
|
||||
@ -352,6 +353,7 @@ use constant { STANDARD => 1, #defined by Netfilter
|
||||
CHAIN => 1024, #Manual Chain
|
||||
SET => 2048, #SET
|
||||
AUDIT => 4096, #A_ACCEPT, etc
|
||||
HELPER => 8192, #CT:helper
|
||||
};
|
||||
#
|
||||
# Valid Targets -- value is a combination of one or more of the above
|
||||
|
@ -33,7 +33,7 @@ use strict;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw( setup_conntrack );
|
||||
our @EXPORT_OK = qw( process_conntrack_rule );
|
||||
our @EXPORT_OK = qw( handle_helper_rule );
|
||||
our $VERSION = 'MODULEVERSION';
|
||||
|
||||
my %valid_ctevent = ( new => 1, related => 1, destroy => 1, reply => 1, assured => 1, protoinfo => 1, helper => 1, mark => 1, natseqinfo => 1, secmark => 1 );
|
||||
@ -41,21 +41,34 @@ my %valid_ctevent = ( new => 1, related => 1, destroy => 1, reply => 1, assured
|
||||
#
|
||||
# Notrack
|
||||
#
|
||||
sub process_conntrack_rule( $$$$$$$ ) {
|
||||
sub process_conntrack_rule( $$$$$$$$$ ) {
|
||||
|
||||
my ($action, $source, $dest, $proto, $ports, $sports, $user ) = @_;
|
||||
my ($chainref, $zoneref, $action, $source, $dest, $proto, $ports, $sports, $user ) = @_;
|
||||
|
||||
require_capability 'RAW_TABLE', 'conntrack rules', '';
|
||||
|
||||
$proto = '' if $proto eq 'any';
|
||||
$ports = '' if $ports eq 'any' || $ports eq 'all';
|
||||
$sports = '' if $sports eq 'any' || $sports eq 'all';
|
||||
|
||||
( my $zone, $source) = split /:/, $source, 2;
|
||||
my $zoneref = find_zone $zone;
|
||||
my $chainref = ensure_raw_chain( notrack_chain $zone );
|
||||
my $restriction = $zoneref->{type} == FIREWALL || $zoneref->{type} == VSERVER ? OUTPUT_RESTRICT : PREROUTE_RESTRICT;
|
||||
my $zone;
|
||||
my $restriction = PREROUTE_RESTRICT;
|
||||
|
||||
fatal_error 'USER/GROUP is not allowed unless the SOURCE zone is $FW or a Vserver zone' if $user ne '-' && $restriction != OUTPUT_RESTRICT;
|
||||
require_capability 'RAW_TABLE', 'conntrack rules', '';
|
||||
unless ( $chainref ) {
|
||||
#
|
||||
# Entry in the conntrack file
|
||||
#
|
||||
if ( $zoneref ) {
|
||||
$zone = $zoneref->{name};
|
||||
} else {
|
||||
($zone, $source) = split /:/, $source, 2;
|
||||
$zoneref = find_zone ( $zone );
|
||||
}
|
||||
|
||||
$chainref = ensure_raw_chain( notrack_chain $zone );
|
||||
$restriction = OUTPUT_RESTRICT if $zoneref->{type} == FIREWALL || $zoneref->{type} == VSERVER;
|
||||
fatal_error 'USER/GROUP is not allowed unless the SOURCE zone is $FW or a Vserver zone' if $user ne '-' && $restriction != OUTPUT_RESTRICT;
|
||||
}
|
||||
|
||||
my $target = $action;
|
||||
my $exception_rule = '';
|
||||
@ -125,6 +138,59 @@ sub process_conntrack_rule( $$$$$$$ ) {
|
||||
progress_message " Conntrack rule \"$currentline\" $done";
|
||||
}
|
||||
|
||||
sub handle_helper_rule( $$$$$$$$$$$ ) {
|
||||
my ( $helper, $source, $dest, $proto, $ports, $sports, $sourceref, $action_target, $actionchain, $user, $rule ) = @_;
|
||||
|
||||
if ( $helper ne '-' ) {
|
||||
fatal_error "A HELPER is not allowed with this ACTION" if $action_target;
|
||||
#
|
||||
# This means that an ACCEPT or NAT rule with a helper is being processed
|
||||
#
|
||||
process_conntrack_rule( $actionchain ? ensure_raw_chain( $actionchain ) : undef ,
|
||||
$sourceref ,
|
||||
"CT:helper:$helper",
|
||||
$source ,
|
||||
$dest ,
|
||||
$proto ,
|
||||
$ports ,
|
||||
$sports ,
|
||||
$user );
|
||||
} else {
|
||||
assert( $action_target );
|
||||
#
|
||||
# The target is an action
|
||||
#
|
||||
if ( $actionchain ) {
|
||||
#
|
||||
# And the source is another action chain
|
||||
#
|
||||
expand_rule( ensure_raw_chain( $actionchain ) ,
|
||||
PREROUTE_RESTRICT ,
|
||||
$rule ,
|
||||
$source ,
|
||||
$dest ,
|
||||
'' ,
|
||||
$action_target ,
|
||||
'',
|
||||
'CT' ,
|
||||
'' );
|
||||
} else {
|
||||
expand_rule( ensure_raw_chain( notrack_chain( $sourceref->{name} ) ) ,
|
||||
( $sourceref->{type} == FIREWALL || $sourceref->{type} == VSERVER ?
|
||||
OUTPUT_RESTRICT :
|
||||
PREROUTE_RESTRICT ) ,
|
||||
$rule ,
|
||||
$source ,
|
||||
$dest ,
|
||||
'' ,
|
||||
$action_target ,
|
||||
'' ,
|
||||
'CT' ,
|
||||
'' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub process_format( $ ) {
|
||||
my $format = shift;
|
||||
|
||||
@ -186,10 +252,10 @@ sub setup_conntrack() {
|
||||
|
||||
if ( $source eq 'all' ) {
|
||||
for my $zone (all_zones) {
|
||||
process_conntrack_rule( $action, $zone, $dest, $proto, $ports, $sports, $user );
|
||||
process_conntrack_rule( undef, undef, $action, $zone, $dest, $proto, $ports, $sports, $user );
|
||||
}
|
||||
} else {
|
||||
process_conntrack_rule( $action, $source, $dest, $proto, $ports, $sports, $user );
|
||||
process_conntrack_rule( undef, undef, $action, $source, $dest, $proto, $ports, $sports, $user );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ use Shorewall::Zones;
|
||||
use Shorewall::Chains qw(:DEFAULT :internal);
|
||||
use Shorewall::IPAddrs;
|
||||
use Shorewall::Nat qw(:rules);
|
||||
use Shorewall::Raw qw( process_conntrack_rule );
|
||||
use Shorewall::Raw qw( handle_helper_rule );
|
||||
use Scalar::Util 'reftype';
|
||||
|
||||
use strict;
|
||||
@ -1783,12 +1783,13 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
#
|
||||
process_action( $ref );
|
||||
#
|
||||
# Processing the action may determine that the action or one of it's dependents does NAT, so:
|
||||
# Processing the action may determine that the action or one of it's dependents does NAT or HELPER, so:
|
||||
#
|
||||
# - Refresh $actiontype
|
||||
# - Create the associate nat table chain if appropriate.
|
||||
# - Create the associated nat and/or table chain if appropriate.
|
||||
#
|
||||
ensure_chain( 'nat', $ref->{name} ) if ( $actiontype = $targets{$basictarget} ) & NATRULE;
|
||||
ensure_chain( 'raw', $ref->{name} ) if ( $actiontype & HELPER );
|
||||
}
|
||||
|
||||
$action = $basictarget; # Remove params, if any, from $action.
|
||||
@ -1803,6 +1804,10 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
$targets{$inaction} |= NATRULE if $inaction;
|
||||
fatal_error "NAT rules are only allowed in the NEW section" unless $section eq 'NEW';
|
||||
}
|
||||
|
||||
if ( $actiontype & HELPER ) {
|
||||
fatal_error "HELPER rules are only allowed in the NEW section" unless $section eq 'NEW';
|
||||
}
|
||||
#
|
||||
# Take care of irregular syntax and targets
|
||||
#
|
||||
@ -1814,7 +1819,13 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
$bt =~ s/[-+!]$//;
|
||||
|
||||
my %functions =
|
||||
( ACCEPT => sub() { $action = 'RETURN' if $blacklist; } ,
|
||||
( ACCEPT => sub() {
|
||||
if ( $blacklist ) {
|
||||
$action = 'RETURN';
|
||||
} elsif ( $helper ne '-' ) {
|
||||
$actiontype |= HELPER;
|
||||
}
|
||||
} ,
|
||||
|
||||
REDIRECT => sub () {
|
||||
my $z = $actiontype & NATONLY ? '' : firewall_zone;
|
||||
@ -1845,6 +1856,8 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
|
||||
if ( $function ) {
|
||||
$function->();
|
||||
} elsif ( $actiontype & NATRULE && $helper ne '-' ) {
|
||||
$actiontype |= HELPER;
|
||||
} elsif ( $actiontype & SET ) {
|
||||
my %xlate = ( ADD => 'add-set' , DEL => 'del-set' );
|
||||
|
||||
@ -2034,8 +2047,26 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
fatal_error "$basictarget rules are not allowed in the $section SECTION" if $actiontype & ( NATRULE | NONAT );
|
||||
$rule .= "$globals{STATEMATCH} $section " unless $section eq 'ALL' || $blacklist;
|
||||
}
|
||||
|
||||
#
|
||||
# Generate CT rules(s), if any
|
||||
#
|
||||
if ( $actiontype & HELPER ) {
|
||||
handle_helper_rule( $helper,
|
||||
$source,
|
||||
$origdest ? $origdest : $dest,
|
||||
$proto,
|
||||
$ports,
|
||||
$sports,
|
||||
$sourceref,
|
||||
( $actiontype & ACTION ) ? $usedactions{$normalized_target}->{name} : '',
|
||||
$inaction ? $chain : '' ,
|
||||
$user ,
|
||||
$rule ,
|
||||
);
|
||||
|
||||
$targets{$inaction} |= HELPER if $inaction;
|
||||
}
|
||||
|
||||
# Generate NAT rule(s), if any
|
||||
#
|
||||
if ( $actiontype & NATRULE ) {
|
||||
@ -2059,17 +2090,6 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
$log_action,
|
||||
);
|
||||
|
||||
unless ( $helper eq '-' ) {
|
||||
my $rulezone = $inaction ? 'all' : $sourcezone;
|
||||
|
||||
process_conntrack_rule( "CT:helper:$helper" ,
|
||||
"$rulezone:$source",
|
||||
$origdest,
|
||||
$proto,
|
||||
$ports,
|
||||
$sports,
|
||||
$user );
|
||||
}
|
||||
#
|
||||
# After NAT:
|
||||
# - the destination port will be the server port ($ports) -- we did that above
|
||||
@ -2141,17 +2161,6 @@ sub process_rule1 ( $$$$$$$$$$$$$$$$$$ ) {
|
||||
$loglevel ,
|
||||
$log_action ,
|
||||
'' );
|
||||
|
||||
if ( $action eq 'ACCEPT' && $helper ne '-' ) {
|
||||
my $rulezone = $inaction ? 'all' : $sourcezone;
|
||||
process_conntrack_rule( "CT:helper:$helper" ,
|
||||
"$rulezone:$source",
|
||||
$origdest ? $origdest : $dest,
|
||||
$proto,
|
||||
$ports,
|
||||
$sports,
|
||||
$user );
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -118,7 +118,8 @@ use constant { IN_OUT => 1,
|
||||
#
|
||||
# @zones contains the ordered list of zones with sub-zones appearing before their parents.
|
||||
#
|
||||
# %zones{<zone1> => {type => <zone type> FIREWALL, IP, IPSEC, BPORT;
|
||||
# %zones{<zone1> => {name => <name>,
|
||||
# type => <zone type> FIREWALL, IP, IPSEC, BPORT;
|
||||
# complex => 0|1
|
||||
# super => 0|1
|
||||
# options => { in_out => < policy match string >
|
||||
|
Loading…
Reference in New Issue
Block a user