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 @@ ipaddress - is an IPv4 address. + is an IPv4 address. DNS names are not allowed. @@ -224,7 +224,7 @@ ipaddress - is an IPv4 address or a MAC address. + is an IPv4 address. DNS Names are not allowed. diff --git a/Shorewall/manpages/shorewall.conf.xml b/Shorewall/manpages/shorewall.conf.xml index 832c98da2..9cbea2963 100644 --- a/Shorewall/manpages/shorewall.conf.xml +++ b/Shorewall/manpages/shorewall.conf.xml @@ -539,19 +539,31 @@ -
- + 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. -
+ + Added in Shorewall 4.5.12. When set to 'Yes' (the default), + DNS names are validated in the compiler and then passed on to the + generated script where they are resolved by iptables-restore. This + is an advantage if you use AUTOMAKE=Yes and the IP address + associated with the DNS name is subject to change. When + DEFER_DNS_RESOLUTION=No, DNS names are converted into IP addresses + by the compiler. This has the advantage that when AUTOMAKE=Yes, the + start and restart commands + will succeed even if no DNS server is reachable (assuming that the + configuration hasn't changed since the compiled script was last + generated). diff --git a/Shorewall6/Samples6/Universal/shorewall6.conf b/Shorewall6/Samples6/Universal/shorewall6.conf index b0ad19f0f..1c554babf 100644 --- a/Shorewall6/Samples6/Universal/shorewall6.conf +++ b/Shorewall6/Samples6/Universal/shorewall6.conf @@ -125,6 +125,8 @@ CLEAR_TC=Yes COMPLETE=Yes +DEFER_DNS_RESOLUTION=Yes + DELETE_THEN_ADD=Yes DONT_LOAD= diff --git a/Shorewall6/Samples6/one-interface/shorewall6.conf b/Shorewall6/Samples6/one-interface/shorewall6.conf index ba43a0e8f..219f4ac8a 100644 --- a/Shorewall6/Samples6/one-interface/shorewall6.conf +++ b/Shorewall6/Samples6/one-interface/shorewall6.conf @@ -125,6 +125,8 @@ CLEAR_TC=Yes COMPLETE=No +DEFER_DNS_RESOLUTION=Yes + DELETE_THEN_ADD=Yes DONT_LOAD= diff --git a/Shorewall6/Samples6/three-interfaces/shorewall6.conf b/Shorewall6/Samples6/three-interfaces/shorewall6.conf index c0edfa88e..b822f3ac2 100644 --- a/Shorewall6/Samples6/three-interfaces/shorewall6.conf +++ b/Shorewall6/Samples6/three-interfaces/shorewall6.conf @@ -125,6 +125,8 @@ CLEAR_TC=Yes COMPLETE=No +DEFER_DNS_RESOLUTION=Yes + DELETE_THEN_ADD=Yes DONT_LOAD= diff --git a/Shorewall6/Samples6/two-interfaces/shorewall6.conf b/Shorewall6/Samples6/two-interfaces/shorewall6.conf index b65becb9d..6a7131407 100644 --- a/Shorewall6/Samples6/two-interfaces/shorewall6.conf +++ b/Shorewall6/Samples6/two-interfaces/shorewall6.conf @@ -125,6 +125,8 @@ CLEAR_TC=Yes COMPLETE=No +DEFER_DNS_RESOLUTION=Yes + DELETE_THEN_ADD=Yes DONT_LOAD= diff --git a/Shorewall6/configfiles/shorewall6.conf b/Shorewall6/configfiles/shorewall6.conf index e9f4dcc3e..0c2a87821 100644 --- a/Shorewall6/configfiles/shorewall6.conf +++ b/Shorewall6/configfiles/shorewall6.conf @@ -125,6 +125,8 @@ CLEAR_TC=No COMPLETE=No +DEFER_DNS_RESOLUTION=Yes + DELETE_THEN_ADD=Yes DONT_LOAD= diff --git a/Shorewall6/manpages/shorewall6.conf.xml b/Shorewall6/manpages/shorewall6.conf.xml index ec6c167e1..13c93621e 100644 --- a/Shorewall6/manpages/shorewall6.conf.xml +++ b/Shorewall6/manpages/shorewall6.conf.xml @@ -478,19 +478,31 @@ -
- 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. -
+ + DEFER_DNS_RESOLUTION=[Yes|No] + + + Added in Shorewall 4.5.12. When set to 'Yes' (the default), + DNS names are validated in the compiler and then passed on to the + generated script where they are resolved by ip6tables-restore. This + is an advantage if you use AUTOMAKE=Yes and the IP address + associated with the DNS name is subject to change. When + DEFER_DNS_RESOLUTION=No, DNS names are converted into IP addresses + by the compiler. This has the advantage that when AUTOMAKE=Yes the + start and restart commands + will succeed even if no DNS server is reachable (assuming that the + configuration hasn't changed since the compiled script was last + generated). @@ -1177,8 +1189,8 @@ net all DROP infothen the chain name is 'net2all' #ACTION SOURCE DEST LOG:info:foo,bar net fw - would generate the following log prefix when using the - default LOGFORMAT setting: + would generate the following log prefix when using the default + LOGFORMAT setting: Shorewall:foo:bar: