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; use strict;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( our @EXPORT = qw(
add_rule add_rule
add_jump add_jump
insert_rule insert_rule
@ -68,6 +68,7 @@ our %EXPORT_TAGS = (
POSTROUTE_RESTRICT POSTROUTE_RESTRICT
ALL_RESTRICT ALL_RESTRICT
chain_family
add_command add_command
add_commands add_commands
move_rules move_rules
@ -247,6 +248,8 @@ use constant { NULL_MODE => 0 , # Generating neither shell commands nor iptabl
our $mode; our $mode;
our $family;
# #
# Initialize globals -- we take this novel approach to globals initialization to allow # Initialize globals -- we take this novel approach to globals initialization to allow
# the compiler to run multiple times in the same process. The # 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. # the second and subsequent calls to that function.
# #
sub initialize() { sub initialize( $ ) {
%chain_table = ( raw => {} , %chain_table = ( raw => {} ,
mangle => {}, mangle => {},
nat => {}, nat => {},
@ -282,40 +285,6 @@ sub initialize() {
# #
$comment = ''; $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', ... # Used to sequence 'exclusion' chains with names 'excl0', 'excl1', ...
# #
$exclseq = 0; $exclseq = 0;
@ -336,10 +305,12 @@ sub initialize() {
%interfacemacs = (); %interfacemacs = ();
%interfacebcasts = (); %interfacebcasts = ();
%interfacegateways = (); %interfacegateways = ();
$family = shift;
} }
INIT { INIT {
initialize; initialize( F_IPV4 );
} }
# #
@ -915,29 +886,108 @@ sub ensure_manual_chain($) {
# #
sub initialize_chain_table() sub initialize_chain_table()
{ {
for my $chain qw(OUTPUT PREROUTING) { if ( $family == F_IPV4 ) {
new_builtin_chain 'raw', $chain, 'ACCEPT'; #
} # 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) { for my $chain qw(OUTPUT PREROUTING) {
new_builtin_chain 'filter', $chain, 'DROP'; new_builtin_chain 'raw', $chain, 'ACCEPT';
} }
for my $chain qw(PREROUTING POSTROUTING OUTPUT) { for my $chain qw(INPUT OUTPUT FORWARD) {
new_builtin_chain 'nat', $chain, 'ACCEPT'; 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 ) { for my $chain qw(PREROUTING INPUT OUTPUT ) {
new_builtin_chain 'mangle', $chain, 'ACCEPT'; new_builtin_chain 'mangle', $chain, 'ACCEPT';
} }
if ( $capabilities{MANGLE_FORWARD} ) { if ( $capabilities{MANGLE_FORWARD} ) {
for my $chain qw( FORWARD POSTROUTING ) { 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'; new_builtin_chain 'mangle', $chain, 'ACCEPT';
} }
} }
} }
# #
# Add ESTABLISHED,RELATED rules and synparam jumps to the passed chain # Add ESTABLISHED,RELATED rules and synparam jumps to the passed chain
# #
@ -1914,7 +1964,16 @@ sub expand_rule( $$$$$$$$$$$ )
if ( $source ) { if ( $source ) {
if ( $source eq '-' ) { if ( $source eq '-' ) {
$source = ''; $source = '';
} elsif ( $source =~ /^([^:]+):([^:]+)$/ ) { } elsif ( $family == F_IPV4 ) {
if ( $source =~ /^([^:]+):([^:]+)$/ ) {
$iiface = $1;
$inets = $2;
} elsif ( $source =~ /\+|~|\..*\./ ) {
$inets = $source;
} else {
$iiface = $source;
}
} elsif ( $source =~ /^([^;]+);([^;]+)$/ ) {
$iiface = $1; $iiface = $1;
$inets = $2; $inets = $2;
} elsif ( $source =~ /\+|~|\..*\./ ) { } elsif ( $source =~ /\+|~|\..*\./ ) {
@ -1986,7 +2045,16 @@ sub expand_rule( $$$$$$$$$$$ )
} }
$dest = ''; $dest = '';
} elsif ( $dest =~ /^([^:]+):([^:]+)$/ ) { } elsif ( $family == F_IPV4 ) {
if ( $dest =~ /^([^:]+):([^:]+)$/ ) {
$diface = $1;
$dnets = $2;
} elsif ( $dest =~ /\+|~|\..*\./ ) {
$dnets = $dest;
} else {
$diface = $dest;
}
} elsif ( $dest =~ /^([^;]+);([^;]+)$/ ) {
$diface = $1; $diface = $1;
$dnets = $2; $dnets = $2;
} elsif ( $dest =~ /\+|~|\..*\./ ) { } elsif ( $dest =~ /\+|~|\..*\./ ) {
@ -2363,10 +2431,14 @@ sub create_netfilter_load() {
my @table_list; my @table_list;
push @table_list, 'raw' if $capabilities{RAW_TABLE}; if ( $family == F_IPV4 ) {
push @table_list, 'nat' if $capabilities{NAT_ENABLED}; push @table_list, 'raw' if $capabilities{RAW_TABLE};
push @table_list, 'mangle' if $capabilities{MANGLE_ENABLED} && $config{MANGLE_ENABLED}; push @table_list, 'nat' if $capabilities{NAT_ENABLED};
push @table_list, 'filter'; 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; $mode = NULL_MODE;
@ -2376,11 +2448,13 @@ sub create_netfilter_load() {
push_indent; 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 '';
emit 'exec 3>${VARDIR}/.iptables-restore-input'; emit "exec 3>\${VARDIR}/.${utility}-input";
enter_cat_mode; enter_cat_mode;
@ -2425,7 +2499,7 @@ sub create_netfilter_load() {
enter_cmd_mode; enter_cmd_mode;
# #
# Now generate the actual iptables-restore command # Now generate the actual ip[6]tables-restore command
# #
emit( 'exec 3>&-', emit( 'exec 3>&-',
'', '',
@ -2433,9 +2507,9 @@ sub create_netfilter_load() {
'', '',
'progress_message2 "Running $command..."', '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', '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" "fi\n"
); );

View File

@ -37,6 +37,7 @@ use Shorewall::Accounting;
use Shorewall::Rules; use Shorewall::Rules;
use Shorewall::Proc; use Shorewall::Proc;
use Shorewall::Proxyarp; use Shorewall::Proxyarp;
use Shorewall::IPAddrs;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG ); our @EXPORT = qw( compiler EXPORT TIMESTAMP DEBUG );
@ -49,6 +50,8 @@ our $test;
our $reused = 0; our $reused = 0;
our $family = F_IPV4;
use constant { EXPORT => 0x01 , use constant { EXPORT => 0x01 ,
TIMESTAMP => 0x02 , TIMESTAMP => 0x02 ,
DEBUG => 0x04 }; DEBUG => 0x04 };
@ -57,8 +60,8 @@ use constant { EXPORT => 0x01 ,
# Reinitilize the package-globals in the other modules # Reinitilize the package-globals in the other modules
# #
sub reinitialize() { sub reinitialize() {
Shorewall::Config::initialize; Shorewall::Config::initialize($family);
Shorewall::Chains::initialize; Shorewall::Chains::initialize ($family);
Shorewall::Zones::initialize; Shorewall::Zones::initialize;
Shorewall::Policy::initialize; Shorewall::Policy::initialize;
Shorewall::Nat::initialize; Shorewall::Nat::initialize;
@ -733,8 +736,14 @@ sub compiler {
defined($val) && ($val >= MIN_VERBOSITY) && ($val <= MAX_VERBOSITY); 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 }, my %parms = ( object => { store => \$objectfile },
directory => { store => \$directory }, directory => { store => \$directory },
family => { store => \$family , edit => \&edit_family } ,
verbosity => { store => \$verbosity , edit => \&edit_verbosity } , verbosity => { store => \$verbosity , edit => \&edit_verbosity } ,
timestamp => { store => \$timestamp, edit => \&edit_boolean } , timestamp => { store => \$timestamp, edit => \&edit_boolean } ,
debug => { store => \$debug, edit => \&edit_boolean } , debug => { store => \$debug, edit => \&edit_boolean } ,
@ -755,7 +764,7 @@ sub compiler {
${$ref->{store}} = $val; ${$ref->{store}} = $val;
} }
reinitialize if $reused++; reinitialize if ++$reused || $family == F_IPV6;
if ( $directory ne '' ) { if ( $directory ne '' ) {
fatal_error "$directory is not an existing directory" unless -d $directory; 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 run_user_exit2
generate_aux_config generate_aux_config
$product
$Product
$command $command
$doing $doing
$done $done
@ -108,6 +110,9 @@ our %EXPORT_TAGS = ( internal => [ qw( create_temp_object
%globals %globals
%capabilities %capabilities
F_IPV4
F_IPV6
MIN_VERBOSITY MIN_VERBOSITY
MAX_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 $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, 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 # 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 # also called by Shorewall::Compiler::compiler at the beginning of
# the second and subsequent calls to that function. # 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. ( $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) $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 => '', LOGPARMS => '',
TC_SCRIPT => '', TC_SCRIPT => '',
EXPORT => 0, EXPORT => 0,
VERSION => "4.2.3", VERSION => "4.3.0",
CAPVERSION => 40203 , CAPVERSION => 40203 ,
); );
# #
# From shorewall.conf file # From shorewall.conf file
# #
%config = if ( $family == F_IPV4 ) {
( STARTUP_ENABLED => undef, %config =
VERBOSITY => undef, ( STARTUP_ENABLED => undef,
# VERBOSITY => undef,
# Logging #
# # Logging
LOGFILE => undef, #
LOGFORMAT => undef, LOGFILE => undef,
LOGTAGONLY => undef, LOGFORMAT => undef,
LOGRATE => undef, LOGTAGONLY => undef,
LOGBURST => undef, LOGRATE => undef,
LOGALLNEW => undef, LOGBURST => undef,
BLACKLIST_LOGLEVEL => undef, LOGALLNEW => undef,
MACLIST_LOG_LEVEL => undef, BLACKLIST_LOGLEVEL => undef,
TCP_FLAGS_LOG_LEVEL => undef, MACLIST_LOG_LEVEL => undef,
RFC1918_LOG_LEVEL => undef, TCP_FLAGS_LOG_LEVEL => undef,
SMURF_LOG_LEVEL => undef, RFC1918_LOG_LEVEL => undef,
LOG_MARTIANS => undef, SMURF_LOG_LEVEL => undef,
LOG_VERBOSITY => undef, LOG_MARTIANS => undef,
STARTUP_LOG => undef, LOG_VERBOSITY => undef,
# STARTUP_LOG => undef,
# Location of Files #
# # Location of Files
IPTABLES => undef, #
# IPTABLES => undef,
#PATH is inherited #
# #PATH is inherited
PATH => undef, #
SHOREWALL_SHELL => undef, PATH => undef,
SUBSYSLOCK => undef, SHOREWALL_SHELL => undef,
MODULESDIR => undef, SUBSYSLOCK => undef,
# MODULESDIR => undef,
#CONFIG_PATH is inherited #
# #CONFIG_PATH is inherited
CONFIG_PATH => undef, #
RESTOREFILE => undef, CONFIG_PATH => undef,
IPSECFILE => undef, RESTOREFILE => undef,
LOCKFILE => undef, IPSECFILE => undef,
# LOCKFILE => undef,
# Default Actions/Macros #
# # Default Actions/Macros
DROP_DEFAULT => undef, #
REJECT_DEFAULT => undef, DROP_DEFAULT => undef,
ACCEPT_DEFAULT => undef, REJECT_DEFAULT => undef,
QUEUE_DEFAULT => undef, ACCEPT_DEFAULT => undef,
NFQUEUE_DEFAULT => undef, QUEUE_DEFAULT => undef,
# NFQUEUE_DEFAULT => undef,
# RSH/RCP Commands #
# # RSH/RCP Commands
RSH_COMMAND => undef, #
RCP_COMMAND => undef, RSH_COMMAND => undef,
# RCP_COMMAND => undef,
# Firewall Options #
# # Firewall Options
BRIDGING => undef, #
IP_FORWARDING => undef, BRIDGING => undef,
ADD_IP_ALIASES => undef, IP_FORWARDING => undef,
ADD_SNAT_ALIASES => undef, ADD_IP_ALIASES => undef,
RETAIN_ALIASES => undef, ADD_SNAT_ALIASES => undef,
TC_ENABLED => undef, RETAIN_ALIASES => undef,
TC_EXPERT => undef, TC_ENABLED => undef,
CLEAR_TC => undef, TC_EXPERT => undef,
MARK_IN_FORWARD_CHAIN => undef, CLEAR_TC => undef,
CLAMPMSS => undef, MARK_IN_FORWARD_CHAIN => undef,
ROUTE_FILTER => undef, CLAMPMSS => undef,
DETECT_DNAT_IPADDRS => undef, ROUTE_FILTER => undef,
MUTEX_TIMEOUT => undef, DETECT_DNAT_IPADDRS => undef,
ADMINISABSENTMINDED => undef, MUTEX_TIMEOUT => undef,
BLACKLISTNEWONLY => undef, ADMINISABSENTMINDED => undef,
DELAYBLACKLISTLOAD => undef, BLACKLISTNEWONLY => undef,
MODULE_SUFFIX => undef, DELAYBLACKLISTLOAD => undef,
DISABLE_IPV6 => undef, MODULE_SUFFIX => undef,
DYNAMIC_ZONES => undef, DISABLE_IPV6 => undef,
PKTTYPE=> undef, DYNAMIC_ZONES => undef,
RFC1918_STRICT => undef, PKTTYPE=> undef,
MACLIST_TABLE => undef, RFC1918_STRICT => undef,
MACLIST_TTL => undef, MACLIST_TABLE => undef,
SAVE_IPSETS => undef, MACLIST_TTL => undef,
MAPOLDACTIONS => undef, SAVE_IPSETS => undef,
FASTACCEPT => undef, MAPOLDACTIONS => undef,
IMPLICIT_CONTINUE => undef, FASTACCEPT => undef,
HIGH_ROUTE_MARKS => undef, IMPLICIT_CONTINUE => undef,
USE_ACTIONS=> undef, HIGH_ROUTE_MARKS => undef,
OPTIMIZE => undef, USE_ACTIONS=> undef,
EXPORTPARAMS => undef, OPTIMIZE => undef,
SHOREWALL_COMPILER => undef, EXPORTPARAMS => undef,
EXPAND_POLICIES => undef, SHOREWALL_COMPILER => undef,
KEEP_RT_TABLES => undef, EXPAND_POLICIES => undef,
DELETE_THEN_ADD => undef, KEEP_RT_TABLES => undef,
MULTICAST => undef, DELETE_THEN_ADD => undef,
DONT_LOAD => '', MULTICAST => undef,
AUTO_COMMENT => undef , DONT_LOAD => '',
MANGLE_ENABLED => undef , AUTO_COMMENT => undef ,
NULL_ROUTE_RFC1918 => undef , MANGLE_ENABLED => undef ,
USE_DEFAULT_RT => undef , NULL_ROUTE_RFC1918 => undef ,
# USE_DEFAULT_RT => undef ,
# Packet Disposition #
# # Packet Disposition
MACLIST_DISPOSITION => undef, #
TCP_FLAGS_DISPOSITION => undef, MACLIST_DISPOSITION => undef,
BLACKLIST_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 # From parsing the capabilities file
# #
@ -452,7 +562,7 @@ sub initialize() {
} }
INIT { INIT {
initialize; initialize( F_IPV4 );
# #
# These variables appear within single quotes in shorewall.conf -- add them to ENV # 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. # 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, my %validlevels = ( DEBUG => 7,
INFO => 6, INFO => 6,
NOTICE => 5, NOTICE => 5,
@ -1681,7 +1797,7 @@ sub ensure_config_path() {
my $f = "$globals{SHAREDIR}/configpath"; my $f = "$globals{SHAREDIR}/configpath";
$globals{CONFDIR} = '/usr/share/shorewall/configfiles/' if $> != 0; $globals{CONFDIR} = "/usr/share/$product/configfiles/";
unless ( $config{CONFIG_PATH} ) { unless ( $config{CONFIG_PATH} ) {
fatal_error "$f does not exist" unless -f $f; 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 # Small functions called by get_configuration. We separate them so profiling is more useful
# #
sub process_shorewall_conf() { sub process_shorewall_conf() {
my $file = find_file 'shorewall.conf'; my $file = find_file "$product.conf";
if ( -f $file ) { if ( -f $file ) {
if ( -r _ ) { if ( -r _ ) {
@ -1774,9 +1890,9 @@ sub read_capabilities() {
} }
if ( $capabilities{CAPVERSION} ) { 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 { } 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]; my $export = $_[0];
if ( ! $export && $> == 0 ) { # $> == $EUID if ( ! $export && $> == 0 ) { # $> == $EUID
my $iptables = $config{IPTABLES}; my $iptables = $config{$toolNAME};
if ( $iptables ) { 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 { } 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'; my $iptables_restore=$iptables . '-restore';
@ -1877,8 +1993,8 @@ sub get_configuration( $ ) {
} }
check_trivalue ( 'IP_FORWARDING', 'on' ); check_trivalue ( 'IP_FORWARDING', 'on' );
check_trivalue ( 'ROUTE_FILTER', '' ); 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' ); 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' , ''; default 'STARTUP_LOG' , '';
@ -1913,7 +2029,7 @@ sub get_configuration( $ ) {
unless ( $config{ADD_IP_ALIASES} || $config{ADD_SNAT_ALIASES} ) { unless ( $config{ADD_IP_ALIASES} || $config{ADD_SNAT_ALIASES} ) {
$config{RETAIN_ALIASES} = ''; $config{RETAIN_ALIASES} = '';
} else { } else {
default_yes_no 'RETAIN_ALIASES' , ''; default_yes_no_ipv4 'RETAIN_ALIASES' , '';
} }
default_yes_no 'ADMINISABSENTMINDED' , ''; default_yes_no 'ADMINISABSENTMINDED' , '';

View File

@ -26,15 +26,20 @@
# #
package Shorewall::IPAddrs; package Shorewall::IPAddrs;
require Exporter; 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; use strict;
our @ISA = qw(Exporter); our @ISA = qw(Exporter);
our @EXPORT = qw( ALLIPv4 our @EXPORT = qw( ALLIPv4
ALLIPv6
ALLIP
ALL
TCP TCP
UDP UDP
ICMP ICMP
IPv6_ICMP
SCTP SCTP
validate_address validate_address
@ -45,33 +50,80 @@ our @EXPORT = qw( ALLIPv4
ip_range_explicit ip_range_explicit
expand_port_range expand_port_range
allipv4 allipv4
allipv6
allip
rfc1918_networks rfc1918_networks
resolve_proto resolve_proto
proto_name proto_name
use_ipv4_addrs
use_ipv6_addrs
using_ipv4_addrs
using_ipv6_addrs
validate_port validate_port
validate_portpair validate_portpair
validate_port_list validate_port_list
validate_icmp validate_icmp
); );
our @EXPORT_OK = qw( ); 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 @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" ); 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( $ ) { sub vlsm_to_mask( $ ) {
my $vlsm = $_[0]; my $vlsm = $_[0];
in_hex8 ( ( 0xFFFFFFFF << ( 32 - $vlsm ) ) && 0xFFFFFFFF ); in_hex8 ( ( 0xFFFFFFFF << ( 32 - $vlsm ) ) && 0xFFFFFFFF );
} }
sub valid_address( $ ) { sub valid_4address( $ ) {
my $address = $_[0]; my $address = $_[0];
my @address = split /\./, $address; my @address = split /\./, $address;
@ -83,20 +135,19 @@ sub valid_address( $ ) {
1; 1;
} }
sub validate_address( $$ ) { sub validate_4address( $$ ) {
my ( $addr, $allow_name ) = @_; my ( $addr, $allow_name ) = @_;
my @addrs = ( $addr ); my @addrs = ( $addr );
unless ( valid_address $addr ) { unless ( valid_4address $addr ) {
fatal_error "Invalid IP Address ($addr)" unless $allow_name; fatal_error "Invalid IP Address ($addr)" unless $allow_name;
fatal_error "Unknown Host ($addr)" unless (@addrs = gethostbyname $addr); fatal_error "Unknown Host ($addr)" unless (@addrs = gethostbyname $addr);
if ( defined wantarray ) { if ( defined wantarray ) {
shift @addrs for (1..4); shift @addrs for (1..4);
for ( @addrs ) { for ( @addrs ) {
my (@a) = unpack('C4',$_); $_ = inet_htoa $_;
$_ = join('.', @a );
} }
} }
} }
@ -130,7 +181,7 @@ sub encodeaddr( $ ) {
$result; $result;
} }
sub validate_net( $$ ) { sub validate_4net( $$ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 ); my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
my $allow_name = $_[1]; my $allow_name = $_[1];
@ -142,10 +193,10 @@ sub validate_net( $$ ) {
if ( defined $vlsm ) { if ( defined $vlsm ) {
fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 32; fatal_error "Invalid VLSM ($vlsm)" unless $vlsm =~ /^\d+$/ && $vlsm <= 32;
fatal_error "Invalid Network address ($_[0])" if defined $rest; 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 { } else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net; fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net;
validate_address $net, $_[1]; validate_4address $net, $_[1];
$vlsm = 32; $vlsm = 32;
} }
@ -159,11 +210,11 @@ sub validate_net( $$ ) {
} }
} }
sub validate_range( $$ ) { sub validate_4range( $$ ) {
my ( $low, $high ) = @_; my ( $low, $high ) = @_;
validate_address $low, 0; validate_4address $low, 0;
validate_address $high, 0; validate_4address $high, 0;
my $first = decodeaddr $low; my $first = decodeaddr $low;
my $last = decodeaddr $high; my $last = decodeaddr $high;
@ -171,6 +222,16 @@ sub validate_range( $$ ) {
fatal_error "Invalid IP Range ($low-$high)" unless $first <= $last; 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( $ ) { sub ip_range_explicit( $ ) {
my $range = $_[0]; my $range = $_[0];
my @result; my @result;
@ -182,7 +243,7 @@ sub ip_range_explicit( $ ) {
push @result, $low; push @result, $low;
if ( defined $high ) { if ( defined $high ) {
validate_address $high, 0; validate_faddress $high, 0;
my $first = decodeaddr $low; my $first = decodeaddr $low;
my $last = decodeaddr $high; 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() { sub allipv4() {
@allipv4; @allipv4;
} }
sub allipv6() {
@allipv6;
}
sub rfc1918_networks() { sub rfc1918_networks() {
@rfc1918_networks @rfc1918_networks
} }
@ -231,7 +286,7 @@ sub rfc1918_networks() {
# Protocol/port validation # 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' ); our @prototoname = ( 'all', 'icmp', '', '', '', '', 'tcp', '', '', '', '', '', '', '', '', '', '', 'udp' );
# #
@ -345,6 +400,8 @@ my %icmp_types = ( any => 'any',
'address-mask-reply' => 18 ); 'address-mask-reply' => 18 );
sub validate_icmp( $ ) { sub validate_icmp( $ ) {
fatal_error "IPv4 ICMP not allowed in an IPv6 Rule" unless $family == F_IPV4;
my $type = $_[0]; my $type = $_[0];
my $value = $icmp_types{$type}; 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; 1;

View File

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