Implement DEFER_DNS_RESOLUTION

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2013-01-13 17:00:14 -08:00
parent 54dbbaaa2d
commit 89a09f0256
18 changed files with 158 additions and 47 deletions

View File

@ -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;

View File

@ -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';

View File

@ -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;
}
}

View File

@ -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 '-';

View File

@ -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);
}

View File

@ -132,6 +132,8 @@ CLEAR_TC=Yes
COMPLETE=Yes
DEFER_DNS_RESOLUTION=Yes
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes

View File

@ -143,6 +143,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes

View File

@ -141,6 +141,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes

View File

@ -144,6 +144,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DISABLE_IPV6=No
DELETE_THEN_ADD=Yes

View File

@ -132,6 +132,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DETECT_DNAT_IPADDRS=No

View File

@ -161,7 +161,7 @@
<term><replaceable>ipaddress</replaceable></term>
<listitem>
<para>is an IPv4 address.</para>
<para>is an IPv4 address. DNS names are not allowed.</para>
</listitem>
</varlistentry>
@ -224,7 +224,7 @@
<term><replaceable>ipaddress</replaceable></term>
<listitem>
<para>is an IPv4 address or a MAC address.</para>
<para>is an IPv4 address. DNS Names are not allowed.</para>
</listitem>
</varlistentry>

View File

@ -539,19 +539,31 @@
</listitem>
</itemizedlist>
<blockquote>
<para></para>
<para>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.</para>
</listitem>
</varlistentry>
<para>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.</para>
<varlistentry>
<term><emphasis role="bold">DEFER_DNS_RESOLUTION=</emphasis>[<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>]</term>
<para>Note that the setting in /usr/share/shorewall/configpath is
always used to locate shorewall.conf.</para>
</blockquote>
<listitem>
<para>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
<command>start</command> and <command>restart</command> commands
will succeed even if no DNS server is reachable (assuming that the
configuration hasn't changed since the compiled script was last
generated).</para>
</listitem>
</varlistentry>

View File

@ -125,6 +125,8 @@ CLEAR_TC=Yes
COMPLETE=Yes
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DONT_LOAD=

View File

@ -125,6 +125,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DONT_LOAD=

View File

@ -125,6 +125,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DONT_LOAD=

View File

@ -125,6 +125,8 @@ CLEAR_TC=Yes
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DONT_LOAD=

View File

@ -125,6 +125,8 @@ CLEAR_TC=No
COMPLETE=No
DEFER_DNS_RESOLUTION=Yes
DELETE_THEN_ADD=Yes
DONT_LOAD=

View File

@ -478,19 +478,31 @@
</listitem>
</itemizedlist>
<blockquote>
<para>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.</para>
<para>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.</para>
</listitem>
</varlistentry>
<para>Note that the setting in /usr/share/shorewall6/configpath is
always used to locate shorewall6.conf.</para>
</blockquote>
<varlistentry>
<term><emphasis role="bold">DEFER_DNS_RESOLUTION=</emphasis>[<emphasis
role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>]</term>
<listitem>
<para>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
<command>start</command> and <command>restart</command> commands
will succeed even if no DNS server is reachable (assuming that the
configuration hasn't changed since the compiled script was last
generated).</para>
</listitem>
</varlistentry>
@ -1177,8 +1189,8 @@ net all DROP info</programlisting>then the chain name is 'net2all'
<programlisting>#ACTION SOURCE DEST
LOG:info:foo,bar net fw</programlisting>
<para> would generate the following log prefix when using the
default LOGFORMAT setting:</para>
<para>would generate the following log prefix when using the default
LOGFORMAT setting:</para>
<simplelist>
<member>Shorewall:foo:bar:</member>