From bfb9852eb6e6818c6aa77c5837776695fb5eae3c Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Thu, 14 Jun 2018 09:18:48 -0700 Subject: [PATCH] Allow MARK, CONNMARK, SAVE and RESTORE in the nat table Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Chains.pm | 26 ++++++---- Shorewall/Perl/Shorewall/Config.pm | 2 +- Shorewall/Perl/Shorewall/Rules.pm | 64 +++++++++++++++++-------- Shorewall/manpages/shorewall-mangle.xml | 36 ++++++++++++++ 4 files changed, 98 insertions(+), 30 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index dfa4a09d4..b2f48d46f 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -153,6 +153,9 @@ our %EXPORT_TAGS = ( STICKY STICKO REALPREROUTING + REALINPUT + REALOUTPUT + REALPOSTROUTING ACTIONCHAIN unreachable_warning @@ -490,16 +493,19 @@ use constant { NO_RESTRICT => 0, # FORWARD chain rule - Both -i an # Mangle Table allowed chains enumeration # use constant { - PREROUTING => 1, #Actually tcpre - INPUT => 2, #Actually tcin - FORWARD => 4, #Actually tcfor - OUTPUT => 8, #Actually tcout - POSTROUTING => 16, #Actually tcpost - ALLCHAINS => 31, - STICKY => 32, - STICKO => 64, - REALPREROUTING => 128, - ACTIONCHAIN => 256, + PREROUTING => 1, #Actually tcpre + INPUT => 2, #Actually tcin + FORWARD => 4, #Actually tcfor + OUTPUT => 8, #Actually tcout + POSTROUTING => 16, #Actually tcpost + STICKY => 32, + STICKO => 64, + REALPREROUTING => 128, + REALINPUT => 256, + REALOUTPUT => 512, + REALPOSTROUTING => 1024, + ALLCHAINS => 2047, + ACTIONCHAIN => 2048, }; # diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 38977b2fd..5c4f3f5a9 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -465,7 +465,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT', TPROXY_TARGET => 'TPROXY Target', FLOW_FILTER => 'Flow Classifier', FWMARK_RT_MASK => 'fwmark route mask', - MARK_ANYWHERE => 'Mark in the filter table', + MARK_ANYWHERE => 'Mark in the filter and nat tables', HEADER_MATCH => 'Header Match', ACCOUNT_TARGET => 'ACCOUNT Target', AUDIT_TARGET => 'AUDIT Target', diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm index 72b2850b4..9956a274d 100644 --- a/Shorewall/Perl/Shorewall/Rules.pm +++ b/Shorewall/Perl/Shorewall/Rules.pm @@ -4077,6 +4077,10 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { O => OUTPUT, T => POSTROUTING, R => REALPREROUTING, + NP => REALPREROUTING, + NI => REALINPUT, + NO => REALOUTPUT, + NT => REALPOSTROUTING ); my %chainlabels = ( 1 => 'PREROUTING', @@ -4085,14 +4089,17 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { 8 => 'OUTPUT', 16 => 'POSTROUTING' ); - my %chainnames = ( 1 => 'tcpre', - 2 => 'tcin', - 4 => 'tcfor', - 8 => 'tcout', - 16 => 'tcpost', - 32 => 'sticky', - 64 => 'sticko', - 128 => 'PREROUTING', + my %chainnames = ( 1 => 'tcpre', + 2 => 'tcin', + 4 => 'tcfor', + 8 => 'tcout', + 16 => 'tcpost', + 32 => 'sticky', + 64 => 'sticko', + 128 => 'PREROUTING', + 256 => 'INPUT', + 512 => 'OUTPUT', + 1024 => 'POSTROUTING', ); my $inchain = defined $chainref; @@ -4116,6 +4123,8 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { my $actiontype; my $commandref; my $prerule = ''; + my $table = 'mangle'; + my $tabletype = MANGLE_TABLE; # # Subroutine for handling MARK and CONNMARK. We use an enclosure so as to keep visibility of the # function's local variables without making them static. process_mangle_rule1() is called @@ -4157,7 +4166,7 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { $option ||= ( $and_or eq '|' ? '--or-mark' : $and_or ? '--and-mark' : '--set-mark' ); - my $chainref = ensure_chain( 'mangle', $chain = $chainnames{$chain} ); + my $chainref = ensure_chain( $table, $chain = $chainnames{$chain} ); $restriction |= $chainref->{restriction}; @@ -4476,7 +4485,7 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { my ( $tgt, $options ) = split( ' ', $params, 2 ); my $target_type = $builtin_target{$tgt}; fatal_error "Unknown target ($tgt)" unless $target_type; - fatal_error "The $tgt TARGET is not allowed in the mangle table" unless $target_type & MANGLE_TABLE; + fatal_error "The $tgt TARGET is not allowed in the mangle table" unless $target_type & $tabletype; $target = $params; $usergenerated = 1; }, @@ -4492,7 +4501,7 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { my ( $tgt, $options ) = split( ' ', $params, 2 ); my $target_type = $builtin_target{$tgt}; fatal_error "Unknown target ($tgt)" unless $target_type; - fatal_error "The $tgt TARGET is not allowed in the mangle table" unless $target_type & MANGLE_TABLE; + fatal_error "The $tgt TARGET is not allowed in the mangle table" unless $target_type & $tabletype; $target = $params; $usergenerated = 1; }, @@ -4564,7 +4573,7 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { RESTORE => { defaultchain => 0, - allowedchains => PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING, + allowedchains => PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING | REALPREROUTING | REALINPUT | REALOUTPUT | REALPOSTROUTING, minparams => 0, maxparams => 1, function => sub () { @@ -4600,7 +4609,7 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { SAVE => { defaultchain => 0, - allowedchains => PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING, + allowedchains => PREROUTING | INPUT | FORWARD | OUTPUT | POSTROUTING | REALPREROUTING | REALINPUT | REALOUTPUT | REALPOSTROUTING, minparams => 0, maxparams => 1, function => sub () { @@ -4846,6 +4855,14 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { fatal_error "A chain designator may not be specified in an action body" if $inaction; my $temp = $designators{$designator}; fatal_error "Invalid chain designator ( $designator )" unless $temp; + + if ( $designator =~ /^N/ ) { + fatal_error "Only MARK, CONNMARK, SAVE and RESTORE may be used in the nat table" unless $cmd =~ /^(?:(?:(?:CONN)MARK)|SAVE|RESTORE)[(]?/; + require_capability('MARK_ANYWHERE', "The $designator designator", 's'); + $table = 'nat'; + $tabletype = NAT_TABLE; + } + $designator = $temp; } @@ -4878,12 +4895,21 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { if ( $source ne '-' ) { if ( $source eq $fw ) { - fatal_error 'Rules with SOURCE $FW must use the OUTPUT chain' if $designator && $designator != OUTPUT; - $chain = OUTPUT; + if ( $designator ) { + fatal_error 'Rules with SOURCE $FW must use the OUTPUT chain' unless $designator & ( OUTPUT | REALOUTPUT ); + $chain = $designator; + } else { + $chain = OUTPUT; + } + $source = '-'; } elsif ( $source =~ s/^($fw):// ) { - fatal_error 'Rules with SOURCE $FW must use the OUTPUT chain' if $designator && $designator != OUTPUT; - $chain = OUTPUT; + if ( $designator ) { + fatal_error 'Rules with SOURCE $FW must use the OUTPUT chain' unless $designator & ( OUTPUT | REALOUTPUT ); + $chain = $designator; + } else { + $chain = OUTPUT; + } } } @@ -4953,11 +4979,11 @@ sub process_mangle_rule1( $$$$$$$$$$$$$$$$$$$ ) { } else { $resolve_chain->(); fatal_error "$cmd rules are not allowed in the $chainlabels{$chain} chain" unless $commandref->{allowedchains} & $chain; - unless ( $chain == OUTPUT || $chain == POSTROUTING ) { + unless ( $chain & ( OUTPUT | POSTROUTING | REALOUTPUT | REALPOSTROUTING ) ) { fatal_error 'A USER/GROUP may only be specified when the SOURCE is $FW' unless $user eq '-'; } - $chainref = ensure_chain( 'mangle', $chainnames{$chain} ); + $chainref = ensure_chain( $table, $chainnames{$chain} ); } $restriction |= $chainref->{restriction}; diff --git a/Shorewall/manpages/shorewall-mangle.xml b/Shorewall/manpages/shorewall-mangle.xml index 761c40aca..aa5cc2f0b 100644 --- a/Shorewall/manpages/shorewall-mangle.xml +++ b/Shorewall/manpages/shorewall-mangle.xml @@ -90,8 +90,44 @@ INPUT chain. + + + NP + + + PREROUTING chain in the nat table. + + + + + NI + + + INPUT chain in the nat table. + + + + + NO + + + OUTPUT chain in the nat table. + + + + + NT + + + POSTROUTING chain in the nat table. + + + The nat table designators were added in Shorewall 5.2.1. When + a nat table designator is given, only the CONNMARK, MARK, SAVE and + RESTORE commands may be used. + Unless otherwise specified for the particular command, the default chain is PREROUTING when MARK_IN_FORWARD_CHAIN=No in