NAT in Actions

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2010-12-13 08:26:24 -08:00
parent e8b26236e2
commit c18154cedc

View File

@ -392,6 +392,8 @@ sub createlogactionchain( $$ ) {
} }
} }
} }
$chainref;
} }
sub createsimpleactionchain( $ ) { sub createsimpleactionchain( $ ) {
@ -418,6 +420,8 @@ sub createsimpleactionchain( $ ) {
} }
} }
} }
$chainref;
} }
# #
@ -518,7 +522,9 @@ sub process_action1 ( $$ ) {
my $targettype = $targets{$target}; my $targettype = $targets{$target};
if ( defined $targettype ) { if ( defined $targettype ) {
return if ( $targettype == STANDARD ) || ( $targettype & ( MACRO | LOGRULE | NFQ | CHAIN ) ); $targets{$action} |= ( $targettype & ( NATRULE | NATONLY | NONAT ) );
return if ( $targettype == STANDARD ) || ( $targettype & ( MACRO | LOGRULE | NFQ | CHAIN | NATRULE | NONAT ) );
fatal_error "Invalid TARGET ($target)" if $targettype & STANDARD; fatal_error "Invalid TARGET ($target)" if $targettype & STANDARD;
@ -659,6 +665,7 @@ sub process_action3( $$$$$ ) {
if ( $target eq 'FORMAT' ) { if ( $target eq 'FORMAT' ) {
my @columns = split_line 2, 2, 'action file'; my @columns = split_line 2, 2, 'action file';
fatal_error "FORMAT must be 1 or 2" unless $source =~ /^[12]$/; fatal_error "FORMAT must be 1 or 2" unless $source =~ /^[12]$/;
$format = $source;
next; next;
} }
@ -1055,7 +1062,8 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
if ( $actiontype & ACTION ) { if ( $actiontype & ACTION ) {
unless ( $usedactions{$target} ) { unless ( $usedactions{$target} ) {
$usedactions{$target} = 1; $usedactions{$target} = 1;
createactionchain $target; my $ref = createactionchain $target;
new_nat_chain $ref->{name} if $actiontype & ( NATRULE | NONAT );
} }
} }
# #
@ -1066,7 +1074,9 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
if ( $actiontype & REDIRECT ) { if ( $actiontype & REDIRECT ) {
my $z = $actiontype & NATONLY ? '' : firewall_zone; my $z = $actiontype & NATONLY ? '' : firewall_zone;
if ( $dest eq '-' ) { if ( $dest eq '-' ) {
$dest = join( '', $z, '::' , $ports =~ /[:,]/ ? '' : $ports ); $dest = $inaction ? '' : join( '', $z, '::' , $ports =~ /[:,]/ ? '' : $ports );
} elsif ( $inaction ) {
$dest = ":$dest";
} else { } else {
$dest = join( '', $z, '::', $dest ) unless $dest =~ /^[^\d].*:/; $dest = join( '', $z, '::', $dest ) unless $dest =~ /^[^\d].*:/;
} }
@ -1300,6 +1310,8 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
if ( $origdest eq '' || $origdest eq '-' ) { if ( $origdest eq '' || $origdest eq '-' ) {
$origdest = ALLIP; $origdest = ALLIP;
} elsif ( $origdest eq 'detect' ) { } elsif ( $origdest eq 'detect' ) {
fatal_error 'ORIGINAL DEST "detect" is invalid in an action' if $inaction;
if ( $config{DETECT_DNAT_IPADDRS} && $sourcezone ne firewall_zone ) { if ( $config{DETECT_DNAT_IPADDRS} && $sourcezone ne firewall_zone ) {
my $interfacesref = $sourceref->{interfaces}; my $interfacesref = $sourceref->{interfaces};
my @interfaces = keys %$interfacesref; my @interfaces = keys %$interfacesref;
@ -1308,15 +1320,19 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
$origdest = ALLIP; $origdest = ALLIP;
} }
} }
} elsif ( $actiontype & ACTION ) {
$target = $action;
} else { } else {
if ( $server eq '' ) { if ( $server eq '' ) {
fatal_error "A server and/or port must be specified in the DEST column in $action rules" unless $serverport; fatal_error "A server and/or port must be specified in the DEST column in $action rules" unless $serverport;
} elsif ( $server =~ /^(.+)-(.+)$/ ) { } elsif ( $server =~ /^(.+)-(.+)$/ ) {
validate_range( $1, $2 ); validate_range( $1, $2 );
} else { } else {
unless ( ( $actiontype & ACTION ) && $server eq ALLIP ) {
my @servers = validate_address $server, 1; my @servers = validate_address $server, 1;
$server = join ',', @servers; $server = join ',', @servers;
} }
}
if ( $action eq 'DNAT' ) { if ( $action eq 'DNAT' ) {
$target = 'DNAT'; $target = 'DNAT';
@ -1331,7 +1347,7 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
} }
unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) { unless ( $origdest && $origdest ne '-' && $origdest ne 'detect' ) {
if ( $config{DETECT_DNAT_IPADDRS} && $sourcezone ne firewall_zone ) { if ( ! $inaction && $config{DETECT_DNAT_IPADDRS} && $sourcezone ne firewall_zone ) {
my $interfacesref = $sourceref->{interfaces}; my $interfacesref = $sourceref->{interfaces};
my @interfaces = keys %$interfacesref; my @interfaces = keys %$interfacesref;
$origdest = @interfaces ? "detect:@interfaces" : ALLIP; $origdest = @interfaces ? "detect:@interfaces" : ALLIP;
@ -1346,7 +1362,7 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
# #
# And generate the nat table rule(s) # And generate the nat table rule(s)
# #
expand_rule ( ensure_chain ('nat' , $sourceref->{type} == FIREWALL ? 'OUTPUT' : dnat_chain $sourcezone ), expand_rule ( ensure_chain ('nat' , $inaction ? $chain : $sourceref->{type} == FIREWALL ? 'OUTPUT' : dnat_chain $sourcezone ),
PREROUTE_RESTRICT , PREROUTE_RESTRICT ,
$rule , $rule ,
$source , $source ,
@ -1393,7 +1409,9 @@ sub process_rule_common ( $$$$$$$$$$$$$$$$ ) {
my $chn; my $chn;
if ( $sourceref->{type} == FIREWALL ) { if ( $inaction ) {
$nonat_chain = ensure_chain 'nat', $chain;
} elsif ( $sourceref->{type} == FIREWALL ) {
$nonat_chain = $nat_table->{OUTPUT}; $nonat_chain = $nat_table->{OUTPUT};
} else { } else {
$nonat_chain = ensure_chain 'nat', dnat_chain $sourcezone; $nonat_chain = ensure_chain 'nat', dnat_chain $sourcezone;