diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index 6c66fa860..6a3ecc6ba 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -5573,32 +5573,56 @@ sub split_host_list( $;$ ) {
my @input = split_list $input, 'host';
- return @input unless $input =~ /\[/;
my $exclude = 0;
my @result;
- while ( @input ) {
- my $element = shift @input;
+ if ( $input =~ /\[/ ) {
+ while ( @input ) {
+ my $element = shift @input;
- if ( $element =~ /\[/ ) {
- while ( $element =~ tr/[/[/ > $element =~ tr/]/]/ ) {
- fatal_error "Missing ']' ($element)" unless @input;
- $element .= ( ',' . shift @input );
+ if ( $element =~ /\[/ ) {
+ while ( $element =~ tr/[/[/ > $element =~ tr/]/]/ ) {
+ fatal_error "Missing ']' ($element)" unless @input;
+ $element .= ( ',' . shift @input );
+ }
+
+ unless ( $loose ) {
+ fatal_error "Invalid host list ($input)" if $exclude && $element =~ /!/;
+ $exclude ||= $element =~ /^!/ || $element =~ /\]!/;
+ }
+
+ fatal_error "Mismatched [...] ($element)" unless $element =~ tr/[/[/ == $element =~ tr/]/]/;
+ } else {
+ $exclude ||= $element =~ /!/ unless $loose;
}
- unless ( $loose ) {
- fatal_error "Invalid host list ($input)" if $exclude && $element =~ /!/;
- $exclude ||= $element =~ /^!/ || $element =~ /\]!/;
- }
+ push @result, $element;
+ }
+ } else {
+ @result = @input;
+ }
- fatal_error "Mismatched [...] ($element)" unless $element =~ tr/[/[/ == $element =~ tr/]/]/;
- } else {
- $exclude ||= $element =~ /!/ unless $loose;
+ unless ( $config{DEFER_DNS_RESOLUTION} ) {
+ my @result1;
+
+ for ( @result ) {
+ if ( m|[-\+\[~/^&]| ) {
+ push @result1, $_;
+ } elsif ( /^.+\..+\./ ) {
+ /^(!)?(.*)$/;
+ if ( valid_address( $2 ) ) {
+ push @result1, $_;
+ } else {
+ push @result1, resolve_dnsname( $_ );
+ }
+ } else {
+ push @result1, $_;
+ }
}
- push @result, $element;
+ return @result1;
}
@result;
diff --git a/Shorewall/Perl/Shorewall/Config.pm b/Shorewall/Perl/Shorewall/Config.pm
index e47e2a300..8ba7a3170 100644
--- a/Shorewall/Perl/Shorewall/Config.pm
+++ b/Shorewall/Perl/Shorewall/Config.pm
@@ -765,6 +765,7 @@ sub initialize( $;$$) {
RESTORE_ROUTEMARKS => undef,
IGNOREUNKNOWNVARIABLES => undef,
WARNOLDCAPVERSION => undef,
+ DEFER_DNS_RESOLUTION => undef,
#
# Packet Disposition
#
@@ -5060,6 +5061,7 @@ sub get_configuration( $$$$ ) {
default_yes_no 'RESTORE_ROUTEMARKS' , 'Yes';
default_yes_no 'IGNOREUNKNOWNVARIABLES' , 'Yes';
default_yes_no 'WARNOLDCAPVERSION' , 'Yes';
+ default_yes_no 'DEFER_DNS_RESOLUTION' , 'Yes';
$config{IPSET} = '' if supplied $config{IPSET} && $config{IPSET} eq 'ipset';
diff --git a/Shorewall/Perl/Shorewall/IPAddrs.pm b/Shorewall/Perl/Shorewall/IPAddrs.pm
index ece7fc1f0..8a0d0721b 100644
--- a/Shorewall/Perl/Shorewall/IPAddrs.pm
+++ b/Shorewall/Perl/Shorewall/IPAddrs.pm
@@ -26,7 +26,7 @@
#
package Shorewall::IPAddrs;
require Exporter;
-use Shorewall::Config qw( :DEFAULT split_list require_capability in_hex8 numeric_value F_IPV4 F_IPV6 :protocols );
+use Shorewall::Config qw( :DEFAULT split_list require_capability in_hex8 numeric_value F_IPV4 F_IPV6 :protocols %config );
use Socket;
use strict;
@@ -49,6 +49,7 @@ our @EXPORT = ( qw( ALLIPv4
NILIP
ALL
+ valid_address
validate_address
validate_net
decompose_net
@@ -65,6 +66,7 @@ our @EXPORT = ( qw( ALLIPv4
nilip
rfc1918_networks
resolve_proto
+ resolve_dnsname
proto_name
validate_port
validate_portpair
@@ -90,6 +92,7 @@ our @nilip;
our $valid_address;
our $validate_address;
our $validate_net;
+our $resolve_dnsname;
our $validate_range;
our $validate_host;
our $family;
@@ -152,6 +155,21 @@ sub validate_4address( $$ ) {
defined wantarray ? wantarray ? @addrs : $addrs[0] : undef;
}
+sub resolve_4dnsname( $ ) {
+ my $net = $_[0];
+ my @addrs;
+
+ fatal_error "Unknown Host ($net)" unless @addrs = gethostbyname( $net );
+
+ shift @addrs for (1..4);
+ for ( @addrs ) {
+ $_ = ( inet_ntoa( $_ ) );
+ }
+
+ @addrs;
+}
+
+
sub decodeaddr( $ ) {
my $address = $_[0];
@@ -202,7 +220,8 @@ sub validate_4net( $$ ) {
fatal_error "Invalid IP address ($net)" unless valid_4address $net;
} else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net;
- validate_4address $net, $_[1];
+ my $net1 = validate_4address $net, $allow_name;
+ $net = $net1 unless $config{DEFER_DNS_RESOLUTION};
$vlsm = 32;
}
@@ -611,6 +630,21 @@ sub validate_6address( $$ ) {
defined wantarray ? wantarray ? @addrs : $addrs[0] : undef;
}
+sub resolve_6dnsname( $ ) {
+ my $net = $_[0];
+ my @addrs;
+
+ require Socket6;
+ fatal_error "Unknown Host ($net)" unless (@addrs = Socket6::gethostbyname2( $net, Socket6::AF_INET6()));
+
+ shift @addrs for (1..4);
+ for ( @addrs ) {
+ $_ = Socket6::inet_ntop( Socket6::AF_INET6(), $_ );
+ }
+
+ @addrs;
+}
+
sub validate_6net( $$ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
my $allow_name = $_[0];
@@ -635,7 +669,8 @@ sub validate_6net( $$ ) {
fatal_error "Invalid IPv6 address ($net)" unless valid_6address $net;
} else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/';
- validate_6address $net, $allow_name;
+ my $net1 = validate_6address $net, $allow_name;
+ $net = $net1 unless $config{DEFER_DNS_RESOLUTION};
$vlsm = 128;
}
@@ -778,6 +813,10 @@ sub validate_net ( $$ ) {
$validate_net->(@_);
}
+sub resolve_dnsname( $ ) {
+ $resolve_dnsname->(@_);
+}
+
sub validate_range ($$ ) {
$validate_range->(@_);
}
@@ -809,6 +848,7 @@ sub initialize( $ ) {
$validate_net = \&validate_4net;
$validate_range = \&validate_4range;
$validate_host = \&validate_4host;
+ $resolve_dnsname = \&resolve_4dnsname;
} else {
$allip = ALLIPv6;
@allip = @allipv6;
@@ -819,6 +859,7 @@ sub initialize( $ ) {
$validate_net = \&validate_6net;
$validate_range = \&validate_6range;
$validate_host = \&validate_6host;
+ $resolve_dnsname = \&resolve_6dnsname;
}
}
diff --git a/Shorewall/Perl/Shorewall/Providers.pm b/Shorewall/Perl/Shorewall/Providers.pm
index b3fe726f6..ca5da94d0 100644
--- a/Shorewall/Perl/Shorewall/Providers.pm
+++ b/Shorewall/Perl/Shorewall/Providers.pm
@@ -1089,7 +1089,7 @@ sub add_a_route( ) {
}
fatal_error 'DEST must be specified' if $dest eq '-';
- $dest = validate_net ( $dest, 1 );
+ $dest = validate_net ( $dest, 0 );
validate_address ( $gateway, 1 ) if $gateway ne '-';
diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm
index fc4021f4e..37ba14e67 100644
--- a/Shorewall/Perl/Shorewall/Zones.pm
+++ b/Shorewall/Perl/Shorewall/Zones.pm
@@ -1200,7 +1200,7 @@ sub process_interface( $$ ) {
$hostoptions{broadcast} = 1;
} elsif ( $option eq 'sfilter' ) {
$filterref = [ split_list $value, 'address' ];
- $_ = validate_net( $_, 1) for @{$filterref}
+ validate_net( $_, 0) for @{$filterref}
} else {
assert(0);
}
diff --git a/Shorewall/Samples/Universal/shorewall.conf b/Shorewall/Samples/Universal/shorewall.conf
index 93c02f110..f3205cba3 100644
--- a/Shorewall/Samples/Universal/shorewall.conf
+++ b/Shorewall/Samples/Universal/shorewall.conf
@@ -132,6 +132,8 @@ CLEAR_TC=Yes
COMPLETE=Yes
+DEFER_DNS_RESOLUTION=Yes
+
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes
diff --git a/Shorewall/Samples/one-interface/shorewall.conf b/Shorewall/Samples/one-interface/shorewall.conf
index b446ff6f0..4bd67b5b7 100644
--- a/Shorewall/Samples/one-interface/shorewall.conf
+++ b/Shorewall/Samples/one-interface/shorewall.conf
@@ -143,6 +143,8 @@ CLEAR_TC=Yes
COMPLETE=No
+DEFER_DNS_RESOLUTION=Yes
+
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes
diff --git a/Shorewall/Samples/three-interfaces/shorewall.conf b/Shorewall/Samples/three-interfaces/shorewall.conf
index ddd75d2e3..344fe7fb0 100644
--- a/Shorewall/Samples/three-interfaces/shorewall.conf
+++ b/Shorewall/Samples/three-interfaces/shorewall.conf
@@ -141,6 +141,8 @@ CLEAR_TC=Yes
COMPLETE=No
+DEFER_DNS_RESOLUTION=Yes
+
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes
diff --git a/Shorewall/Samples/two-interfaces/shorewall.conf b/Shorewall/Samples/two-interfaces/shorewall.conf
index 5a7f64f26..b7ecf7663 100644
--- a/Shorewall/Samples/two-interfaces/shorewall.conf
+++ b/Shorewall/Samples/two-interfaces/shorewall.conf
@@ -144,6 +144,8 @@ CLEAR_TC=Yes
COMPLETE=No
+DEFER_DNS_RESOLUTION=Yes
+
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes
diff --git a/Shorewall/configfiles/shorewall.conf b/Shorewall/configfiles/shorewall.conf
index 6ee7b7d45..d49366214 100644
--- a/Shorewall/configfiles/shorewall.conf
+++ b/Shorewall/configfiles/shorewall.conf
@@ -132,6 +132,8 @@ CLEAR_TC=Yes
COMPLETE=No
+DEFER_DNS_RESOLUTION=Yes
+
DELETE_THEN_ADD=Yes
DETECT_DNAT_IPADDRS=No
diff --git a/Shorewall/manpages/shorewall-arprules.xml b/Shorewall/manpages/shorewall-arprules.xml
index f78e56b4d..f3fdedbea 100644
--- a/Shorewall/manpages/shorewall-arprules.xml
+++ b/Shorewall/manpages/shorewall-arprules.xml
@@ -161,7 +161,7 @@
-++ If CONFIG_PATH is not given or if it is set to the empty value + then the contents of /usr/share/shorewall/configpath are used. As + released from shorewall.net, that file sets the CONFIG_PATH to + /etc/shorewall:/usr/share/shorewall but your particular distribution + may set it differently. See the output of shorewall show config for + the default on your system. + + -If CONFIG_PATH is not given or if it is set to the empty - value then the contents of /usr/share/shorewall/configpath are - used. As released from shorewall.net, that file sets the - CONFIG_PATH to /etc/shorewall:/usr/share/shorewall but your - particular distribution may set it differently. See the output of - shorewall show config for the default on your system. ++ - DEFER_DNS_RESOLUTION= [Yes |No ]Note that the setting in /usr/share/shorewall/configpath is - always used to locate shorewall.conf. -
-+If CONFIG_PATH is not given or if it is set to the empty - value then the contents of /usr/share/shorewall6/configpath are - used. As released from shorewall.net, that file sets the - CONFIG_PATH to - /etc/shorewall6:/usr/share/shorewall6:/usr/share/shorewall but - your particular distribution may set it differently. See the - output of shorewall6 show config for the default on your - system. +If CONFIG_PATH is not given or if it is set to the empty value + then the contents of /usr/share/shorewall6/configpath are used. As + released from shorewall.net, that file sets the CONFIG_PATH to + /etc/shorewall6:/usr/share/shorewall6:/usr/share/shorewall but your + particular distribution may set it differently. See the output of + shorewall6 show config for the default on your system. + + -Note that the setting in /usr/share/shorewall6/configpath is - always used to locate shorewall6.conf. -