diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index d9834ed00..3a221a6c1 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -2637,9 +2637,12 @@ sub initialize_chain_table($) {
# As new targets (Actions, Macros and Manual Chains) are discovered, they are added to the table
#
%targets = ('ACCEPT' => STANDARD,
+ 'ACCEPT+' => STANDARD + NONAT,
'ACCEPT!' => STANDARD,
+ 'A_ACCEPT+' => STANDARD + NONAT + AUDIT,
'AUDIT' => STANDARD + AUDIT,
'A_ACCEPT' => STANDARD + AUDIT,
+ 'NONAT' => STANDARD + NONAT + NATONLY,
'DROP' => STANDARD,
'DROP!' => STANDARD,
'A_DROP' => STANDARD + AUDIT,
@@ -2648,6 +2651,10 @@ sub initialize_chain_table($) {
'REJECT!' => STANDARD,
'A_REJECT' => STANDARD + AUDIT,
'A_REJECT!' => STANDARD + AUDIT,
+ 'DNAT' => NATRULE,
+ 'DNAT-' => NATRULE + NATONLY,
+ 'REDIRECT' => NATRULE + REDIRECT,
+ 'REDIRECT-' => NATRULE + REDIRECT + NATONLY,
'LOG' => STANDARD + LOGRULE,
'CONTINUE' => STANDARD,
'CONTINUE!' => STANDARD,
diff --git a/Shorewall/Perl/Shorewall/Compiler.pm b/Shorewall/Perl/Shorewall/Compiler.pm
index 8a936294a..89c2d8341 100644
--- a/Shorewall/Perl/Shorewall/Compiler.pm
+++ b/Shorewall/Perl/Shorewall/Compiler.pm
@@ -807,7 +807,7 @@ sub compiler {
#
# Setup Nat
#
- setup_nat;
+ setup_nat if $family == F_IPV4;
#
# Setup NETMAP
#
diff --git a/Shorewall/Perl/Shorewall/Nat.pm b/Shorewall/Perl/Shorewall/Nat.pm
index a9d4b590e..4e4a80af2 100644
--- a/Shorewall/Perl/Shorewall/Nat.pm
+++ b/Shorewall/Perl/Shorewall/Nat.pm
@@ -44,11 +44,13 @@ our $VERSION = 'MODULEVERSION';
our @addresses_to_add;
our %addresses_to_add;
+our $family;
#
# Called by the compiler
#
-sub initialize() {
+sub initialize($) {
+ $family = shift;
@addresses_to_add = ();
%addresses_to_add = ();
}
@@ -61,7 +63,7 @@ sub process_one_masq1( $$$$$$$$$$ )
my ($interfacelist, $networks, $addresses, $proto, $ports, $ipsec, $mark, $user, $condition, $origdest ) = @_;
my $pre_nat;
- my $add_snat_aliases = $config{ADD_SNAT_ALIASES};
+ my $add_snat_aliases = $family == F_IPV4 && $config{ADD_SNAT_ALIASES};
my $destnets = '';
my $baserule = '';
@@ -72,28 +74,30 @@ sub process_one_masq1( $$$$$$$$$$ )
#
# Parse the remaining part of the INTERFACE column
#
- if ( $interfacelist =~ /^([^:]+)::([^:]*)$/ ) {
- $add_snat_aliases = 0;
- $destnets = $2;
- $interfacelist = $1;
- } elsif ( $interfacelist =~ /^([^:]+:[^:]+):([^:]+)$/ ) {
- $destnets = $2;
- $interfacelist = $1;
- } elsif ( $interfacelist =~ /^([^:]+):$/ ) {
- $add_snat_aliases = 0;
- $interfacelist = $1;
- } elsif ( $interfacelist =~ /^([^:]+):([^:]*)$/ ) {
- my ( $one, $two ) = ( $1, $2 );
- if ( $2 =~ /\./ || $2 =~ /^%/ ) {
- $interfacelist = $one;
- $destnets = $two;
+ if ( $family == F_IPV4 ) {
+ if ( $interfacelist =~ /^([^:]+)::([^:]*)$/ ) {
+ $add_snat_aliases = 0;
+ $destnets = $2;
+ $interfacelist = $1;
+ } elsif ( $interfacelist =~ /^([^:]+:[^:]+):([^:]+)$/ ) {
+ $destnets = $2;
+ $interfacelist = $1;
+ } elsif ( $interfacelist =~ /^([^:]+):$/ ) {
+ $add_snat_aliases = 0;
+ $interfacelist = $1;
+ } elsif ( $interfacelist =~ /^([^:]+):([^:]*)$/ ) {
+ my ( $one, $two ) = ( $1, $2 );
+ if ( $2 =~ /\./ || $2 =~ /^%/ ) {
+ $interfacelist = $one;
+ $destnets = $two;
+ }
}
}
#
# If there is no source or destination then allow all addresses
#
- $networks = ALLIPv4 if $networks eq '-';
- $destnets = ALLIPv4 if $destnets eq '-';
+ $networks = ALLIP if $networks eq '-';
+ $destnets = ALLIP if $destnets eq '-';
#
# Handle IPSEC options, if any
@@ -162,6 +166,7 @@ sub process_one_masq1( $$$$$$$$$$ )
#
if ( $addresses ne '-' ) {
if ( $addresses eq 'random' ) {
+ fatal_error 'Invalid IPv6 address (random)' if $family == F_IPV6;
$randomize = '--random ';
} else {
$addresses =~ s/:persistent$// and $persistent = ' --persistent ';
@@ -187,7 +192,9 @@ sub process_one_masq1( $$$$$$$$$$ )
$add_snat_aliases = 0;
} else {
my $addrlist = '';
- for my $addr ( split_list $addresses , 'address' ) {
+ my @addrs = split_list $addresses, 'address';
+
+ for my $addr ( @addrs ) {
if ( $addr =~ /^([&%])(.+)$/ ) {
my ( $type, $interface ) = ( $1, $2 );
$target = 'SNAT ';
@@ -199,22 +206,57 @@ sub process_one_masq1( $$$$$$$$$$ )
} else {
$addrlist .= '--to-source ' . record_runtime_address( $type, $interface );
}
- } elsif ( $addr =~ /^.*\..*\..*\./ ) {
- $target = 'SNAT ';
- my ($ipaddr, $rest) = split ':', $addr;
- if ( $ipaddr =~ /^(.+)-(.+)$/ ) {
- validate_range( $1, $2 );
+ } elsif ( $family == F_IPV4 ) {
+ if ( $addr =~ /^.*\..*\..*\./ ) {
+ $target = 'SNAT ';
+ my ($ipaddr, $rest) = split ':', $addr;
+ if ( $ipaddr =~ /^(.+)-(.+)$/ ) {
+ validate_range( $1, $2 );
+ } else {
+ validate_address $ipaddr, 0;
+ }
+ $addrlist .= "--to-source $addr ";
+ $exceptionrule = do_proto( $proto, '', '' ) if $addr =~ /:/;
} else {
- validate_address $ipaddr, 0;
+ my $ports = $addr;
+ $ports =~ s/^://;
+ validate_portpair1( $proto, $ports );
+ $addrlist .= "--to-ports $ports ";
+ $exceptionrule = do_proto( $proto, '', '' );
}
- $addrlist .= "--to-source $addr ";
- $exceptionrule = do_proto( $proto, '', '' ) if $addr =~ /:/;
} else {
- my $ports = $addr;
- $ports =~ s/^://;
- validate_portpair1( $proto, $ports );
- $addrlist .= "--to-ports $ports ";
- $exceptionrule = do_proto( $proto, '', '' );
+ fatal_error "Only one IPv6 ADDRESS may be specified" if @addrs > 1;
+
+ $target = 'SNAT ';
+
+ if ( $addr =~ /^\[/ ) {
+ #
+ # Can have ports specified
+ #
+ my $ports;
+
+ if ( $addr =~ s/:([^]]+)$// ) {
+ $ports = $1;
+ }
+
+ fatal_error "Invalid IPv6 Address ($addr)" unless $addr =~ /^\[(.+)\]$/;
+
+ $addr = $1;
+
+ if ( $addr =~ /^(.+)-(.+)$/ ) {
+ validate_range( $1, $2 );
+ } else {
+ validate_address $addr, 0;
+ }
+
+ $addrlist .= "--to-source $addr ";
+
+ if ( supplied $ports ) {
+ validate_portpair( $proto, $ports );
+ $exceptionrule = do_proto( $proto, '', '' );
+ $addrlist .= "--toports $ports ";
+ }
+ }
}
}
@@ -225,6 +267,7 @@ sub process_one_masq1( $$$$$$$$$$ )
$target .= $randomize;
$target .= $persistent;
} else {
+ fatal_error "IPv6 does does not support MASQUERADE -- you must use SNAT" if $family == F_IPV6;
$add_snat_aliases = 0;
}
#
@@ -597,9 +640,18 @@ sub handle_nat_rule( $$$$$$$$$$$$ ) {
if ( $server eq '' ) {
fatal_error "A server and/or port must be specified in the DEST column in $action rules" unless $serverport;
} elsif ( $server =~ /^(.+)-(.+)$/ ) {
- validate_range( $1, $2 );
+ if ( $family == F_IPV4 ) {
+ validate_range( $1, $2 );
+ } else {
+ my ( $addr1, $addr2 ) = ( $1, $2 );
+ $addr1 = $1 if $addr1 =~ /^\[(.+)\]$/;
+ $addr2 = $1 if $addr2 =~ /^\[(.+)\]$/;
+ validate_range( $addr1, $addr2 );
+ $server = join '-', $addr1, $addr2
+ }
} else {
unless ( $server eq ALLIP ) {
+ $server = $1 if $family == F_IPV6 && $server =~ /^\[(.+)\]$/;
my @servers = validate_address $server, 1;
$server = join ',', @servers;
}
@@ -609,8 +661,15 @@ sub handle_nat_rule( $$$$$$$$$$$$ ) {
$target = $action;
if ( $server ) {
$serverport = ":$serverport" if $serverport;
- for my $serv ( split /,/, $server ) {
- $target .= " --to-destination ${serv}${serverport}";
+ if ( $family == F_IPV4 ) {
+ for my $serv ( split /,/, $server ) {
+ $target .= " --to-destination ${serv}${serverport}";
+ }
+ } else {
+ for my $serv ( split /,/, $server ) {
+ $serv =~ s/-/]-[/; #In case this is a range.
+ $target .= " --to-destination [${serv}]${serverport}";
+ }
}
} else {
$target .= " --to-destination :$serverport";
diff --git a/Shorewall6/configfiles/masq b/Shorewall6/configfiles/masq
new file mode 100644
index 000000000..c8b582bb6
--- /dev/null
+++ b/Shorewall6/configfiles/masq
@@ -0,0 +1,11 @@
+#
+# Shorewall6 version 4 - Masq file
+#
+# For information about entries in this file, type "man shorewall6-masq"
+#
+# The manpage is also online at
+# http://www.shorewall.net/manpages6/shorewall6-masq.html
+#
+########################################################################################################################
+#INTERFACE SOURCE ADDRESS PROTO PORT(S) IPSEC MARK USER/ SWITCH ORIGINAL
+# GROUP DEST
diff --git a/Shorewall6/manpages/shorewall6-masq.xml b/Shorewall6/manpages/shorewall6-masq.xml
new file mode 100644
index 000000000..1c6fc5830
--- /dev/null
+++ b/Shorewall6/manpages/shorewall6-masq.xml
@@ -0,0 +1,533 @@
+
+
+
+
+ shorewall6-masq
+
+ 5
+
+
+
+ masq
+
+ Shorewall6 SNAT definition file
+
+
+
+
+ /etc/shorewall/masq
+
+
+
+
+ Description
+
+ Use this file to define Source NAT (SNAT).
+
+
+ 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.
+
+
+
+ If you have more than one ISP link, adding entries to this file
+ will not force connections to go out
+ through a particular link. You must use entries in shorewall6-rtrules(5) or
+ PREROUTING entries in shorewall-tcrules(5) to do
+ that.
+
+
+ The columns in the file are as follows.
+
+
+
+ INTERFACE:DEST - {[+]interfacelist|[?]COMMENT}
+
+
+ Outgoing interfacelist. This may be a
+ comma-separated list of interface names. This is usually your
+ internet interface.
+
+ Each interface must match an entry in shorewall6-interfaces(5).
+ Shorewall allows loose matches to wildcard entries in shorewall6-interfaces(5).
+ For example, ppp0 in this
+ file will match a shorewall6-interfaces(5)
+ entry that defines ppp+.
+
+ Where more that
+ one internet provider share a single interface, the provider
+ is specified by including the provider name or number in
+ parentheses:
+
+ eth0(Avvanta)
+
+ In that case, you will want to specify the interfaces's
+ address for that provider in the ADDRESS column.
+
+ The interface may be qualified by adding the character ":"
+ followed by a comma-separated list of destination host or subnet
+ addresses to indicate that you only want to change the source IP
+ address for packets being sent to those particular destinations.
+ Exclusion is allowed (see shorewall-exclusion(5)) as
+ are ipset names preceded by a plus sign '+';
+
+ If you wish to inhibit the action of ADD_SNAT_ALIASES for this
+ entry then include the ":" but omit the digit:
+
+ eth0(Avvanta):
+ eth2::192.0.2.32/27
+
+ Normally Masq/SNAT rules are evaluated after those for
+ one-to-one NAT (defined in shorewall-nat(5)). If you want the
+ rule to be applied before one-to-one NAT rules, prefix the interface
+ name with "+":
+
+ +eth0
+ +eth0:192.0.2.32/27
+ +eth0:2
+
+ This feature should only be required if you need to insert
+ rules in this file that preempt entries in shorewall-nat(5).
+
+ Comments may be attached to Netfilter rules generated from
+ entries in this file through the use of COMMENT lines. These lines
+ begin with the word COMMENT; the remainder of the line is treated as
+ a comment which is attached to subsequent rules until another
+ COMMENT line is found or until the end of the file is reached. To
+ stop adding comments to rules, use a line with only the word
+ COMMENT.
+
+
+ Beginning with Shorewall 4.5.11, ?COMMENT is a synonym for
+ COMMENT and is preferred.
+
+
+
+
+
+ SOURCE -
+ {interface|address[,address][exclusion]}
+
+
+ Set of hosts that you wish to SNAT; one or more host or
+ network addresses separated by comma. You may use ipset names
+ preceded by a plus sign (+) to specify a set of hosts.
+
+
+
+
+ ADDRESS -
+ {address-or-address-range[,address-or-address-range]...][:lowport-highport][:random][:persistent]|}
+
+
+ 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.
+
+ 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.
+
+ Example:
+ [2001:470:a:227::2]-[2001:470:a:227::10]::1000-1010
+
+ You may follow the port range (or :random) with :persistent. This is only useful when an
+ 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
+ number. You may cause netfilter to remap the source port by
+ following an address or range (if any) by ":" and a port range with
+ the format
+ lowport-highport. If this
+ is done, you must specify "tcp" or "udp" in the PROTO column.
+
+ Examples:
+
+ [2001:470:a:787::2]:5000-6000
+
+ If you simply place NONAT in
+ this column, no rewriting of the source IP address or port number
+ will be performed. This is useful if you want particular traffic to
+ be exempt from the entries that follow in the file.
+
+
+
+
+ PROTO (Optional) - {-|[!]{protocol-name|protocol-number}[,...]}
+
+
+ If you wish to restrict this entry to a particular protocol
+ then enter the protocol name (from protocols(5)) or number
+ here.
+
+ Beginning with Shorewall 4.5.12, this column can accept a
+ comma-separated list of protocols.
+
+
+
+
+ PORT(S) (Optional) -
+ [[!]port-name-or-number[,port-name-or-number]...]
+
+
+ If the PROTO column specifies TCP (6), UDP (17), DCCP (33),
+ SCTP (132) or UDPLITE (136) then you may list one or more port
+ numbers (or names from services(5)) or port ranges separated by
+ commas.
+
+ Port ranges are of the form
+ lowport:highport.
+
+
+
+
+ IPSEC (Optional) -
+ [option[,option]...]
+
+
+ If you specify a value other than "-" in this column, you must
+ be running kernel 2.6 and your kernel and iptables must include
+ policy match support.
+
+ Comma-separated list of options from the following. Only
+ packets that will be encrypted via an SA that matches these options
+ will have their source address changed.
+
+
+
+ reqid=number
+
+
+ where number is specified using
+ setkey(8) using the 'unique:number option
+ for the SPD level.
+
+
+
+
+ spi=<number>
+
+
+ where number is the SPI of the SA
+ used to encrypt/decrypt packets.
+
+
+
+
+ proto=ah|esp|ipcomp
+
+
+ IPSEC Encapsulation Protocol
+
+
+
+
+ mss=number
+
+
+ sets the MSS field in TCP packets
+
+
+
+
+ mode=transport|tunnel
+
+
+ IPSEC mode
+
+
+
+
+ tunnel-src=address[/mask]
+
+
+ only available with mode=tunnel
+
+
+
+
+ tunnel-dst=address[/mask]
+
+
+ only available with mode=tunnel
+
+
+
+
+ strict
+
+
+ Means that packets must match all rules.
+
+
+
+
+ next
+
+
+ Separates rules; can only be used with strict
+
+
+
+
+ yes
+
+
+ When used by itself, causes all traffic that will be
+ encrypted/encapsulated to match the rule.
+
+
+
+
+
+
+
+ MARK - [!]value[/mask][:C]
+
+
+ Defines a test on the existing packet or connection mark. The
+ rule will match only if the test returns true.
+
+ If you don't want to define a test but need to specify
+ anything in the following columns, place a "-" in this field.
+
+
+
+ !
+
+
+ Inverts the test (not equal)
+
+
+
+
+ value
+
+
+ Value of the packet or connection mark.
+
+
+
+
+ mask
+
+
+ A mask to be applied to the mark before testing.
+
+
+
+
+ :C
+
+
+ Designates a connection mark. If omitted, the packet
+ mark's value is tested.
+
+
+
+
+
+
+
+ USER/GROUP (Optional) -
+ [!][user-name-or-number][:group-name-or-number][+program-name]
+
+
+ Only locally-generated connections will match if this column
+ is non-empty.
+
+ When this column is non-empty, the rule matches only if the
+ program generating the output is running under the effective
+ user and/or group
+ specified (or is NOT running under that id if "!" is given).
+
+ Examples:
+
+
+
+ joe
+
+
+ program must be run by joe
+
+
+
+
+ :kids
+
+
+ program must be run by a member of the 'kids'
+ group
+
+
+
+
+ !:kids
+
+
+ program must not be run by a member of the 'kids'
+ group
+
+
+
+
+ +upnpd
+
+
+ #program named upnpd
+
+
+ The ability to specify a program name was removed from
+ Netfilter in kernel version 2.6.14.
+
+
+
+
+
+
+
+
+ SWITCH -
+ [!]switch-name[={0|1}]
+
+
+ Added in Shorewall 4.5.1 and allows enabling and disabling the
+ rule without requiring shorewall restart.
+
+ The rule is enabled if the value stored in
+ /proc/net/nf_condition/switch-name
+ is 1. The rule is disabled if that file contains 0 (the default). If
+ '!' is supplied, the test is inverted such that the rule is enabled
+ if the file contains 0.
+
+ Within the switch-name, '@0' and
+ '@{0}' are replaced by the name of the chain to which the rule is a
+ added. The switch-name (after '@...'
+ expansion) must begin with a letter and be composed of letters,
+ decimal digits, underscores or hyphens. Switch names must be 30
+ characters or less in length.
+
+ Switches are normally off. To
+ turn a switch on:
+
+
+ echo 1 >
+ /proc/net/nf_condition/switch-name
+
+
+ To turn it off again:
+
+
+ echo 0 >
+ /proc/net/nf_condition/switch-name
+
+
+ Switch settings are retained over shorewall
+ restart.
+
+ Beginning with Shoreawll 4.5.10, when the
+ switch-name is followed by
+ or , then the switch is
+ initialized to off or on respectively by the
+ start command. Other commands do not affect the
+ switch setting.
+
+
+
+
+ ORIGINAL DEST (origdest) -
+ [-|address[,address]...[exclusion]|exclusion]
+
+
+ (Optional) Added in Shorewall 4.5.6. This column may be
+ included and may contain one or more addresses (host or network)
+ separated by commas. Address ranges are not allowed. When this
+ column is supplied, rules are generated that require that the
+ original destination address matches one of the listed addresses. It
+ is useful for specifying that SNAT should occur only for connections
+ that were acted on by a DNAT when they entered the firewall.
+
+
+
+
+
+
+ Examples
+
+
+
+ Example 1:
+
+
+ You have a simple 'masquerading' setup where eth0 connects to
+ a DSL or cable modem and eth1 connects to your local network with
+ subnet 2001:470:b:787::0/64
+
+ Your entry in the file will be:
+
+ #INTERFACE SOURCE ADDRESS
+ eth0 2001:470:b:787::0/64 ð0
+
+
+
+
+
+
+ FILES
+
+ /etc/shorewall6/masq
+
+
diff --git a/Shorewall6/manpages/shorewall6-rules.xml b/Shorewall6/manpages/shorewall6-rules.xml
index 5c88f0787..92cc36710 100644
--- a/Shorewall6/manpages/shorewall6-rules.xml
+++ b/Shorewall6/manpages/shorewall6-rules.xml
@@ -173,6 +173,19 @@
+
+ ACCEPT+
+
+
+ like ACCEPT but also excludes the connection from any
+ subsequent matching DNAT[-] or REDIRECT[-] rules.
+
+
+
ACCEPT!
@@ -333,6 +346,28 @@
+
+ DNAT
+
+
+ Forward the request to another system (and optionally
+ another port).
+
+
+
+
+ DNAT-
+
+
+ Advanced users only.
+
+ Like DNAT but only
+ generates the DNAT iptables
+ rule and not the companion ACCEPT rule.
+
+
+
DROP
@@ -470,6 +505,28 @@
+
+ REDIRECT
+
+
+ Redirect the request to a server running on the
+ firewall.
+
+
+
+
+ REDIRECT-
+
+
+ Advanced users only.
+
+ Like REDIRECT but only
+ generates the REDIRECT
+ iptables rule and not the companion ACCEPT rule.
+
+
+
REJECT