From c26db29244dc47e03b331cb223931c5ad81975a4 Mon Sep 17 00:00:00 2001 From: Tom Eastep Date: Sun, 13 Jan 2013 13:23:38 -0800 Subject: [PATCH] Implement DEFER_DNS_RESOLUTION --- Shorewall/Perl/Shorewall/Chains.pm | 54 +++++++++++++------ Shorewall/Perl/Shorewall/Config.pm | 2 + Shorewall/Perl/Shorewall/IPAddrs.pm | 39 ++++++++++++++ Shorewall/Samples/Universal/shorewall.conf | 2 + .../Samples/one-interface/shorewall.conf | 2 + .../Samples/three-interfaces/shorewall.conf | 2 + .../Samples/two-interfaces/shorewall.conf | 2 + Shorewall/configfiles/shorewall.conf | 2 + Shorewall/manpages/shorewall.conf.xml | 46 ++++++++++++---- Shorewall6/Samples6/Universal/shorewall6.conf | 2 + .../Samples6/one-interface/shorewall6.conf | 2 + .../Samples6/three-interfaces/shorewall6.conf | 2 + .../Samples6/two-interfaces/shorewall6.conf | 2 + Shorewall6/configfiles/shorewall6.conf | 2 + Shorewall6/manpages/shorewall6.conf.xml | 52 +++++++++++++----- 15 files changed, 173 insertions(+), 40 deletions(-) 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..399920b70 100644 --- a/Shorewall/Perl/Shorewall/IPAddrs.pm +++ b/Shorewall/Perl/Shorewall/IPAddrs.pm @@ -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]; @@ -611,6 +629,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]; @@ -778,6 +811,10 @@ sub validate_net ( $$ ) { $validate_net->(@_); } +sub resolve_dnsname( $ ) { + $resolve_dnsname->(@_); +} + sub validate_range ($$ ) { $validate_range->(@_); } @@ -809,6 +846,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 +857,7 @@ sub initialize( $ ) { $validate_net = \&validate_6net; $validate_range = \&validate_6range; $validate_host = \&validate_6host; + $resolve_dnsname = \&resolve_6dnsname; } } 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.conf.xml b/Shorewall/manpages/shorewall.conf.xml index 832c98da2..25429ccc3 100644 --- a/Shorewall/manpages/shorewall.conf.xml +++ b/Shorewall/manpages/shorewall.conf.xml @@ -539,19 +539,43 @@ -
- + 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 two advantages: + + + + 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). + + + + The restore command (including the + automatic restore performed when + start or restart fails) + will succeed even if no DNS server is reachable. + + 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..f5c17147a 100644 --- a/Shorewall6/manpages/shorewall6.conf.xml +++ b/Shorewall6/manpages/shorewall6.conf.xml @@ -478,19 +478,43 @@ -
- 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 two advantages: + + + + 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). + + + + The restore command (including the + automatic restore performed when + start or restart fails) + will succeed even if no DNS server is reachable. + + @@ -1177,8 +1201,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: