diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm index 5cf6314d7..bd1779d61 100644 --- a/Shorewall/Perl/Shorewall/Chains.pm +++ b/Shorewall/Perl/Shorewall/Chains.pm @@ -806,7 +806,7 @@ sub transform_rule( $ ) { } } - set_rule_option( $ruleref, $option, $params ) unless $params eq ''; + set_rule_option( $ruleref, $option, $params ); } $ruleref->{simple} = $simple; diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index d50b57b84..6b655219c 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -169,6 +169,7 @@ my %restrictions = ( tcpre => PREROUTE_RESTRICT , tcout => OUTPUT_RESTRICT ); my $family; +my $divert; # # Rather than initializing globals in an INIT block or during declaration, @@ -191,6 +192,7 @@ sub initialize( $ ) { $devnum = 0; $sticky = 0; $ipp2p = 0; + $divert = 0; } sub process_tc_rule( ) { @@ -242,6 +244,7 @@ sub process_tc_rule( ) { my $restriction = 0; my $cmd; my $rest; + my $matches = ''; my %processtcc = ( sticky => sub() { if ( $chain eq 'tcout' ) { @@ -294,6 +297,32 @@ sub process_tc_rule( ) { $target = "IPMARK --addr $srcdst --and-mask $mask1 --or-mask $mask2 --shift $shift"; }, + DIVERT => sub() { + fatal_error "Invalid DIVERT specification( $cmd/$rest )" if $rest; + + $chain = 'tcpre'; + + $cmd =~ /DIVERT\((.+?)\)$/; + + $mark = $1; + + fatal_error "Invalid DIVERT specification( $cmd )" unless defined $mark; + + my $val = numeric_value( $mark ); + + validate_mark $val . '/' . in_hex( $globals{PROVIDER_MASK} ); + + my $divertref = new_chain( 'mangle', 'DIVERT' . ( $divert ? $divert : '' ) ); + + $divert++; + + add_ijump( $divertref , j => 'MARK', targetopts => '--set-mark ' . in_hex( $val ) . '/' . in_hex( $globals{PROVIDER_MASK} ) ); + add_ijump( $divertref , j => 'ACCEPT' ); + + $target = $divertref->{name}; + + $matches = '-m socket '; + }, TPROXY => sub() { require_capability( 'TPROXY_TARGET', 'Use of TPROXY', 's'); @@ -539,7 +568,8 @@ sub process_tc_rule( ) { do_helper( $helper ) . do_headers( $headers ) . do_probability( $probability ) . - do_dscp( $dscp ), + do_dscp( $dscp ) . + $matches , $source , $dest , '' , @@ -2002,6 +2032,11 @@ sub setup_tc() { mark => HIGHMARK, mask => '', connmark => '' }, + { match => sub( $ ) { $_[0] =~ /^DIVERT/ }, + target => 'DIVERT', + mark => HIGHMARK, + mask => '', + connmark => '' }, { match => sub( $ ) { $_[0] =~ /^TTL/ }, target => 'TTL', mark => NOMARK, diff --git a/Shorewall/manpages/shorewall-tcrules.xml b/Shorewall/manpages/shorewall-tcrules.xml index 118634c5e..e0293b90a 100644 --- a/Shorewall/manpages/shorewall-tcrules.xml +++ b/Shorewall/manpages/shorewall-tcrules.xml @@ -407,6 +407,19 @@ SAME $FW 0.0.0.0/0 tcp 80,443 classes will have a value > 256. + + DIVERT(mark) + + Added in Shorewall 4.5.3. A DIVERT rule should preceed + each TPROXY rule and should specify the same + mark value. DIVERT avoids sending + packets to the TPROXY target once a socket connection to Squid3 + has been established by TPROXY. DIVERT marks the packet with the + specified mark and exempts it from + any rules that follow. + + TPROXY(mark[/mask][,[port][,[address]]]) @@ -438,6 +451,12 @@ SAME $FW 0.0.0.0/0 tcp 80,443 request arrives. + + + A DIVERT rule specifying the same + mark value and other column values + should preceed each TPROXY rule. + diff --git a/Shorewall6/manpages/shorewall6-tcrules.xml b/Shorewall6/manpages/shorewall6-tcrules.xml index 103653f78..ebe7fc79c 100644 --- a/Shorewall6/manpages/shorewall6-tcrules.xml +++ b/Shorewall6/manpages/shorewall6-tcrules.xml @@ -304,6 +304,19 @@ SAME $FW 0.0.0.0/0 tcp 80,443 simply include COMMENT on a line by itself. + + DIVERT(mark) + + Added in Shorewall 4.5.3. A DIVERT rule should preceed + each TPROXY rule and should specify the same + mark value. DIVERT avoids sending + packets to the TPROXY target once a socket connection to Squid3 + has been established by TPROXY. DIVERT marks the packet with the + specified mark and exempts it from + any rules that follow. + + TPROXY(mark[/mask][,[port][,[address]]]) @@ -335,6 +348,12 @@ SAME $FW 0.0.0.0/0 tcp 80,443 request arrives. + + + A DIVERT rule specifying the same + mark value and other column values + should preceed each TPROXY rule. + diff --git a/docs/Shorewall_Squid_Usage.xml b/docs/Shorewall_Squid_Usage.xml index af678e68e..92e6f8851 100644 --- a/docs/Shorewall_Squid_Usage.xml +++ b/docs/Shorewall_Squid_Usage.xml @@ -336,8 +336,16 @@ Tproxy 1 1 - lo - local MARK SOURCE DEST PROTO PORT(S) +DIVERT(1) eth1 0.0.0.0/0 tcp 80 TPROXY(1,3128) eth1 0.0.0.0/0 tcp 80 + + The DIVERT action was added in Shorewall 4.5.3; user's running + earlier versions of Shorewall will need to use the start extension script to add the + DIVERT logic mentioned in the Squid article linked above. + + /etc/shorewall/rules: #ACTION SOURCE DEST PROTO DEST PORT(S)