Another set of IPv6 Changes -- two-product strategy

git-svn-id: https://shorewall.svn.sourceforge.net/svnroot/shorewall/trunk@8950 fbd18981-670d-0410-9b5c-8dc0c1a9a2bb
This commit is contained in:
teastep 2008-12-08 20:48:02 +00:00
parent 9eaa3979c0
commit 4812fb6d2d
6 changed files with 630 additions and 212 deletions

View File

@ -1,2 +1,2 @@
This is the Shorewall-perl stable 4.2 branch of SVN.
This is the Shorewall-perl development 4.2 branch of SVN.

View File

@ -34,7 +34,7 @@ use Shorewall::IPAddrs;
use strict;
our @ISA = qw(Exporter);
our @EXPORT = qw(
our @EXPORT = qw(
add_rule
add_jump
insert_rule
@ -68,6 +68,7 @@ our %EXPORT_TAGS = (
POSTROUTE_RESTRICT
ALL_RESTRICT
chain_family
add_command
add_commands
move_rules
@ -247,6 +248,8 @@ use constant { NULL_MODE => 0 , # Generating neither shell commands nor iptabl
our $mode;
our $family;
#
# Initialize globals -- we take this novel approach to globals initialization to allow
# the compiler to run multiple times in the same process. The
@ -256,7 +259,7 @@ our $mode;
# the second and subsequent calls to that function.
#
sub initialize() {
sub initialize( $ ) {
%chain_table = ( raw => {} ,
mangle => {},
nat => {},
@ -282,40 +285,6 @@ sub initialize() {
#
$comment = '';
#
# As new targets (Actions, Macros and Manual Chains) are discovered, they are added to the table
#
%targets = ('ACCEPT' => STANDARD,
'ACCEPT+' => STANDARD + NONAT,
'ACCEPT!' => STANDARD,
'NONAT' => STANDARD + NONAT + NATONLY,
'DROP' => STANDARD,
'DROP!' => STANDARD,
'REJECT' => STANDARD,
'REJECT!' => STANDARD,
'DNAT' => NATRULE,
'DNAT-' => NATRULE + NATONLY,
'REDIRECT' => NATRULE + REDIRECT,
'REDIRECT-' => NATRULE + REDIRECT + NATONLY,
'LOG' => STANDARD + LOGRULE,
'CONTINUE' => STANDARD,
'CONTINUE!' => STANDARD,
'QUEUE' => STANDARD,
'QUEUE!' => STANDARD,
'NFQUEUE' => STANDARD + NFQ,
'NFQUEUE!' => STANDARD + NFQ,
'SAME' => NATRULE,
'SAME-' => NATRULE + NATONLY,
'dropBcast' => BUILTIN + ACTION,
'allowBcast' => BUILTIN + ACTION,
'dropNotSyn' => BUILTIN + ACTION,
'rejNotSyn' => BUILTIN + ACTION,
'dropInvalid' => BUILTIN + ACTION,
'allowInvalid' => BUILTIN + ACTION,
'allowinUPnP' => BUILTIN + ACTION,
'forwardUPnP' => BUILTIN + ACTION,
'Limit' => BUILTIN + ACTION,
);
#
# Used to sequence 'exclusion' chains with names 'excl0', 'excl1', ...
#
$exclseq = 0;
@ -336,10 +305,12 @@ sub initialize() {
%interfacemacs = ();
%interfacebcasts = ();
%interfacegateways = ();
$family = shift;
}
INIT {
initialize;
initialize( F_IPV4 );
}
#
@ -915,29 +886,108 @@ sub ensure_manual_chain($) {
#
sub initialize_chain_table()
{
for my $chain qw(OUTPUT PREROUTING) {
new_builtin_chain 'raw', $chain, 'ACCEPT';
}
if ( $family == F_IPV4 ) {
#
# As new targets (Actions, Macros and Manual Chains) are discovered, they are added to the table
#
%targets = ('ACCEPT' => STANDARD,
'ACCEPT+' => STANDARD + NONAT,
'ACCEPT!' => STANDARD,
'NONAT' => STANDARD + NONAT + NATONLY,
'DROP' => STANDARD,
'DROP!' => STANDARD,
'REJECT' => STANDARD,
'REJECT!' => STANDARD,
'DNAT' => NATRULE,
'DNAT-' => NATRULE + NATONLY,
'REDIRECT' => NATRULE + REDIRECT,
'REDIRECT-' => NATRULE + REDIRECT + NATONLY,
'LOG' => STANDARD + LOGRULE,
'CONTINUE' => STANDARD,
'CONTINUE!' => STANDARD,
'QUEUE' => STANDARD,
'QUEUE!' => STANDARD,
'NFQUEUE' => STANDARD + NFQ,
'NFQUEUE!' => STANDARD + NFQ,
'SAME' => NATRULE,
'SAME-' => NATRULE + NATONLY,
'dropBcast' => BUILTIN + ACTION,
'allowBcast' => BUILTIN + ACTION,
'dropNotSyn' => BUILTIN + ACTION,
'rejNotSyn' => BUILTIN + ACTION,
'dropInvalid' => BUILTIN + ACTION,
'allowInvalid' => BUILTIN + ACTION,
'allowinUPnP' => BUILTIN + ACTION,
'forwardUPnP' => BUILTIN + ACTION,
'Limit' => BUILTIN + ACTION,
);
for my $chain qw(INPUT OUTPUT FORWARD) {
new_builtin_chain 'filter', $chain, 'DROP';
}
for my $chain qw(OUTPUT PREROUTING) {
new_builtin_chain 'raw', $chain, 'ACCEPT';
}
for my $chain qw(PREROUTING POSTROUTING OUTPUT) {
new_builtin_chain 'nat', $chain, 'ACCEPT';
}
for my $chain qw(INPUT OUTPUT FORWARD) {
new_builtin_chain 'filter', $chain, 'DROP';
}
for my $chain qw(PREROUTING POSTROUTING OUTPUT) {
new_builtin_chain 'nat', $chain, 'ACCEPT';
}
for my $chain qw(PREROUTING INPUT OUTPUT ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT';
}
for my $chain qw(PREROUTING INPUT OUTPUT ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT';
}
if ( $capabilities{MANGLE_FORWARD} ) {
for my $chain qw( FORWARD POSTROUTING ) {
if ( $capabilities{MANGLE_FORWARD} ) {
for my $chain qw( FORWARD POSTROUTING ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT';
}
}
} else {
#
# As new targets (Actions, Macros and Manual Chains) are discovered, they are added to the table
#
%targets = ('ACCEPT' => STANDARD,
'ACCEPT!' => STANDARD,
'DROP' => STANDARD,
'DROP!' => STANDARD,
'REJECT' => STANDARD,
'REJECT!' => STANDARD,
'LOG' => STANDARD + LOGRULE,
'CONTINUE' => STANDARD,
'CONTINUE!' => STANDARD,
'QUEUE' => STANDARD,
'QUEUE!' => STANDARD,
'NFQUEUE' => STANDARD + NFQ,
'NFQUEUE!' => STANDARD + NFQ,
'dropBcast' => BUILTIN + ACTION,
'allowBcast' => BUILTIN + ACTION,
'dropNotSyn' => BUILTIN + ACTION,
'rejNotSyn' => BUILTIN + ACTION,
'dropInvalid' => BUILTIN + ACTION,
'allowInvalid' => BUILTIN + ACTION,
'allowinUPnP' => BUILTIN + ACTION,
'forwardUPnP' => BUILTIN + ACTION,
'Limit' => BUILTIN + ACTION,
);
for my $chain qw(OUTPUT PREROUTING) {
new_builtin_chain 'raw', $chain, 'ACCEPT';
}
for my $chain qw(INPUT OUTPUT FORWARD) {
new_builtin_chain 'filter', $chain, 'DROP';
}
for my $chain qw(PREROUTING POSTROUTING OUTPUT) {
new_builtin_chain 'nat', $chain, 'ACCEPT';
}
for my $chain qw(PREROUTING INPUT OUTPUT FORWARD POSTROUTING ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT';
}
}
}
#
# Add ESTABLISHED,RELATED rules and synparam jumps to the passed chain
#
@ -1914,7 +1964,16 @@ sub expand_rule( $$$$$$$$$$$ )
if ( $source ) {
if ( $source eq '-' ) {
$source = '';
} elsif ( $source =~ /^([^:]+):([^:]+)$/ ) {
} elsif ( $family == F_IPV4 ) {
if ( $source =~ /^([^:]+):([^:]+)$/ ) {
$iiface = $1;
$inets = $2;
} elsif ( $source =~ /\+|~|\..*\./ ) {
$inets = $source;
} else {
$iiface = $source;
}
} elsif ( $source =~ /^([^;]+);([^;]+)$/ ) {
$iiface = $1;
$inets = $2;
} elsif ( $source =~ /\+|~|\..*\./ ) {
@ -1986,7 +2045,16 @@ sub expand_rule( $$$$$$$$$$$ )
}
$dest = '';
} elsif ( $dest =~ /^([^:]+):([^:]+)$/ ) {
} elsif ( $family == F_IPV4 ) {
if ( $dest =~ /^([^:]+):([^:]+)$/ ) {
$diface = $1;
$dnets = $2;
} elsif ( $dest =~ /\+|~|\..*\./ ) {
$dnets = $dest;
} else {
$diface = $dest;
}
} elsif ( $dest =~ /^([^;]+);([^;]+)$/ ) {
$diface = $1;
$dnets = $2;
} elsif ( $dest =~ /\+|~|\..*\./ ) {
@ -2363,10 +2431,14 @@ sub create_netfilter_load() {
my @table_list;
push @table_list, 'raw' if $capabilities{RAW_TABLE};
push @table_list, 'nat' if $capabilities{NAT_ENABLED};
push @table_list, 'mangle' if $capabilities{MANGLE_ENABLED} && $config{MANGLE_ENABLED};
push @table_list, 'filter';
if ( $family == F_IPV4 ) {
push @table_list, 'raw' if $capabilities{RAW_TABLE};
push @table_list, 'nat' if $capabilities{NAT_ENABLED};
push @table_list, 'mangle' if $capabilities{MANGLE_ENABLED} && $config{MANGLE_ENABLED};
push @table_list, 'filter';
} else {
@table_list = qw( raw mangle filter );
}
$mode = NULL_MODE;
@ -2376,11 +2448,13 @@ sub create_netfilter_load() {
push_indent;
save_progress_message "Preparing iptables-restore input...";
my $utility = $family == F_IPV4 ? 'iptables-restore' : 'ip6tables-restore';
save_progress_message "Preparing $utility input...";
emit '';
emit 'exec 3>${VARDIR}/.iptables-restore-input';
emit "exec 3>\${VARDIR}/.${utility}-input";
enter_cat_mode;
@ -2425,7 +2499,7 @@ sub create_netfilter_load() {
enter_cmd_mode;
#
# Now generate the actual iptables-restore command
# Now generate the actual ip[6]tables-restore command
#
emit( 'exec 3>&-',
'',
@ -2433,9 +2507,9 @@ sub create_netfilter_load() {
'',
'progress_message2 "Running $command..."',
'',
'cat ${VARDIR}/.iptables-restore-input | $command # Use this nonsensical form to appease SELinux',
"cat \${VARDIR}/.${utility}-input | \$command # Use this nonsensical form to appease SELinux",
'if [ $? != 0 ]; then',
' fatal_error "iptables-restore Failed. Input is in ${VARDIR}/.iptables-restore-input"',
qq( fatal_error "iptables-restore Failed. Input is in \${VARDIR}/.${utility}-input"),
"fi\n"
);

View File

@ -37,6 +37,7 @@ use Shorewall::Accounting;
use Shorewall::Rules;
use Shorewall::Proc;
use Shorewall::Proxyarp;
use Shorewall::IPAddrs;
our @ISA = qw(Exporter);
our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG );
@ -49,6 +50,8 @@ our $test;
our $reused = 0;
our $family = F_IPV4;
use constant { EXPORT => 0x01 ,
TIMESTAMP => 0x02 ,
DEBUG => 0x04 };
@ -57,8 +60,8 @@ use constant { EXPORT => 0x01 ,
# Reinitilize the package-globals in the other modules
#
sub reinitialize() {
Shorewall::Config::initialize;
Shorewall::Chains::initialize;
Shorewall::Config::initialize($family);
Shorewall::Chains::initialize ($family);
Shorewall::Zones::initialize;
Shorewall::Policy::initialize;
Shorewall::Nat::initialize;
@ -733,8 +736,14 @@ sub compiler {
defined($val) && ($val >= MIN_VERBOSITY) && ($val <= MAX_VERBOSITY);
}
sub edit_family( $ ) {
my $val = numeric_value( shift );
defined($val) && ($val == F_IPV4 || $val == F_IPV6);
}
my %parms = ( object => { store => \$objectfile },
directory => { store => \$directory },
family => { store => \$family , edit => \&edit_family } ,
verbosity => { store => \$verbosity , edit => \&edit_verbosity } ,
timestamp => { store => \$timestamp, edit => \&edit_boolean } ,
debug => { store => \$debug, edit => \&edit_boolean } ,
@ -755,7 +764,7 @@ sub compiler {
${$ref->{store}} = $val;
}
reinitialize if $reused++;
reinitialize if ++$reused || $family == F_IPV6;
if ( $directory ne '' ) {
fatal_error "$directory is not an existing directory" unless -d $directory;

View File

@ -100,6 +100,8 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_object
run_user_exit2
generate_aux_config
$product
$Product
$command
$doing
$done
@ -108,6 +110,9 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_object
%globals
%capabilities
F_IPV4
F_IPV6
MIN_VERBOSITY
MAX_VERBOSITY
) ] );
@ -240,8 +245,17 @@ our $shorewall_dir; # Shorewall Directory
our $debug; # If true, use Carp to report errors with stack trace.
our $family;
our $toolname;
our $toolNAME;
our $product;
our $Product;
use constant { MIN_VERBOSITY => -1,
MAX_VERBOSITY => 2 };
MAX_VERBOSITY => 2 ,
F_IPV4 => 1,
F_IPV6 => 2,
};
#
# Initialize globals -- we take this novel approach to globals initialization to allow
@ -251,7 +265,15 @@ use constant { MIN_VERBOSITY => -1,
# also called by Shorewall::Compiler::compiler at the beginning of
# the second and subsequent calls to that function.
#
sub initialize() {
sub initialize( $ ) {
$family = shift;
if ( $family == F_IPV4 ) {
( $product, $Product, $toolname, $toolNAME ) = qw( shorewall Shorewall iptables IPTABLES );
} else {
( $product, $Product, $toolname, $toolNAME ) = qw( shorewall6 Shorewall6 ip6tables IP6TABLES );
}
( $command, $doing, $done ) = qw/ compile Compiling Compiled/; #describe the current command, it's present progressive, and it's completion.
$verbose = 0; # Verbosity setting. 0 = almost silent, 1 = major progress messages only, 2 = all progress messages (very noisy)
@ -274,115 +296,203 @@ sub initialize() {
LOGPARMS => '',
TC_SCRIPT => '',
EXPORT => 0,
VERSION => "4.2.3",
VERSION => "4.3.0",
CAPVERSION => 40203 ,
);
#
# From shorewall.conf file
#
%config =
( STARTUP_ENABLED => undef,
VERBOSITY => undef,
#
# Logging
#
LOGFILE => undef,
LOGFORMAT => undef,
LOGTAGONLY => undef,
LOGRATE => undef,
LOGBURST => undef,
LOGALLNEW => undef,
BLACKLIST_LOGLEVEL => undef,
MACLIST_LOG_LEVEL => undef,
TCP_FLAGS_LOG_LEVEL => undef,
RFC1918_LOG_LEVEL => undef,
SMURF_LOG_LEVEL => undef,
LOG_MARTIANS => undef,
LOG_VERBOSITY => undef,
STARTUP_LOG => undef,
#
# Location of Files
#
IPTABLES => undef,
#
#PATH is inherited
#
PATH => undef,
SHOREWALL_SHELL => undef,
SUBSYSLOCK => undef,
MODULESDIR => undef,
#
#CONFIG_PATH is inherited
#
CONFIG_PATH => undef,
RESTOREFILE => undef,
IPSECFILE => undef,
LOCKFILE => undef,
#
# Default Actions/Macros
#
DROP_DEFAULT => undef,
REJECT_DEFAULT => undef,
ACCEPT_DEFAULT => undef,
QUEUE_DEFAULT => undef,
NFQUEUE_DEFAULT => undef,
#
# RSH/RCP Commands
#
RSH_COMMAND => undef,
RCP_COMMAND => undef,
#
# Firewall Options
#
BRIDGING => undef,
IP_FORWARDING => undef,
ADD_IP_ALIASES => undef,
ADD_SNAT_ALIASES => undef,
RETAIN_ALIASES => undef,
TC_ENABLED => undef,
TC_EXPERT => undef,
CLEAR_TC => undef,
MARK_IN_FORWARD_CHAIN => undef,
CLAMPMSS => undef,
ROUTE_FILTER => undef,
DETECT_DNAT_IPADDRS => undef,
MUTEX_TIMEOUT => undef,
ADMINISABSENTMINDED => undef,
BLACKLISTNEWONLY => undef,
DELAYBLACKLISTLOAD => undef,
MODULE_SUFFIX => undef,
DISABLE_IPV6 => undef,
DYNAMIC_ZONES => undef,
PKTTYPE=> undef,
RFC1918_STRICT => undef,
MACLIST_TABLE => undef,
MACLIST_TTL => undef,
SAVE_IPSETS => undef,
MAPOLDACTIONS => undef,
FASTACCEPT => undef,
IMPLICIT_CONTINUE => undef,
HIGH_ROUTE_MARKS => undef,
USE_ACTIONS=> undef,
OPTIMIZE => undef,
EXPORTPARAMS => undef,
SHOREWALL_COMPILER => undef,
EXPAND_POLICIES => undef,
KEEP_RT_TABLES => undef,
DELETE_THEN_ADD => undef,
MULTICAST => undef,
DONT_LOAD => '',
AUTO_COMMENT => undef ,
MANGLE_ENABLED => undef ,
NULL_ROUTE_RFC1918 => undef ,
USE_DEFAULT_RT => undef ,
#
# Packet Disposition
#
MACLIST_DISPOSITION => undef,
TCP_FLAGS_DISPOSITION => undef,
BLACKLIST_DISPOSITION => undef,
);
if ( $family == F_IPV4 ) {
%config =
( STARTUP_ENABLED => undef,
VERBOSITY => undef,
#
# Logging
#
LOGFILE => undef,
LOGFORMAT => undef,
LOGTAGONLY => undef,
LOGRATE => undef,
LOGBURST => undef,
LOGALLNEW => undef,
BLACKLIST_LOGLEVEL => undef,
MACLIST_LOG_LEVEL => undef,
TCP_FLAGS_LOG_LEVEL => undef,
RFC1918_LOG_LEVEL => undef,
SMURF_LOG_LEVEL => undef,
LOG_MARTIANS => undef,
LOG_VERBOSITY => undef,
STARTUP_LOG => undef,
#
# Location of Files
#
IPTABLES => undef,
#
#PATH is inherited
#
PATH => undef,
SHOREWALL_SHELL => undef,
SUBSYSLOCK => undef,
MODULESDIR => undef,
#
#CONFIG_PATH is inherited
#
CONFIG_PATH => undef,
RESTOREFILE => undef,
IPSECFILE => undef,
LOCKFILE => undef,
#
# Default Actions/Macros
#
DROP_DEFAULT => undef,
REJECT_DEFAULT => undef,
ACCEPT_DEFAULT => undef,
QUEUE_DEFAULT => undef,
NFQUEUE_DEFAULT => undef,
#
# RSH/RCP Commands
#
RSH_COMMAND => undef,
RCP_COMMAND => undef,
#
# Firewall Options
#
BRIDGING => undef,
IP_FORWARDING => undef,
ADD_IP_ALIASES => undef,
ADD_SNAT_ALIASES => undef,
RETAIN_ALIASES => undef,
TC_ENABLED => undef,
TC_EXPERT => undef,
CLEAR_TC => undef,
MARK_IN_FORWARD_CHAIN => undef,
CLAMPMSS => undef,
ROUTE_FILTER => undef,
DETECT_DNAT_IPADDRS => undef,
MUTEX_TIMEOUT => undef,
ADMINISABSENTMINDED => undef,
BLACKLISTNEWONLY => undef,
DELAYBLACKLISTLOAD => undef,
MODULE_SUFFIX => undef,
DISABLE_IPV6 => undef,
DYNAMIC_ZONES => undef,
PKTTYPE=> undef,
RFC1918_STRICT => undef,
MACLIST_TABLE => undef,
MACLIST_TTL => undef,
SAVE_IPSETS => undef,
MAPOLDACTIONS => undef,
FASTACCEPT => undef,
IMPLICIT_CONTINUE => undef,
HIGH_ROUTE_MARKS => undef,
USE_ACTIONS=> undef,
OPTIMIZE => undef,
EXPORTPARAMS => undef,
SHOREWALL_COMPILER => undef,
EXPAND_POLICIES => undef,
KEEP_RT_TABLES => undef,
DELETE_THEN_ADD => undef,
MULTICAST => undef,
DONT_LOAD => '',
AUTO_COMMENT => undef ,
MANGLE_ENABLED => undef ,
NULL_ROUTE_RFC1918 => undef ,
USE_DEFAULT_RT => undef ,
#
# Packet Disposition
#
MACLIST_DISPOSITION => undef,
TCP_FLAGS_DISPOSITION => undef,
BLACKLIST_DISPOSITION => undef,
);
} else {
%config =
( STARTUP_ENABLED => undef,
VERBOSITY => undef,
#
# Logging
#
LOGFILE => undef,
LOGFORMAT => undef,
LOGTAGONLY => undef,
LOGRATE => undef,
LOGBURST => undef,
LOGALLNEW => undef,
BLACKLIST_LOGLEVEL => undef,
MACLIST_LOG_LEVEL => undef,
TCP_FLAGS_LOG_LEVEL => undef,
SMURF_LOG_LEVEL => undef,
LOG_VERBOSITY => undef,
STARTUP_LOG => undef,
#
# Location of Files
#
IP6TABLES => undef,
#
#PATH is inherited
#
PATH => undef,
SHOREWALL_SHELL => undef,
SUBSYSLOCK => undef,
MODULESDIR => undef,
#
#CONFIG_PATH is inherited
#
CONFIG_PATH => undef,
RESTOREFILE => undef,
LOCKFILE => undef,
#
# Default Actions/Macros
#
DROP_DEFAULT => undef,
REJECT_DEFAULT => undef,
ACCEPT_DEFAULT => undef,
QUEUE_DEFAULT => undef,
NFQUEUE_DEFAULT => undef,
#
# RSH/RCP Commands
#
RSH_COMMAND => undef,
RCP_COMMAND => undef,
#
# Firewall Options
#
IP_FORWARDING => undef,
TC_ENABLED => undef,
TC_EXPERT => undef,
CLEAR_TC => undef,
MARK_IN_FORWARD_CHAIN => undef,
CLAMPMSS => undef,
MUTEX_TIMEOUT => undef,
ADMINISABSENTMINDED => undef,
BLACKLISTNEWONLY => undef,
MODULE_SUFFIX => undef,
MACLIST_TABLE => undef,
MACLIST_TTL => undef,
MAPOLDACTIONS => 'Yes',
FASTACCEPT => undef,
IMPLICIT_CONTINUE => undef,
HIGH_ROUTE_MARKS => undef,
OPTIMIZE => undef,
EXPORTPARAMS => undef,
SHOREWALL_COMPILER => undef,
EXPAND_POLICIES => undef,
KEEP_RT_TABLES => undef,
DELETE_THEN_ADD => undef,
MULTICAST => undef,
DONT_LOAD => '',
AUTO_COMMENT => undef,
MANGLE_ENABLED => undef ,
NULL_ROUTE_RFC1918 => undef ,
USE_DEFAULT_RT => undef ,
#
# Packet Disposition
#
MACLIST_DISPOSITION => undef,
TCP_FLAGS_DISPOSITION => undef,
BLACKLIST_DISPOSITION => undef,
);
}
#
# From parsing the capabilities file
#
@ -452,7 +562,7 @@ sub initialize() {
}
INIT {
initialize;
initialize( F_IPV4 );
#
# These variables appear within single quotes in shorewall.conf -- add them to ENV
# so that read_a_line doesn't have to be smart enough to parse that usage.
@ -1340,6 +1450,12 @@ sub default_yes_no ( $$ ) {
}
}
sub default_yes_no_ipv4 ( $$ ) {
my ( $var, $val ) = @_;
default_yes_no( $var, $val );
warning_message "$var=Yes is ignored for IPv6" if $family == F_IPV4 && $config{$var};
}
my %validlevels = ( DEBUG => 7,
INFO => 6,
NOTICE => 5,
@ -1681,7 +1797,7 @@ sub ensure_config_path() {
my $f = "$globals{SHAREDIR}/configpath";
$globals{CONFDIR} = '/usr/share/shorewall/configfiles/' if $> != 0;
$globals{CONFDIR} = "/usr/share/$product/configfiles/";
unless ( $config{CONFIG_PATH} ) {
fatal_error "$f does not exist" unless -f $f;
@ -1728,7 +1844,7 @@ sub set_shorewall_dir( $ ) {
# Small functions called by get_configuration. We separate them so profiling is more useful
#
sub process_shorewall_conf() {
my $file = find_file 'shorewall.conf';
my $file = find_file "$product.conf";
if ( -f $file ) {
if ( -r _ ) {
@ -1774,9 +1890,9 @@ sub read_capabilities() {
}
if ( $capabilities{CAPVERSION} ) {
warning_message "Your capabilities file is out of date -- it does not contain all of the capabilities defined by Shorewall version $globals{VERSION}" unless $capabilities{CAPVERSION} >= $globals{CAPVERSION};
warning_message "Your capabilities file is out of date -- it does not contain all of the capabilities defined by $Product version $globals{VERSION}" unless $capabilities{CAPVERSION} >= $globals{CAPVERSION};
} else {
warning_message "Your capabilities file may not contain all of the capabilities defined by Shorewall version $globals{VERSION}";
warning_message "Your capabilities file may not contain all of the capabilities defined by $Product version $globals{VERSION}";
}
}
@ -1787,12 +1903,12 @@ sub get_capabilities( $ ) {
my $export = $_[0];
if ( ! $export && $> == 0 ) { # $> == $EUID
my $iptables = $config{IPTABLES};
my $iptables = $config{$toolNAME};
if ( $iptables ) {
fatal_error "IPTABLES=$iptables does not exist or is not executable" unless -x $iptables;
fatal_error "$toolNAME=$iptables does not exist or is not executable" unless -x $iptables;
} else {
fatal_error "Can't find iptables executable" unless $iptables = which 'iptables';
fatal_error "Can't find $toolname executable" unless $iptables = which $toolname;
}
my $iptables_restore=$iptables . '-restore';
@ -1877,8 +1993,8 @@ sub get_configuration( $ ) {
}
check_trivalue ( 'IP_FORWARDING', 'on' );
check_trivalue ( 'ROUTE_FILTER', '' );
check_trivalue ( 'LOG_MARTIANS', 'on' );
check_trivalue ( 'ROUTE_FILTER', '' ); fatal_error "ROUTE_FILTER=On is not supported in IPv6" if $config{ROUTE_FILTER} eq 'on' && $family == F_IPV6;
check_trivalue ( 'LOG_MARTIANS', 'on' ); fatal_error "LOG_MARTIANS=On is not supported in IPv6" if $config{LOG_MARTIANS} eq 'on' && $family == F_IPV6;
default 'STARTUP_LOG' , '';
@ -1913,7 +2029,7 @@ sub get_configuration( $ ) {
unless ( $config{ADD_IP_ALIASES} || $config{ADD_SNAT_ALIASES} ) {
$config{RETAIN_ALIASES} = '';
} else {
default_yes_no 'RETAIN_ALIASES' , '';
default_yes_no_ipv4 'RETAIN_ALIASES' , '';
}
default_yes_no 'ADMINISABSENTMINDED' , '';

View File

@ -26,15 +26,20 @@
#
package Shorewall::IPAddrs;
require Exporter;
use Shorewall::Config qw( :DEFAULT split_list require_capability in_hex8);
use Socket6;
use Shorewall::Config qw( :DEFAULT split_list require_capability in_hex8 F_IPV4 F_IPV6 );
use strict;
our @ISA = qw(Exporter);
our @EXPORT = qw( ALLIPv4
ALLIPv6
ALLIP
ALL
TCP
UDP
ICMP
IPv6_ICMP
SCTP
validate_address
@ -45,33 +50,80 @@ our @EXPORT = qw( ALLIPv4
ip_range_explicit
expand_port_range
allipv4
allipv6
allip
rfc1918_networks
resolve_proto
proto_name
use_ipv4_addrs
use_ipv6_addrs
using_ipv4_addrs
using_ipv6_addrs
validate_port
validate_portpair
validate_port_list
validate_icmp
);
our @EXPORT_OK = qw( );
our $VERSION = 4.1.5;
our $VERSION = 4.3.0;
#
# Some IPv4 useful stuff
# Some IPv4/6 useful stuff
#
our @allipv4 = ( '0.0.0.0/0' );
our @allipv6 = ( '::/0' );
our $family;
use constant { ALLIPv4 => '0.0.0.0/0' , ICMP => 1, TCP => 6, UDP => 17 , SCTP => 132 };
use constant { ALLIPv4 => '0.0.0.0/0' ,
ALLIPv6 => '::/0' ,
ICMP => 1,
TCP => 6,
UDP => 17,
ICMPv6_ICMP => 58,
SCTP => 132 };
our @rfc1918_networks = ( "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" );
sub use_ipv4_addrs() {
$family = F_IPV4;
}
sub using_ipv4() {
$family == F_IPV4;
}
sub use_ipv6_addrs() {
$family = F_IPV6;
}
sub using_ipv6() {
$family == F_IPV6;
}
#
# Initialize globals -- we take this novel approach to globals initialization to allow
# the compiler to run multiple times in the same process. The
# initialize() function does globals initialization for this
# module and is called from an INIT block below. The function is
# also called by Shorewall::Compiler::compiler at the beginning of
# the second and subsequent calls to that function.
#
sub initialize() {
use_ipv4_addrs;
}
INIT {
initialize;
}
sub vlsm_to_mask( $ ) {
my $vlsm = $_[0];
in_hex8 ( ( 0xFFFFFFFF << ( 32 - $vlsm ) ) && 0xFFFFFFFF );
}
sub valid_address( $ ) {
sub valid_4address( $ ) {
my $address = $_[0];
my @address = split /\./, $address;
@ -83,20 +135,19 @@ sub valid_address( $ ) {
1;
}
sub validate_address( $$ ) {
sub validate_4address( $$ ) {
my ( $addr, $allow_name ) = @_;
my @addrs = ( $addr );
unless ( valid_address $addr ) {
unless ( valid_4address $addr ) {
fatal_error "Invalid IP Address ($addr)" unless $allow_name;
fatal_error "Unknown Host ($addr)" unless (@addrs = gethostbyname $addr);
if ( defined wantarray ) {
shift @addrs for (1..4);
for ( @addrs ) {
my (@a) = unpack('C4',$_);
$_ = join('.', @a );
$_ = inet_htoa $_;
}
}
}
@ -130,7 +181,7 @@ sub encodeaddr( $ ) {
$result;
}
sub validate_net( $$ ) {
sub validate_4net( $$ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
my $allow_name = $_[1];
@ -142,10 +193,10 @@ sub validate_net( $$ ) {
if ( defined $vlsm ) {
fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 32;
fatal_error "Invalid Network address ($_[0])" if defined $rest;
fatal_error "Invalid IP address ($net)" unless valid_address $net;
fatal_error "Invalid IP address ($net)" unless valid_4address $net;
} else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net;
validate_address $net, $_[1];
validate_4address $net, $_[1];
$vlsm = 32;
}
@ -159,11 +210,11 @@ sub validate_net( $$ ) {
}
}
sub validate_range( $$ ) {
sub validate_4range( $$ ) {
my ( $low, $high ) = @_;
validate_address $low, 0;
validate_address $high, 0;
validate_4address $low, 0;
validate_4address $high, 0;
my $first = decodeaddr $low;
my $last = decodeaddr $high;
@ -171,6 +222,16 @@ sub validate_range( $$ ) {
fatal_error "Invalid IP Range ($low-$high)" unless $first <= $last;
}
sub validate_4host( $$ ) {
my ( $host, $allow_name ) = $_[0];
if ( $host =~ /^(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)$/ ) {
validate_4ange $1, $2;
} else {
validate_4net( $host, $allow_name );
}
}
sub ip_range_explicit( $ ) {
my $range = $_[0];
my @result;
@ -182,7 +243,7 @@ sub ip_range_explicit( $ ) {
push @result, $low;
if ( defined $high ) {
validate_address $high, 0;
validate_faddress $high, 0;
my $first = decodeaddr $low;
my $last = decodeaddr $high;
@ -209,20 +270,14 @@ sub decompose_net( $ ) {
}
sub validate_host( $$ ) {
my ( $host, $allow_name ) = $_[0];
if ( $host =~ /^(\d+\.\d+\.\d+\.\d+)-(\d+\.\d+\.\d+\.\d+)$/ ) {
validate_range $1, $2;
} else {
validate_net( $host, $allow_name );
}
}
sub allipv4() {
@allipv4;
}
sub allipv6() {
@allipv6;
}
sub rfc1918_networks() {
@rfc1918_networks
}
@ -231,7 +286,7 @@ sub rfc1918_networks() {
# Protocol/port validation
#
our %nametoproto = ( all => 0, ALL => 0, icmp => 1, ICMP => 1, tcp => 6, TCP => 6, udp => 17, UDP => 17 );
our %nametoproto = ( all => 0, ALL => 0, icmp => 1, ICMP => 1, tcp => 6, TCP => 6, udp => 17, UDP => 17 );
our @prototoname = ( 'all', 'icmp', '', '', '', '', 'tcp', '', '', '', '', '', '', '', '', '', '', 'udp' );
#
@ -345,6 +400,8 @@ my %icmp_types = ( any => 'any',
'address-mask-reply' => 18 );
sub validate_icmp( $ ) {
fatal_error "IPv4 ICMP not allowed in an IPv6 Rule" unless $family == F_IPV4;
my $type = $_[0];
my $value = $icmp_types{$type};
@ -419,4 +476,159 @@ sub expand_port_range( $$ ) {
}
}
sub valid_6address( $ ) {
my $address = $_[0];
my @address = split /:/, $address;
return 0 if @address > 8;
return 0 if @address < 8 && ! $address =~ /::/;
return 0 if $address =~ /:::/ || $address =~ /::.*::/;
if ( $address =~ /^:/ ) {
unless ( $address eq '::' ) {
return 0 if $address =~ /:$/ || $address =~ /^:.*::/;
}
} elsif ( $address =~ /:$/ ) {
return 0 if $address =~ /::.*:$/;
}
for my $a ( @address ) {
return 0 unless $a eq '' || ( $a =~ /^[a-fA-f\d]+$/ && oct "0x$a" < 65536 );
}
1;
}
sub validate_6address( $$ ) {
my ( $addr, $allow_name ) = @_;
my @addrs = ( $addr );
unless ( valid_6address $addr ) {
fatal_error "Invalid IPv6 Address ($addr)" unless $allow_name;
fatal_error "Unknown Host ($addr)" unless (@addrs = gethostbyname2 $addr, AF_INET6);
if ( defined wantarray ) {
shift @addrs for (1..4);
for ( @addrs ) {
$_ = inet_ntop AF_INET6, $_;
}
}
}
defined wantarray ? wantarray ? @addrs : $addrs[0] : undef;
}
sub validate_6net( $$ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
my $allow_name = $_[1];
fatal_error "An ipset name ($net) is not allowed in this context" if substr( $net, 0, 1 ) eq '+';
if ( defined $vlsm ) {
fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 64;
fatal_error "Invalid Network address ($_[0])" if defined $rest;
fatal_error "Invalid IPv6 address ($net)" unless valid_6address $net;
} else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net;
validate_6address $net, $allow_name;
}
}
sub validate_6range( $$ ) {
my ( $low, $high ) = @_;
validate_6address $low, 0;
validate_6address $high, 0;
my @low = split ":", $low;
my @high = split ":", $high;
if ( @low == @high ) {
my ( $l, $h) = ( pop @low, pop @high );
return 1 if hex "0x$l" <= hex "0x$h" && join( ":", @low ) eq join( ":", @high );
}
fatal_error "Invalid IPv6 Range ($low-$high)";
}
sub validate_6host( $$ ) {
my ( $host, $allow_name ) = $_[0];
if ( $host =~ /^(.*:.*)-(.*:.*)$/ ) {
validate_6range $1, $2;
} else {
validate_6net( $host, $allow_name );
}
}
my %ipv6_icmp_types = ( any => 'any',
'destination-unreachable' => 1,
'no-route' => '1/0',
'communication-prohibited' => '1/1',
'address-unreachable' => '1/2',
'port-unreachable' => '1/3',
'packet-too-big' => 2,
'time-exceeded' => 3,
'ttl-exceeded' => 3,
'ttl-zero-during-transit' => '3/0',
'ttl-zero-during-reassembly' => '3/1',
'parameter-problem' => 4,
'bad-header' => '4/0',
'unknown-header-type' => '4/1',
'unknown-option' => '4/2',
'echo-request' => 128,
'echo-reply' => 129,
'router-solicitation' => 133,
'router-advertisement' => 134,
'neighbour-solicitation' => 135,
'neighbour-advertisement' => 136,
redirect => 137 );
sub validate_icmp6( $ ) {
fatal_error "IPv6 ICMP not allowed in an IPv4 Rule" unless $family == F_IPV6;
my $type = $_[0];
my $value = $ipv6_icmp_types{$type};
return $value if defined $value;
if ( $type =~ /^(\d+)(\/(\d+))?$/ ) {
return $type if $1 < 256 && ( ! $2 || $3 < 256 );
}
fatal_error "Invalid IPv6 ICMP Type ($type)"
}
sub ALLIP() {
$family == F_IPV4 ? ALLIPv4 : ALLIPv6;
}
sub allip() {
$family == F_IPV4 ? ALLIPv4 : ALLIPv6;
}
sub valid_address ( $ ) {
$family == F_IPV4 ? valid_4address( $_[0] ) : valid_6address( $_[0] );
}
sub validate_address ( $$ ) {
$family == F_IPV4 ? validate_4address( $_[0], $_[1] ) : validate_6address( $_[0], $_[1] );
}
sub validate_net ( $$ ) {
$family == F_IPV4 ? validate_4net( $_[0], $_[1] ) : validate_6net( $_[0], $_[1] );
}
sub validate_range ($$ ) {
$family == F_IPV4 ? validate_4range( $_[0], $_[1] ) : validate_6range( $_[0], $_[1] );
}
sub validate_host ($$ ) {
$family == F_IPV4 ? validate_4host( $_[0], $_[1] ) : validate_6host( $_[0], $_[1] );
}
1;

View File

@ -35,11 +35,13 @@
# --refresh=<chainlist> # Make the 'refresh' command refresh a comma-separated list of chains rather than 'blacklst'.
# --log=<filename> # Log file
# --log_verbosity=<number> # Log Verbosity range -1 to 2
# --family=<number> # IP family; 1 = IPv4, 2 = IPv6
#
use strict;
use FindBin;
use lib "$FindBin::Bin";
use Shorewall::Compiler;
use Shorewall::IPAddrs;
use Getopt::Long;
sub usage( $ ) {
@ -55,6 +57,7 @@ sub usage( $ ) {
[ --log=<filename> ]
[ --log-verbose={-1|0-2} ]
[ --test ]
[ --family={1|2} ]
';
exit shift @_;
}
@ -72,6 +75,7 @@ my $log = '';
my $log_verbose = 0;
my $help = 0;
my $test = 0;
my $family = 1; # F_IPV4
Getopt::Long::Configure ('bundling');
@ -92,6 +96,8 @@ my $result = GetOptions('h' => \$help,
'l=s' => \$log,
'log_verbosity=i' => \$log_verbose,
'test' => \$test,
'f=i' => \$family,
'family=i' => \$family,
);
usage(1) unless $result && @ARGV < 2;
@ -106,4 +112,5 @@ compiler( object => defined $ARGV[0] ? $ARGV[0] : '',
chains => $chains,
log => $log,
log_verbosity => $log_verbose,
test => $test );
test => $test,
family => $family );