From 07cdb8ca8233cadf735b6ea07e644afffba486f6 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 17 Jan 2010 08:12:44 -0800 Subject: [PATCH] Backport TPROXY from 4.5 Signed-off-by: Tom Eastep --- Shorewall/Perl/Shorewall/Providers.pm | 25 ++++++++++++--- Shorewall/Perl/Shorewall/Tc.pm | 44 +++++++++++++++++++++++++-- Shorewall/lib.base | 6 +++- Shorewall6/lib.base | 6 +++- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm index b325c280c..55f16ce0c 100644 --- a/Shorewall/Perl/Shorewall/Providers.pm +++ b/Shorewall/Perl/Shorewall/Providers.pm @@ -35,7 +35,7 @@ use strict; our @ISA = qw(Exporter); our @EXPORT = qw( setup_providers @routemarked_interfaces handle_stickiness handle_optional_interfaces ); our @EXPORT_OK = qw( initialize lookup_provider ); -our $VERSION = '4.4_6'; +our $VERSION = '4.4_7'; use constant { LOCAL_TABLE => 255, MAIN_TABLE => 254, @@ -295,8 +295,8 @@ sub add_a_provider( ) { $gateway = ''; } - my ( $loose, $track, $balance , $default, $default_balance, $optional, $mtu ) = - (0, $config{TRACK_PROVIDERS}, 0 , 0, $config{USE_DEFAULT_RT} ? 1 : 0, interface_is_optional( $interface ), '' ); + my ( $loose, $track, $balance , $default, $default_balance, $optional, $mtu, $local ) = + (0, $config{TRACK_PROVIDERS}, 0 , 0, $config{USE_DEFAULT_RT} ? 1 : 0, interface_is_optional( $interface ), '' , 0 ); unless ( $options eq '-' ) { for my $option ( split_list $options, 'option' ) { @@ -337,6 +337,10 @@ sub add_a_provider( ) { } else { $default = -1; } + } elsif ( $option eq 'local' ) { + $local = 1; + $track = 0 if $config{TRACK_PROVIDERS}; + $default_balance = 0 if$config{USE_DEFAULT_RT}; } else { fatal_error "Invalid option ($option)"; } @@ -421,7 +425,13 @@ sub add_a_provider( ) { $provider_interfaces{$interface} = $table; - emit "run_ip route add default dev $physical table $number" if $gatewaycase eq 'none'; + if ( $gatewaycase eq 'none' ) { + if ( $local ) { + emit "run_ip route add local 0.0.0.0/0 dev $physical table $number"; + } else { + emit "run_ip route add default dev $physical table $number"; + } + } } if ( $mark ne '-' ) { @@ -471,7 +481,12 @@ sub add_a_provider( ) { } } - if ( $loose ) { + if ( $local ) { + fatal_error "GATEWAY not valid with 'local' provider" unless $gatewaycase eq 'none'; + fatal_error "'track' not valid with 'local'" if $track; + fatal_error "DUPLICATE not valid with 'local'" if $duplicate ne '-'; + fatal_error "MARK required with 'local'" unless $mark; + } elsif ( $loose ) { if ( $config{DELETE_THEN_ADD} ) { emit ( "\nfind_interface_addresses $physical | while read address; do", " qt \$IP -$family rule del from \$address", diff --git a/Shorewall/Perl/Shorewall/Tc.pm b/Shorewall/Perl/Shorewall/Tc.pm index eee052bdf..fc1b87d9f 100644 --- a/Shorewall/Perl/Shorewall/Tc.pm +++ b/Shorewall/Perl/Shorewall/Tc.pm @@ -40,7 +40,7 @@ use strict; our @ISA = qw(Exporter); our @EXPORT = qw( setup_tc ); our @EXPORT_OK = qw( process_tc_rule initialize ); -our $VERSION = '4.4_6'; +our $VERSION = '4.4_7'; our %tcs = ( T => { chain => 'tcpost', connmark => 0, @@ -314,7 +314,39 @@ sub process_tc_rule( ) { } $target = "IPMARK --addr $srcdst --and-mask $mask1 --or-mask $mask2 --shift $shift"; + } elsif ( $target eq 'TPROXY ' ) { + require_capability( 'TPROXY_TARGET', 'Use of TPROXY', 's'); + + fatal_error "Invalid TPROXY specification( $cmd/$rest )" if $rest; + + $chain = 'tcpre'; + + $cmd =~ /TPROXY\((.+?)\)$/; + + my $params = $1; + + fatal_error "Invalid TPROXY specification( $cmd )" unless defined $params; + + ( $mark, my $port, my $ip, my $bad ) = split ',', $params; + + fatal_error "Invalid TPROXY specification( $cmd )" if defined $bad; + + if ( $port ) { + $port = validate_port( 'tcp', $port ); + } else { + $port = 0; + } + + $target .= "--on-port $port"; + + if ( defined $ip && $ip ne '' ) { + validate_address $ip, 1; + $target .= " --on-ip $ip"; + } + + $target .= ' --tproxy-mark'; } + if ( $rest ) { fatal_error "Invalid MARK ($originalmark)" if $marktype == NOMARK; @@ -1363,6 +1395,9 @@ sub setup_tc() { $mark_part = '-m mark --mark 0/' . in_hex( $globals{PROVIDER_MASK} ) . ' '; unless ( $config{TRACK_PROVIDERS} ) { + # + # This is overloading TRACK_PROVIDERS a bit but sending tracked packets through PREROUTING is a PITA for users + # for my $interface ( @routemarked_interfaces ) { add_rule $mangle_table->{PREROUTING} , match_source_dev( $interface ) . "-j tcpre"; } @@ -1428,7 +1463,12 @@ sub setup_tc() { mark => HIGHMARK , mask => '' , connmark => 0 - } + } , + { match => sub ( $ ) { $_[0] =~ /^TPROXY/ }, + target => 'TPROXY', + mark => HIGHMARK, + mask => '', + connmark => '' }, ); if ( my $fn = open_file 'tcrules' ) { diff --git a/Shorewall/lib.base b/Shorewall/lib.base index 9ced599cd..757dc545c 100644 --- a/Shorewall/lib.base +++ b/Shorewall/lib.base @@ -29,7 +29,7 @@ # and /usr/share/shorewall-lite/shorecap. # -SHOREWALL_LIBVERSION=40406 +SHOREWALL_LIBVERSION=40407 SHOREWALL_CAPVERSION=40407 [ -n "${VARDIR:=/var/lib/shorewall}" ] @@ -814,6 +814,7 @@ determine_capabilities() { MARK= XMARK= EXMARK= + TPROXY_TARGET= MANGLE_FORWARD= COMMENTS= ADDRTYPE= @@ -925,6 +926,7 @@ determine_capabilities() { qt $IPTABLES -t mangle -A $chain -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes qt $IPTABLES -t mangle -A $chain -j IPMARK --addr src && IPMARK_TARGET=Yes + qt $IPTABLES -t mangle -A $chain -p tcp -j TPROXY --on-port 0 --tproxy-mark 1 && TPROXY_TARGET=Yes qt $IPTABLES -t mangle -F $chain qt $IPTABLES -t mangle -X $chain qt $IPTABLES -t mangle -L FORWARD -n && MANGLE_FORWARD=Yes @@ -1030,6 +1032,7 @@ report_capabilities() { report_capability "IPMARK Target" $IPMARK_TARGET report_capability "LOG Target" $LOG_TARGET report_capability "Persistent SNAT" $PERSISTENT_SNAT + report_capability "TPROXY Target" $TPROXY_TARGET fi [ -n "$PKTTYPE" ] || USEPKTTYPE= @@ -1090,6 +1093,7 @@ report_capabilities1() { report_capability1 IPMARK_TARGET report_capability1 LOG_TARGET report_capability1 PERSISTENT_SNAT + report_capability1 TPROXY_TARGET echo CAPVERSION=$SHOREWALL_CAPVERSION echo KERNELVERSION=$KERNELVERSION diff --git a/Shorewall6/lib.base b/Shorewall6/lib.base index f309e6bdc..bcf9c38aa 100644 --- a/Shorewall6/lib.base +++ b/Shorewall6/lib.base @@ -32,7 +32,7 @@ # by the compiler. # -SHOREWALL_LIBVERSION=40406 +SHOREWALL_LIBVERSION=40407 SHOREWALL_CAPVERSION=40407 [ -n "${VARDIR:=/var/lib/shorewall6}" ] @@ -723,6 +723,7 @@ determine_capabilities() { MARK= XMARK= EXMARK= + TPROXY_TARGET= MANGLE_FORWARD= COMMENTS= ADDRTYPE= @@ -833,6 +834,7 @@ determine_capabilities() { qt $IP6TABLES -t mangle -A $chain -j CLASSIFY --set-class 1:1 && CLASSIFY_TARGET=Yes qt $IP6TABLES -t mangle -A $chain -j IPMARK --addr src && IPMARK_TARGET=Yes + qt $IP6TABLES -t mangle -A $chain -p tcp -j TPROXY --on-port 0 --tproxy-mark 1 && TPROXY_TARGET=Yes qt $IP6TABLES -t mangle -F $chain qt $IP6TABLES -t mangle -X $chain qt $IP6TABLES -t mangle -L FORWARD -n && MANGLE_FORWARD=Yes @@ -934,6 +936,7 @@ report_capabilities() { report_capability "Goto Support" $GOTO_TARGET report_capability "IPMARK Target" $IPMARK_TARGET report_capability "LOG Target" $LOG_TARGET + report_capability "TPROXY Target" $TPROXY_TARGET fi [ -n "$PKTTYPE" ] || USEPKTTYPE= @@ -991,6 +994,7 @@ report_capabilities1() { report_capability1 GOTO_TARGET report_capability1 IPMARK_TARGET report_capability1 LOG_TARGET + report_capability1 TPROXY_TARGET echo CAPVERSION=$SHOREWALL_CAPVERSION echo KERNELVERSION=$KERNELVERSION