diff --git a/Shorewall-common/changelog.txt b/Shorewall-common/changelog.txt index 114348b36..8a08fbcc3 100644 --- a/Shorewall-common/changelog.txt +++ b/Shorewall-common/changelog.txt @@ -12,6 +12,8 @@ Changes in 4.1.4 5) Allow interface lists in the masq and nat files. +6) Allow loose match of interface names used in masq, nat and netmap. + Changes in 4.1.3 1) Fix NFLOG/ULOG upcasing problem. diff --git a/Shorewall-common/releasenotes.txt b/Shorewall-common/releasenotes.txt index 4cc73f9db..506cf9b62 100644 --- a/Shorewall-common/releasenotes.txt +++ b/Shorewall-common/releasenotes.txt @@ -138,6 +138,22 @@ Other changes in Shorewall 4.1.4. 206.124.146.178 eth0 192.168.1.3 206.124.146.178 wlan0 192.168.1.3 +4) Previously, the INTERFACE name used in the masq, nat and netmap + files had to exactly match the name of an interface from the + interfaces file. Beginning with Shorewall-perl 4.1.4, the + interface may loosely match a wildcard entry in the interfaces + file. + + Example: + + /etc/shorewall/interfaces: + + vpn tun+ + + /etc/shorewall/masq: + + tun1 192.168.4.0/24 + Migration Issues. 1) Previously, when HIGH_ROUTE_MARKS=Yes, Shorewall allowed non-zero diff --git a/Shorewall-perl/Shorewall/Nat.pm b/Shorewall-perl/Shorewall/Nat.pm index ac7092d1c..5b44a8024 100644 --- a/Shorewall-perl/Shorewall/Nat.pm +++ b/Shorewall-perl/Shorewall/Nat.pm @@ -196,7 +196,12 @@ sub setup_one_masq($$$$$$$) $rule .= "-m realm --realm $realm "; } - fatal_error "Unknown interface ($interface)" unless find_interface( $interface )->{root}; + fatal_error "Unknown interface ($interface)" unless my $interfaceref = known_interface( $interface ); + + unless ( $interfaceref->{root} ) { + $rule .= "-o $interface "; + $interface = $interfaceref->{name}; + } my $chainref = ensure_chain('nat', $pre_nat ? snat_chain $interface : masq_chain $interface); @@ -368,6 +373,16 @@ sub do_one_nat( $$$$$ ) my $policyin = ''; my $policyout = ''; + my $rulein = ''; + my $ruleout = ''; + + fatal_error "Unknown interface ($interface)" unless my $interfaceref = known_interface( $interface ); + + unless ( $interfaceref->{root} ) { + $rulein = "-i $interface "; + $ruleout = "-o $interface "; + $interface = $interfaceref->{name}; + } if ( $capabilities{POLICY_MATCH} ) { $policyin = ' -m policy --pol none --dir in'; @@ -391,8 +406,8 @@ sub do_one_nat( $$$$$ ) add_nat_rule 'nat_in' , "-d $external $policyin -j DNAT --to-destination $internal"; add_nat_rule 'nat_out' , "-s $internal $policyout -j SNAT --to-source $external"; } else { - add_nat_rule input_chain( $interface ) , "-d $external $policyin -j DNAT --to-destination $internal"; - add_nat_rule output_chain( $interface ) , "-s $internal $policyout -j SNAT --to-source $external"; + add_nat_rule input_chain( $interface ) , $rulein . "-d $external $policyin -j DNAT --to-destination $internal"; + add_nat_rule output_chain( $interface ) , $ruleout . "-s $internal $policyout -j SNAT --to-source $external"; } add_nat_rule 'OUTPUT' , "-d $external $policyout -j DNAT --to-destination $internal " if $localnat; @@ -449,20 +464,32 @@ sub setup_netmap() { while ( read_a_line ) { - my ( $type, $net1, $interface, $net2 ) = split_line 4, 4, 'netmap file'; + my ( $type, $net1, $interfacelist, $net2 ) = split_line 4, 4, 'netmap file'; - fatal_error "Unknown Interface ($interface)" unless known_interface $interface; + for my $interface ( split /,/, $interfacelist ) { + + my $rulein = ''; + my $ruleout = ''; + my $iface = $interface; + + fatal_error "Unknown interface ($interface)" unless my $interfaceref = find_interface( $interface ); + + unless ( $interfaceref->{root} ) { + $rulein = "-i $interface "; + $ruleout = "-o $interface "; + $interface = $interfaceref->{name}; + } - if ( $type eq 'DNAT' ) { - add_rule ensure_chain( 'nat' , input_chain $interface ) , "-d $net1 -j NETMAP --to $net2"; - } elsif ( $type eq 'SNAT' ) { - add_rule ensure_chain( 'nat' , output_chain $interface ) , "-s $net1 -j NETMAP --to $net2"; - } else { - fatal_error "Invalid type ($type)"; + if ( $type eq 'DNAT' ) { + add_rule ensure_chain( 'nat' , input_chain $interface ) , $rulein . "-d $net1 -j NETMAP --to $net2"; + } elsif ( $type eq 'SNAT' ) { + add_rule ensure_chain( 'nat' , output_chain $interface ) , $ruleout . "-s $net1 -j NETMAP --to $net2"; + } else { + fatal_error "Invalid type ($type)"; + } + + progress_message " Network $net1 on $iface mapped to $net2 ($type)"; } - - progress_message " Network $net1 on $interface mapped to $net2 ($type)"; - } } diff --git a/Shorewall-perl/Shorewall/Zones.pm b/Shorewall-perl/Shorewall/Zones.pm index 96cefe971..daa29da0b 100644 --- a/Shorewall-perl/Shorewall/Zones.pm +++ b/Shorewall-perl/Shorewall/Zones.pm @@ -121,7 +121,8 @@ our %reservedName = ( all => 1, # # @interfaces lists the interface names in the order that they appear in the interfaces file. # -# %interfaces { => { root => +# %interfaces { => { name => +# root => # options => { = , # ... # } @@ -643,6 +644,8 @@ sub validate_interfaces_file( $ ) $interfaces{$interface}{bridge} = $interface; } + $interfaces{$interface}{name} = $interface; + my $wildcard = 0; if ( $interface =~ /\+$/ ) { @@ -772,19 +775,19 @@ sub validate_interfaces_file( $ ) sub known_interface($) { my $interface = $_[0]; - - return 1 if $interfaces{$interface}; + my $interfaceref = $interfaces{$interface}; + + return $interfaceref if $interfaceref; for my $i ( @interfaces ) { - my $interfaceref = $interfaces{$i}; + $interfaceref = $interfaces{$i}; my $val = $interfaceref->{root}; next if $val eq $i; if ( substr( $interface, 0, length $val ) eq $val ) { # - # Cache this result for future reference + # Cache this result for future reference. We set the 'name' to the name of the entry that appears in /etc/shorewall/interfaces. # - $interfaces{$interface} = { options => $interfaceref->{options}, bridge => $interfaceref->{bridge} }; - return 1; + return $interfaces{$interface} = { options => $interfaceref->{options}, bridge => $interfaceref->{bridge} , name => $i }; } } diff --git a/Shorewall-shell/lib.nat b/Shorewall-shell/lib.nat index 3e0ff50ac..215855588 100644 --- a/Shorewall-shell/lib.nat +++ b/Shorewall-shell/lib.nat @@ -227,7 +227,7 @@ setup_masq() build_exclusion_chain newchain nat "$nomasq" "$destnets" if [ -n "$networks" ]; then - for s in $networks; do + for s in $(separate_list networks); do addnatrule $chain $(source_ip_range $s) $proto $ports $mark $policy -j $newchain done networks= @@ -261,7 +261,7 @@ __EOF__ build_exclusion_chain newchain nat $nomasq if [ -n "$networks" ]; then - for s in $networks; do + for s in $(separate_list $networks); do for destnet in $(separate_list $destnets); do addnatrule $chain $(both_ip_ranges $s $destnet) $proto $ports $mark $policy -j $newchain done @@ -388,7 +388,7 @@ __EOF__ fi if [ -n "$networks" ]; then - for network in $networks; do + for network in $(separate_list $networks); do for destnet in $(separate_list $destnets); do addnatrule $chain $(both_ip_ranges $network $destnet) $proto $ports $mark $policy -j $target $addrlist done diff --git a/manpages/shorewall-masq.xml b/manpages/shorewall-masq.xml index c5e685774..d4e0f54ea 100644 --- a/manpages/shorewall-masq.xml +++ b/manpages/shorewall-masq.xml @@ -59,6 +59,18 @@ the only use for the alias name; it may not appear in any other place in your Shorewall configuration. + Each interface must match an entry in shorewall-interfaces(5). + Prior to Shorewall 4.1.4, this must be an exact match. + Shorewall-perl 4.1.4 and later allow loose matches to wildcard + entries in shorewall-interfaces(5). For + example, ppp0 in this file + will match a shorewall-interfaces(5) + entry that defines ppp+. + 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 diff --git a/manpages/shorewall-nat.xml b/manpages/shorewall-nat.xml index 962aa689f..9dbe3ffcd 100644 --- a/manpages/shorewall-nat.xml +++ b/manpages/shorewall-nat.xml @@ -73,6 +73,18 @@ cannot use it anwhere else in your Shorewall configuration. + Each interface must match an entry in shorewall-interfaces(5). + Prior to Shorewall 4.1.4, this must be an exact match. + Shorewall-perl 4.1.4 and later allow loose matches to wildcard + entries in shorewall-interfaces(5). For + example, ppp0 in this file + will match a shorewall-interfaces(5) + entry that defines ppp+. + Prior to Shorewall 4.1.4, interfacelist must be a single interface name. Beginning with Shorewall-perl 4.1.4, Shorewall-perl users may diff --git a/manpages/shorewall-netmap.xml b/manpages/shorewall-netmap.xml index 0028e689b..fa8b14383 100644 --- a/manpages/shorewall-netmap.xml +++ b/manpages/shorewall-netmap.xml @@ -66,7 +66,16 @@ The name of a network interface. The interface must be defined in shorewall-interfaces(5). + url="shorewall-interfaces.html">shorewall-interfaces(5) + Prior to Shorewall 4.1.4, this must be an exact match. + Shorewall-perl 4.1.4 and later allow loose matches to wildcard + entries in shorewall-interfaces(5). For + example, ppp0 in this file + will match a shorewall-interfaces(8) + entry that defines ppp+. diff --git a/manpages/shorewall-rules.xml b/manpages/shorewall-rules.xml index 8743c5774..65996adf3 100644 --- a/manpages/shorewall-rules.xml +++ b/manpages/shorewall-rules.xml @@ -684,9 +684,10 @@ 1. MAC addresses are not allowed (this is a Netfilter restriction). - 2. In DNAT rules, only IP - addresses are allowed; no FQDNs or subnet addresses are - permitted. + 2.Prior to Shorewall 4.1.4, only IP addresses are allowed in + DNAT rules; no DNS names are + permitted. In no case may a network be specified as the + server. 3. You may not specify both an interface and an address.