From 418034579f5f4e0e96567c4f2e684462df986fc4 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Wed, 27 Feb 2013 09:25:26 -0800 Subject: [PATCH] Support IPv6 Masquerade Signed-off-by: Tom Eastep --- Shorewall-core/lib.cli | 6 ++- Shorewall/Perl/Shorewall/Config.pm | 21 +++++++- Shorewall/Perl/Shorewall/Nat.pm | 16 +++--- Shorewall6/configfiles/{snat => masq} | 6 +-- ...horewall6-snat.xml => shorewall6-masq.xml} | 51 +++++++++---------- 5 files changed, 61 insertions(+), 39 deletions(-) rename Shorewall6/configfiles/{snat => masq} (74%) rename Shorewall6/manpages/{shorewall6-snat.xml => shorewall6-masq.xml} (92%) diff --git a/Shorewall-core/lib.cli b/Shorewall-core/lib.cli index 2a00c0469..f6f022d9e 100644 --- a/Shorewall-core/lib.cli +++ b/Shorewall-core/lib.cli @@ -25,7 +25,7 @@ # loaded after this one and replaces some of the functions declared here. # -SHOREWALL_CAPVERSION=40512 +SHOREWALL_CAPVERSION=40514 [ -n "${g_program:=shorewall}" ] @@ -2197,6 +2197,7 @@ determine_capabilities() { NFACCT_MATCH= CHECKSUM_TARGET= ARPTABLESJF= + MASQUERADE_TGT= AMANDA_HELPER= FTP_HELPER= FTP0_HELPER= @@ -2228,6 +2229,7 @@ determine_capabilities() { else qt $g_tool -t nat -A $chain -j SNAT --to-source 2001::1 --persistent && PERSISTENT_SNAT=Yes fi + qt $g_tool -t nat -A $chain -j MASQUERADE && MASQUERADE_TGT=Yes qt $g_tool -t nat -F $chain qt $g_tool -t nat -X $chain fi @@ -2602,6 +2604,7 @@ report_capabilities_unsorted() { report_capability "NFAcct match" $NFACCT_MATCH report_capability "Checksum Target" $CHECKSUM_TARGET report_capability "Arptables JF" $ARPTABLESJF + report_capability "MASQUERADE Target" $MASQUERADE_TGT report_capability "Amanda Helper" $AMANDA_HELPER report_capability "FTP Helper" $FTP_HELPER @@ -2720,6 +2723,7 @@ report_capabilities_unsorted1() { report_capability1 NFACCT_MATCH report_capability1 CHECKSUM_TARGET report_capability1 ARPTABLESJF + report_capability1 MASQUERADE_TGT report_capability1 AMANDA_HELPER report_capability1 FTP_HELPER diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm index 5bf08ced1..c5c0bf876 100644 --- a/Shorewall/Perl/Shorewall/Config.pm +++ b/Shorewall/Perl/Shorewall/Config.pm @@ -357,6 +357,7 @@ our %capdesc = ( NAT_ENABLED => 'NAT', NFACCT_MATCH => 'NFAcct Match', CHECKSUM_TARGET => 'Checksum Target', ARPTABLESJF => 'Arptables JF', + MASQUERADE_TGT => 'MASQUERADE Target', AMANDA_HELPER => 'Amanda Helper', FTP_HELPER => 'FTP Helper', FTP0_HELPER => 'FTP-0 Helper', @@ -649,7 +650,7 @@ sub initialize( $;$$) { KLUDGEFREE => '', STATEMATCH => '-m state --state', VERSION => "4.5.13-Beta3", - CAPVERSION => 40512 , + CAPVERSION => 40514 , ); # # From shorewall.conf file @@ -901,6 +902,7 @@ sub initialize( $;$$) { NFACCT_MATCH => undef, CHECKSUM_TARGET => undef, ARPTABLESJF => undef, + MASQUERADE_TGT => undef, AMANDA_HELPER => undef, FTP_HELPER => undef, @@ -3561,6 +3563,22 @@ sub Persistent_Snat() { $result; } +sub Masquerade_Tgt() { + have_capability( 'NAT_ENABLED' ) || return ''; + + my $result = ''; + my $address = $family == F_IPV4 ? '1.2.3.4' : '2001::1'; + + if ( qt1( "$iptables -t nat -N $sillyname" ) ) { + $result = qt1( "$iptables -t nat -A $sillyname -j MASQUERADE" ); + qt1( "$iptables -t nat -F $sillyname" ); + qt1( "$iptables -t nat -X $sillyname" ); + + } + + $result; +} + sub Mangle_Enabled() { if ( qt1( "$iptables -t mangle -L -n" ) ) { system( "$iptables -t mangle -N $sillyname" ) == 0 || fatal_error "Cannot Create Mangle chain $sillyname"; @@ -4075,6 +4093,7 @@ our %detect_capability = MANGLE_FORWARD => \&Mangle_Forward, MARK => \&Mark, MARK_ANYWHERE => \&Mark_Anywhere, + MASQUERADE_TGT => \&Masquerade_Tgt, MULTIPORT => \&Multiport, NAT_ENABLED => \&Nat_Enabled, NETBIOS_NS_HELPER => \&Netbios_ns_Helper, diff --git a/Shorewall/Perl/Shorewall/Nat.pm b/Shorewall/Perl/Shorewall/Nat.pm index ca2c8e9d3..05c4cfb2e 100644 --- a/Shorewall/Perl/Shorewall/Nat.pm +++ b/Shorewall/Perl/Shorewall/Nat.pm @@ -172,7 +172,7 @@ sub process_one_masq1( $$$$$$$$$$ ) # if ( $addresses ne '-' ) { if ( $addresses eq 'random' ) { - fatal_error 'Invalid IPv6 address (random)' if $family == F_IPV6; + require_capability( 'MASQUERADE_TGT', 'Masquerade rules', '') if $family == F_IPV6; $randomize = '--random '; } else { $addresses =~ s/:persistent$// and $persistent = ' --persistent '; @@ -194,9 +194,11 @@ sub process_one_masq1( $$$$$$$$$$ ) $detectaddress = 1; } } elsif ( $addresses eq 'NONAT' ) { + fatal_error "'persistent' may not be specified with 'NONAT'" if $persistent; + fatal_error "'random' may not be specified with 'NONAT'" if $randomize; $target = 'RETURN'; $add_snat_aliases = 0; - } else { + } elsif ( $addresses ) { my $addrlist = ''; my @addrs = split_list $addresses, 'address'; @@ -305,13 +307,15 @@ sub process_one_masq1( $$$$$$$$$$ ) } $target .= $addrlist; + } else { + require_capability( 'MASQUERADE_TGT', 'Masquerade rules', '' ) if $family == F_IPV6; } } $target .= $randomize; $target .= $persistent; } else { - fatal_error "IPv6 does does not support MASQUERADE -- you must use SNAT" if $family == F_IPV6; + require_capability( 'MASQUERADE_TGT', 'Masquerade rules', '' ) if $family == F_IPV6; $add_snat_aliases = 0; } # @@ -373,11 +377,9 @@ sub process_one_masq( ) # sub setup_masq() { - my $name = $family == F_IPV4 ? 'masq' : 'snat'; + if ( my $fn = open_file( 'masq', 1, 1 ) ) { - if ( my $fn = open_file( $name, 1, 1 ) ) { - - first_entry( sub { progress_message2 "$doing $fn..."; require_capability 'NAT_ENABLED' , "a non-empty $name file" , 's'; } ); + first_entry( sub { progress_message2 "$doing $fn..."; require_capability 'NAT_ENABLED' , "a non-empty masq file" , 's'; } ); process_one_masq while read_a_line( NORMAL_READ ); } diff --git a/Shorewall6/configfiles/snat b/Shorewall6/configfiles/masq similarity index 74% rename from Shorewall6/configfiles/snat rename to Shorewall6/configfiles/masq index c7f3773d5..cc39de594 100644 --- a/Shorewall6/configfiles/snat +++ b/Shorewall6/configfiles/masq @@ -1,10 +1,10 @@ # -# Shorewall6 version 4 - SNAT file +# Shorewall6 version 4 - MASQUERADE/SNAT file # -# For information about entries in this file, type "man shorewall6-snat" +# For information about entries in this file, type "man shorewall6-masq" # # The manpage is also online at -# http://www.shorewall.net/manpages6/shorewall6-snat.html +# http://www.shorewall.net/manpages6/shorewall6-masq.html # ######################################################################################################################## #INTERFACE SOURCE ADDRESS PROTO PORT(S) IPSEC MARK USER/ SWITCH ORIGINAL diff --git a/Shorewall6/manpages/shorewall6-snat.xml b/Shorewall6/manpages/shorewall6-masq.xml similarity index 92% rename from Shorewall6/manpages/shorewall6-snat.xml rename to Shorewall6/manpages/shorewall6-masq.xml index 4027da24c..2877ffa56 100644 --- a/Shorewall6/manpages/shorewall6-snat.xml +++ b/Shorewall6/manpages/shorewall6-masq.xml @@ -3,20 +3,20 @@ "http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd"> - shorewall6-snat + shorewall6-masq 5 - snat + masq - Shorewall6 SNAT definition file + Shorewall6 Masquerade/SNAT definition file - /etc/shorewall6/snat + /etc/shorewall6/masq @@ -26,11 +26,6 @@ Use this file to define Source NAT (SNAT). Requires Shorewall 4.5.14 or later. - - Unlike with IPv4, Netfilter does not support the MASQUERADE target - with IPv6. - - The entries in this file are order-sensitive. The first entry that matches a particular connection will be the one that is used. @@ -117,27 +112,32 @@ - ADDRESS - - {address-or-address-range[,address-or-address-range]...][:lowportADDRESS (Optional) - [-|NONAT|[address-or-address-range[,address-or-address-range]...][:lowport-highport][:random][:persistent]|} + role="bold">:random][:persistent]|detect|random] - The address specified here will be used as the source address. - If you simply wish to use the IPv6 address of the - interface in the first column, enter the - name of that interface preceded by an apersand ('&') - e.g., - &sit1. + If you do not specify an address or address range, + masquerading will be performed. This requires Masquerade + Target support in your kernel and ip6tables. + + If you specify an address here, SNAT will be used and this + will be the source address. You may also specify a range of up to 256 IP addresses if you want the SNAT address to be assigned from that range in a round-robin fashion by connection. The range is specified by first.ip.in.range-last.ip.in.range. - The address or address range may be optionally followed by a port - range. When this is done, you must enclose the IPv6 address(es) in - square brackets. You may follow the port range with :random in which case assignment of ports - from the range will be random. + You may follow the port range with:random in which case assignment of ports + from the list will be random. random may also be specified by itself in + this column in which case random local port assignments are made for + the outgoing connections. Example: [2001:470:a:227::2]-[2001:470:a:227::10]:1000-1010 @@ -148,9 +148,6 @@ address range is specified and causes a client to be given the same source/destination IP pair. - Finally, you may also specify a comma-separated list of ranges - and/or addresses in this column. - This column may not contain DNS Names. Normally, Netfilter will attempt to retain the source port @@ -502,7 +499,7 @@ Your entry in the file will be: #INTERFACE SOURCE ADDRESS - eth0 2001:470:b:787::0/64 &eth0 + eth0 2001:470:b:787::0/64 - @@ -511,6 +508,6 @@ FILES - /etc/shorewall6/snat + /etc/shorewall6/masq