forked from extern/shorewall_code
Add Nat Module
git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@5532 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
parent
721008f156
commit
b86c59f1a9
@ -26,7 +26,11 @@ our @EXPORT = qw(ALLIPv4
|
||||
|
||||
@allipv4
|
||||
@rfc1918_networks
|
||||
$line);
|
||||
$line
|
||||
$command
|
||||
$doing
|
||||
$done
|
||||
);
|
||||
our @EXPORT_OK = ();
|
||||
our @VERSION = 1.00;
|
||||
|
||||
@ -40,6 +44,9 @@ use constant { ALLIPv4 => '0.0.0.0/0' };
|
||||
our @rfc1918_networks = ( "10.0.0.0/24", "172.16.0.0/12", "192.168.0.0/16" );
|
||||
|
||||
our $line = ''; # Current config file line
|
||||
|
||||
our ( $command, $doing, $done ) = qw/ compile Compiling Compiled/; #describe the current command, it's present progressive, and it's completion.
|
||||
|
||||
my $object = 0; # Object file Handle Reference
|
||||
my $lastlineblank = 0; # Avoid extra blank lines in the output
|
||||
my $indent = '';
|
||||
|
325
New/Shorewall/Nat.pm
Normal file
325
New/Shorewall/Nat.pm
Normal file
@ -0,0 +1,325 @@
|
||||
package Shorewall::Nat;
|
||||
require Exporter;
|
||||
use Shorewall::Common;
|
||||
use Shorewall::Config;
|
||||
use Shorewall::Zones;
|
||||
use Shorewall::Chains;
|
||||
|
||||
use strict;
|
||||
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT = qw( setup_masq setup_nat );
|
||||
our @EXPORT_OK = ();
|
||||
our @VERSION = 1.00;
|
||||
|
||||
#
|
||||
# Handle IPSEC Options in a masq record
|
||||
#
|
||||
sub do_ipsec_options($)
|
||||
{
|
||||
my %validoptions = ( strict => NOTHING,
|
||||
next => NOTHING,
|
||||
reqid => NUMERIC,
|
||||
spi => NUMERIC,
|
||||
proto => IPSECPROTO,
|
||||
mode => IPSECMODE,
|
||||
"tunnel-src" => NETWORK,
|
||||
"tunnel-dst" => NETWORK,
|
||||
);
|
||||
my $list=$_[0];
|
||||
my $options = '-m policy';
|
||||
my $fmt;
|
||||
|
||||
for my $e ( split ',' , $list ) {
|
||||
my $val = undef;
|
||||
my $invert = '';
|
||||
|
||||
if ( $e =~ /([\w-]+)!=(.+)/ ) {
|
||||
$val = $2;
|
||||
$e = $1;
|
||||
$invert = '! ';
|
||||
} elsif ( $e =~ /([\w-]+)=(.+)/ ) {
|
||||
$val = $2;
|
||||
$e = $1;
|
||||
}
|
||||
|
||||
$fmt = $validoptions{$e};
|
||||
|
||||
fatal_error "Invalid Option ($e)" unless $fmt;
|
||||
|
||||
if ( $fmt eq NOTHING ) {
|
||||
fatal_error "Option $e does not take a value" if defined $val;
|
||||
} else {
|
||||
fatal_error "Invalid value ($val) for option \"$e\"" unless $val =~ /^($fmt)$/;
|
||||
}
|
||||
|
||||
$options .= $invert;
|
||||
$options .= "--$e";
|
||||
$options .= " $val" if defined $val;
|
||||
}
|
||||
|
||||
$options . ' ';
|
||||
}
|
||||
|
||||
#
|
||||
# Process a single rule from the the masq file
|
||||
#
|
||||
sub setup_one_masq($$$$$$)
|
||||
{
|
||||
my ($fullinterface, $networks, $addresses, $proto, $ports, $ipsec) = @_;
|
||||
|
||||
my $rule = '';
|
||||
my $pre_nat;
|
||||
my $add_snat_aliases = $config{ADD_SNAT_ALIASES};
|
||||
my $destnets = '';
|
||||
my $target = '-j MASQUERADE ';
|
||||
|
||||
#
|
||||
# Take care of missing ADDRESSES column
|
||||
#
|
||||
$addresses = '' unless defined $addresses;
|
||||
$addresses = '' if $addresses eq '-';
|
||||
|
||||
#
|
||||
# Handle IPSEC options, if any
|
||||
#
|
||||
if ( $ipsec && $ipsec ne '-' ) {
|
||||
fatal_error "Non-empty IPSEC column requires policy match support in your kernel and iptables" unless $env{ORIGINAL_POLICY_MATCH};
|
||||
|
||||
if ( $ipsec =~ /^yes$/i ) {
|
||||
$rule .= '-m policy --pol ipsec --dir out ';
|
||||
} elsif ( $ipsec =~ /^no$/i ) {
|
||||
$rule .= '-m policy --pol none --dir out ';
|
||||
} else {
|
||||
$rule .= do_ipsec_options $ipsec;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Leading '+'
|
||||
#
|
||||
if ( $fullinterface =~ /^\+/ ) {
|
||||
$pre_nat = 1;
|
||||
$fullinterface =~ s/\+//;
|
||||
}
|
||||
|
||||
#
|
||||
# Parse the remaining part of the INTERFACE column
|
||||
#
|
||||
if ( $fullinterface =~ /^([^:]+)::([^:]*)$/ ) {
|
||||
$add_snat_aliases = undef;
|
||||
$destnets = $2;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+:[^:]+):([^:]+)$/ ) {
|
||||
$destnets = $2;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+):$/ ) {
|
||||
$add_snat_aliases = undef;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+):([^:]*)$/ ) {
|
||||
my ( $one, $two ) = ( $1, $2 );
|
||||
if ( $2 =~ /\./ ) {
|
||||
$fullinterface = $one;
|
||||
$destnets = $two;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Isolate and verify the interface part
|
||||
#
|
||||
( my $interface = $fullinterface ) =~ s/:.*//;
|
||||
|
||||
fatal_error "Unknown interface $interface, rule \"$line\"" unless $interfaces{$interface}{root};
|
||||
|
||||
#
|
||||
# If there is no source or destination then allow all addresses
|
||||
#
|
||||
$networks = ALLIPv4 unless $networks;
|
||||
$destnets = ALLIPv4 unless $destnets;
|
||||
|
||||
#
|
||||
# Handle Protocol and Ports
|
||||
#
|
||||
$rule .= do_proto $proto, $ports, '';
|
||||
|
||||
#
|
||||
# Parse the ADDRESSES column
|
||||
#
|
||||
if ( $addresses ) {
|
||||
if ( $addresses =~ /^SAME:nodst:/ ) {
|
||||
$target = '-j SAME ';
|
||||
$addresses =~ s/.*://;
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
$target .= "--to $addr ";
|
||||
}
|
||||
} elsif ( $addresses =~ /^SAME:nodst:/ ) {
|
||||
$target = '-j SAME --nodst ';
|
||||
$addresses =~ s/.*://;
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
$target .= "--to $addr ";
|
||||
}
|
||||
} else {
|
||||
my $addrlist = '';
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
if ( $addr =~ /^.*\..*\..*\./ ) {
|
||||
$target = '-j SNAT ';
|
||||
$addrlist .= "--to-source $addr ";
|
||||
} else {
|
||||
$addr =~ s/^://;
|
||||
$addrlist .= "--to-ports $addr ";
|
||||
}
|
||||
}
|
||||
|
||||
$target .= $addrlist;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# And Generate the Rule(s)
|
||||
#
|
||||
expand_rule ensure_chain('nat', $pre_nat ? snat_chain $interface : masq_chain $interface), $rule, $networks, $destnets, '', $target, '', '' , '';
|
||||
|
||||
progress_message " Masq record \"$line\" $done";
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Process the masq file
|
||||
#
|
||||
sub setup_masq()
|
||||
{
|
||||
open MASQ, "$ENV{TMP_DIR}/masq" or fatal_error "Unable to open stripped zones file: $!";
|
||||
|
||||
while ( $line = <MASQ> ) {
|
||||
|
||||
chomp $line;
|
||||
$line =~ s/\s+/ /g;
|
||||
|
||||
my ($fullinterface, $networks, $addresses, $proto, $ports, $ipsec, $extra) = split /\s+/, $line;
|
||||
|
||||
if ( $fullinterface eq 'COMMENT' ) {
|
||||
if ( $capabilities{COMMENTS} ) {
|
||||
( $comment = $line ) =~ s/^\s*COMMENT\s*//;
|
||||
$comment =~ s/\s*$//;
|
||||
} else {
|
||||
warning_message "COMMENT ignored -- requires comment support in iptables/Netfilter";
|
||||
}
|
||||
} else {
|
||||
fatal_error "Invalid masq file entry: \"$line\"" if $extra;
|
||||
setup_one_masq $fullinterface, $networks, $addresses, $proto, $ports, $ipsec;
|
||||
}
|
||||
}
|
||||
|
||||
close MASQ;
|
||||
|
||||
$comment = '';
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Validate the ALL INTERFACES or LOCAL column in the NAT file
|
||||
#
|
||||
sub validate_nat_column( $$ ) {
|
||||
my $ref = $_[1];
|
||||
my $val = $$ref;
|
||||
|
||||
if ( defined $val ) {
|
||||
unless ( ( $val = "\L$val" ) eq 'yes' ) {
|
||||
if ( ( $val eq 'no' ) || ( $val eq '-' ) ) {
|
||||
$$ref = '';
|
||||
} else {
|
||||
fatal_error "Invalid value ($val) for $_[0] in NAT entry \"$line\"";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$$ref = '';
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Process a record from the NAT file
|
||||
#
|
||||
sub do_one_nat( $$$$$ )
|
||||
{
|
||||
my ( $external, $interface, $internal, $allints, $localnat ) = @_;
|
||||
|
||||
sub add_nat_rule( $$ ) {
|
||||
add_rule ensure_chain( 'nat', $_[0] ) , $_[1];
|
||||
}
|
||||
|
||||
my $add_ip_aliases = $config{ADD_IP_ALIASES};
|
||||
|
||||
my $policyin = '';
|
||||
my $policyout = '';
|
||||
|
||||
if ( $capabilities{POLICY_MATCH} ) {
|
||||
$policyin = ' -m policy --pol none --dir in';
|
||||
$policyout = '-m policy --pol none --dir out';
|
||||
}
|
||||
|
||||
fatal_error "Invalid nat file entry \"$line\""
|
||||
unless defined $interface and defined $internal;
|
||||
|
||||
if ( $add_ip_aliases ) {
|
||||
if ( $interface =~ s/:$// ) {
|
||||
$add_ip_aliases = '';
|
||||
} else {
|
||||
#
|
||||
# Fixme
|
||||
#
|
||||
}
|
||||
} else {
|
||||
$interface =~ s/:$//;
|
||||
}
|
||||
|
||||
validate_nat_column 'ALL INTERFACES', \$allints;
|
||||
validate_nat_column 'LOCAL' , \$localnat;
|
||||
|
||||
if ( $allints ) {
|
||||
add_nat_rule 'nat_in' , "-d $external $policyin -j DNAT --to-destination $internal";
|
||||
add_nat_rule 'nat_out' , "-s $internal $policyout -j SNAT --to-source $external";
|
||||
} else {
|
||||
add_nat_rule input_chain( $interface ) , "-d $external $policyin -j DNAT --to-destination $internal";
|
||||
add_nat_rule output_chain( $interface ) , "-s $internal $policyout -j SNAT --to-source $external";
|
||||
}
|
||||
|
||||
add_nat_rule 'OUTPUT' , "-d $external$policyout -j DNAT --to-destination $internal " if $localnat;
|
||||
|
||||
#
|
||||
# Fixme -- add_ip_aliases
|
||||
#
|
||||
progress_message " NAT entry \"$line\" $done";
|
||||
}
|
||||
|
||||
#
|
||||
# Process NAT file
|
||||
#
|
||||
sub setup_nat() {
|
||||
|
||||
open NAT, "$ENV{TMP_DIR}/nat" or fatal_error "Unable to open stripped nat file: $!";
|
||||
|
||||
while ( $line = <NAT> ) {
|
||||
|
||||
chomp $line;
|
||||
$line =~ s/\s+/ /g;
|
||||
|
||||
my ( $external, $interface, $internal, $allints, $localnat, $extra ) = split /\s+/, $line;
|
||||
|
||||
if ( $external eq 'COMMENT' ) {
|
||||
if ( $capabilities{COMMENTS} ) {
|
||||
( $comment = $line ) =~ s/^\s*COMMENT\s*//;
|
||||
$comment =~ s/\s*$//;
|
||||
} else {
|
||||
warning_message "COMMENT ignored -- requires comment support in iptables/Netfilter";
|
||||
}
|
||||
} else {
|
||||
fatal_error "Invalid nat file entry: \"$line\"" if $extra;
|
||||
do_one_nat $external, $interface, $internal, $allints, $localnat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close NAT;
|
||||
|
||||
$comment = '';
|
||||
}
|
317
New/compiler.pl
317
New/compiler.pl
@ -8,8 +8,7 @@ use Shorewall::Chains;
|
||||
use Shorewall::Zones;
|
||||
use Shorewall::Interfaces;
|
||||
use Shorewall::Hosts;
|
||||
|
||||
my ( $command, $doing, $done ) = qw/ compile Compiling Compiled/; #describe the current command, it's present progressive, and it's completion.
|
||||
use Shorewall::Nat;
|
||||
|
||||
#
|
||||
# Set to one if we find a SECTION
|
||||
@ -482,318 +481,6 @@ sub process_tos() {
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Handle IPSEC Options in a masq record
|
||||
#
|
||||
sub do_ipsec_options($)
|
||||
{
|
||||
my %validoptions = ( strict => NOTHING,
|
||||
next => NOTHING,
|
||||
reqid => NUMERIC,
|
||||
spi => NUMERIC,
|
||||
proto => IPSECPROTO,
|
||||
mode => IPSECMODE,
|
||||
"tunnel-src" => NETWORK,
|
||||
"tunnel-dst" => NETWORK,
|
||||
);
|
||||
my $list=$_[0];
|
||||
my $options = '-m policy';
|
||||
my $fmt;
|
||||
|
||||
for my $e ( split ',' , $list ) {
|
||||
my $val = undef;
|
||||
my $invert = '';
|
||||
|
||||
if ( $e =~ /([\w-]+)!=(.+)/ ) {
|
||||
$val = $2;
|
||||
$e = $1;
|
||||
$invert = '! ';
|
||||
} elsif ( $e =~ /([\w-]+)=(.+)/ ) {
|
||||
$val = $2;
|
||||
$e = $1;
|
||||
}
|
||||
|
||||
$fmt = $validoptions{$e};
|
||||
|
||||
fatal_error "Invalid Option ($e)" unless $fmt;
|
||||
|
||||
if ( $fmt eq NOTHING ) {
|
||||
fatal_error "Option $e does not take a value" if defined $val;
|
||||
} else {
|
||||
fatal_error "Invalid value ($val) for option \"$e\"" unless $val =~ /^($fmt)$/;
|
||||
}
|
||||
|
||||
$options .= $invert;
|
||||
$options .= "--$e";
|
||||
$options .= " $val" if defined $val;
|
||||
}
|
||||
|
||||
$options . ' ';
|
||||
}
|
||||
|
||||
#
|
||||
# Process a single rule from the the masq file
|
||||
#
|
||||
sub setup_one_masq($$$$$$)
|
||||
{
|
||||
my ($fullinterface, $networks, $addresses, $proto, $ports, $ipsec) = @_;
|
||||
|
||||
my $rule = '';
|
||||
my $pre_nat;
|
||||
my $add_snat_aliases = $config{ADD_SNAT_ALIASES};
|
||||
my $destnets = '';
|
||||
my $target = '-j MASQUERADE ';
|
||||
|
||||
#
|
||||
# Take care of missing ADDRESSES column
|
||||
#
|
||||
$addresses = '' unless defined $addresses;
|
||||
$addresses = '' if $addresses eq '-';
|
||||
|
||||
#
|
||||
# Handle IPSEC options, if any
|
||||
#
|
||||
if ( $ipsec && $ipsec ne '-' ) {
|
||||
fatal_error "Non-empty IPSEC column requires policy match support in your kernel and iptables" unless $env{ORIGINAL_POLICY_MATCH};
|
||||
|
||||
if ( $ipsec =~ /^yes$/i ) {
|
||||
$rule .= '-m policy --pol ipsec --dir out ';
|
||||
} elsif ( $ipsec =~ /^no$/i ) {
|
||||
$rule .= '-m policy --pol none --dir out ';
|
||||
} else {
|
||||
$rule .= do_ipsec_options $ipsec;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Leading '+'
|
||||
#
|
||||
if ( $fullinterface =~ /^\+/ ) {
|
||||
$pre_nat = 1;
|
||||
$fullinterface =~ s/\+//;
|
||||
}
|
||||
|
||||
#
|
||||
# Parse the remaining part of the INTERFACE column
|
||||
#
|
||||
if ( $fullinterface =~ /^([^:]+)::([^:]*)$/ ) {
|
||||
$add_snat_aliases = undef;
|
||||
$destnets = $2;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+:[^:]+):([^:]+)$/ ) {
|
||||
$destnets = $2;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+):$/ ) {
|
||||
$add_snat_aliases = undef;
|
||||
$fullinterface = $1;
|
||||
} elsif ( $fullinterface =~ /^([^:]+):([^:]*)$/ ) {
|
||||
my ( $one, $two ) = ( $1, $2 );
|
||||
if ( $2 =~ /\./ ) {
|
||||
$fullinterface = $one;
|
||||
$destnets = $two;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Isolate and verify the interface part
|
||||
#
|
||||
( my $interface = $fullinterface ) =~ s/:.*//;
|
||||
|
||||
fatal_error "Unknown interface $interface, rule \"$line\"" unless $interfaces{$interface}{root};
|
||||
|
||||
#
|
||||
# If there is no source or destination then allow all addresses
|
||||
#
|
||||
$networks = ALLIPv4 unless $networks;
|
||||
$destnets = ALLIPv4 unless $destnets;
|
||||
|
||||
#
|
||||
# Handle Protocol and Ports
|
||||
#
|
||||
$rule .= do_proto $proto, $ports, '';
|
||||
|
||||
#
|
||||
# Parse the ADDRESSES column
|
||||
#
|
||||
if ( $addresses ) {
|
||||
if ( $addresses =~ /^SAME:nodst:/ ) {
|
||||
$target = '-j SAME ';
|
||||
$addresses =~ s/.*://;
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
$target .= "--to $addr ";
|
||||
}
|
||||
} elsif ( $addresses =~ /^SAME:nodst:/ ) {
|
||||
$target = '-j SAME --nodst ';
|
||||
$addresses =~ s/.*://;
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
$target .= "--to $addr ";
|
||||
}
|
||||
} else {
|
||||
my $addrlist = '';
|
||||
for my $addr ( split /,/, $addresses ) {
|
||||
if ( $addr =~ /^.*\..*\..*\./ ) {
|
||||
$target = '-j SNAT ';
|
||||
$addrlist .= "--to-source $addr ";
|
||||
} else {
|
||||
$addr =~ s/^://;
|
||||
$addrlist .= "--to-ports $addr ";
|
||||
}
|
||||
}
|
||||
|
||||
$target .= $addrlist;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# And Generate the Rule(s)
|
||||
#
|
||||
expand_rule ensure_chain('nat', $pre_nat ? snat_chain $interface : masq_chain $interface), $rule, $networks, $destnets, '', $target, '', '' , '';
|
||||
|
||||
progress_message " Masq record \"$line\" $done";
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Process the masq file
|
||||
#
|
||||
sub setup_masq()
|
||||
{
|
||||
open MASQ, "$ENV{TMP_DIR}/masq" or fatal_error "Unable to open stripped zones file: $!";
|
||||
|
||||
while ( $line = <MASQ> ) {
|
||||
|
||||
chomp $line;
|
||||
$line =~ s/\s+/ /g;
|
||||
|
||||
my ($fullinterface, $networks, $addresses, $proto, $ports, $ipsec, $extra) = split /\s+/, $line;
|
||||
|
||||
if ( $fullinterface eq 'COMMENT' ) {
|
||||
if ( $capabilities{COMMENTS} ) {
|
||||
( $comment = $line ) =~ s/^\s*COMMENT\s*//;
|
||||
$comment =~ s/\s*$//;
|
||||
} else {
|
||||
warning_message "COMMENT ignored -- requires comment support in iptables/Netfilter";
|
||||
}
|
||||
} else {
|
||||
fatal_error "Invalid masq file entry: \"$line\"" if $extra;
|
||||
setup_one_masq $fullinterface, $networks, $addresses, $proto, $ports, $ipsec;
|
||||
}
|
||||
}
|
||||
|
||||
close MASQ;
|
||||
|
||||
$comment = '';
|
||||
|
||||
}
|
||||
|
||||
#
|
||||
# Validate the ALL INTERFACES or LOCAL column in the NAT file
|
||||
#
|
||||
sub validate_nat_column( $$ ) {
|
||||
my $ref = $_[1];
|
||||
my $val = $$ref;
|
||||
|
||||
if ( defined $val ) {
|
||||
unless ( ( $val = "\L$val" ) eq 'yes' ) {
|
||||
if ( ( $val eq 'no' ) || ( $val eq '-' ) ) {
|
||||
$$ref = '';
|
||||
} else {
|
||||
fatal_error "Invalid value ($val) for $_[0] in NAT entry \"$line\"";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$$ref = '';
|
||||
}
|
||||
}
|
||||
|
||||
sub add_nat_rule( $$ ) {
|
||||
add_rule ensure_chain( 'nat', $_[0] ) , $_[1];
|
||||
}
|
||||
|
||||
#
|
||||
# Process a record from the NAT file
|
||||
#
|
||||
sub do_one_nat( $$$$$ )
|
||||
{
|
||||
my ( $external, $interface, $internal, $allints, $localnat ) = @_;
|
||||
|
||||
my $add_ip_aliases = $config{ADD_IP_ALIASES};
|
||||
|
||||
my $policyin = '';
|
||||
my $policyout = '';
|
||||
|
||||
if ( $capabilities{POLICY_MATCH} ) {
|
||||
$policyin = ' -m policy --pol none --dir in';
|
||||
$policyout = '-m policy --pol none --dir out';
|
||||
}
|
||||
|
||||
fatal_error "Invalid nat file entry \"$line\""
|
||||
unless defined $interface and defined $internal;
|
||||
|
||||
if ( $add_ip_aliases ) {
|
||||
if ( $interface =~ s/:$// ) {
|
||||
$add_ip_aliases = '';
|
||||
} else {
|
||||
#
|
||||
# Fixme
|
||||
#
|
||||
}
|
||||
} else {
|
||||
$interface =~ s/:$//;
|
||||
}
|
||||
|
||||
validate_nat_column 'ALL INTERFACES', \$allints;
|
||||
validate_nat_column 'LOCAL' , \$localnat;
|
||||
|
||||
if ( $allints ) {
|
||||
add_nat_rule 'nat_in' , "-d $external $policyin -j DNAT --to-destination $internal";
|
||||
add_nat_rule 'nat_out' , "-s $internal $policyout -j SNAT --to-source $external";
|
||||
} else {
|
||||
add_nat_rule input_chain( $interface ) , "-d $external $policyin -j DNAT --to-destination $internal";
|
||||
add_nat_rule output_chain( $interface ) , "-s $internal $policyout -j SNAT --to-source $external";
|
||||
}
|
||||
|
||||
add_nat_rule 'OUTPUT' , "-d $external$policyout -j DNAT --to-destination $internal " if $localnat;
|
||||
|
||||
#
|
||||
# Fixme -- add_ip_aliases
|
||||
#
|
||||
progress_message " NAT entry \"$line\" $done";
|
||||
}
|
||||
|
||||
#
|
||||
# Process NAT file
|
||||
#
|
||||
sub setup_nat() {
|
||||
|
||||
open NAT, "$ENV{TMP_DIR}/nat" or fatal_error "Unable to open stripped nat file: $!";
|
||||
|
||||
while ( $line = <NAT> ) {
|
||||
|
||||
chomp $line;
|
||||
$line =~ s/\s+/ /g;
|
||||
|
||||
my ( $external, $interface, $internal, $allints, $localnat, $extra ) = split /\s+/, $line;
|
||||
|
||||
if ( $external eq 'COMMENT' ) {
|
||||
if ( $capabilities{COMMENTS} ) {
|
||||
( $comment = $line ) =~ s/^\s*COMMENT\s*//;
|
||||
$comment =~ s/\s*$//;
|
||||
} else {
|
||||
warning_message "COMMENT ignored -- requires comment support in iptables/Netfilter";
|
||||
}
|
||||
} else {
|
||||
fatal_error "Invalid nat file entry: \"$line\"" if $extra;
|
||||
do_one_nat $external, $interface, $internal, $allints, $localnat;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
close NAT;
|
||||
|
||||
$comment = '';
|
||||
}
|
||||
|
||||
sub add_rule_pair( $$$$ ) {
|
||||
my ($chainref , $predicate , $target , $level ) = @_;
|
||||
|
||||
@ -1418,7 +1105,7 @@ sub process_tcrules() {
|
||||
|
||||
}
|
||||
|
||||
close NAT;
|
||||
close TC;
|
||||
|
||||
$comment = '';
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user