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'; my @input = split_list $input, 'host';
return @input unless $input =~ /\[/;
my $exclude = 0; my $exclude = 0;
my @result; my @result;
while ( @input ) { if ( $input =~ /\[/ ) {
my $element = shift @input; while ( @input ) {
my $element = shift @input;
if ( $element =~ /\[/ ) { if ( $element =~ /\[/ ) {
while ( $element =~ tr/[/[/ > $element =~ tr/]/]/ ) { while ( $element =~ tr/[/[/ > $element =~ tr/]/]/ ) {
fatal_error "Missing ']' ($element)" unless @input; fatal_error "Missing ']' ($element)" unless @input;
$element .= ( ',' . shift @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 ) { push @result, $element;
fatal_error "Invalid host list ($input)" if $exclude && $element =~ /!/; }
$exclude ||= $element =~ /^!/ || $element =~ /\]!/; } else {
} @result = @input;
}
fatal_error "Mismatched [...] ($element)" unless $element =~ tr/[/[/ == $element =~ tr/]/]/; unless ( $config{DEFER_DNS_RESOLUTION} ) {
} else { my @result1;
$exclude ||= $element =~ /!/ unless $loose;
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; @result;

View File

@ -765,6 +765,7 @@ sub initialize( $;$$) {
RESTORE_ROUTEMARKS => undef, RESTORE_ROUTEMARKS => undef,
IGNOREUNKNOWNVARIABLES => undef, IGNOREUNKNOWNVARIABLES => undef,
WARNOLDCAPVERSION => undef, WARNOLDCAPVERSION => undef,
DEFER_DNS_RESOLUTION => undef,
# #
# Packet Disposition # Packet Disposition
# #
@ -5060,6 +5061,7 @@ sub get_configuration( $$$$ ) {
default_yes_no 'RESTORE_ROUTEMARKS' , 'Yes'; default_yes_no 'RESTORE_ROUTEMARKS' , 'Yes';
default_yes_no 'IGNOREUNKNOWNVARIABLES' , 'Yes'; default_yes_no 'IGNOREUNKNOWNVARIABLES' , 'Yes';
default_yes_no 'WARNOLDCAPVERSION' , 'Yes'; default_yes_no 'WARNOLDCAPVERSION' , 'Yes';
default_yes_no 'DEFER_DNS_RESOLUTION' , 'Yes';
$config{IPSET} = '' if supplied $config{IPSET} && $config{IPSET} eq 'ipset'; $config{IPSET} = '' if supplied $config{IPSET} && $config{IPSET} eq 'ipset';

View File

@ -26,7 +26,7 @@
# #
package Shorewall::IPAddrs; package Shorewall::IPAddrs;
require Exporter; 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 Socket;
use strict; use strict;
@ -49,6 +49,7 @@ our @EXPORT = ( qw( ALLIPv4
NILIP NILIP
ALL ALL
valid_address
validate_address validate_address
validate_net validate_net
decompose_net decompose_net
@ -65,6 +66,7 @@ our @EXPORT = ( qw( ALLIPv4
nilip nilip
rfc1918_networks rfc1918_networks
resolve_proto resolve_proto
resolve_dnsname
proto_name proto_name
validate_port validate_port
validate_portpair validate_portpair
@ -90,6 +92,7 @@ our @nilip;
our $valid_address; our $valid_address;
our $validate_address; our $validate_address;
our $validate_net; our $validate_net;
our $resolve_dnsname;
our $validate_range; our $validate_range;
our $validate_host; our $validate_host;
our $family; our $family;
@ -152,6 +155,21 @@ sub validate_4address( $$ ) {
defined wantarray ? wantarray ? @addrs : $addrs[0] : undef; 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( $ ) { sub decodeaddr( $ ) {
my $address = $_[0]; my $address = $_[0];
@ -202,7 +220,8 @@ sub validate_4net( $$ ) {
fatal_error "Invalid IP address ($net)" unless valid_4address $net; fatal_error "Invalid IP address ($net)" unless valid_4address $net;
} else { } else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/' || ! defined $net; 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; $vlsm = 32;
} }
@ -611,6 +630,21 @@ sub validate_6address( $$ ) {
defined wantarray ? wantarray ? @addrs : $addrs[0] : undef; 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( $$ ) { sub validate_6net( $$ ) {
my ($net, $vlsm, $rest) = split( '/', $_[0], 3 ); my ($net, $vlsm, $rest) = split( '/', $_[0], 3 );
my $allow_name = $_[0]; my $allow_name = $_[0];
@ -635,7 +669,8 @@ sub validate_6net( $$ ) {
fatal_error "Invalid IPv6 address ($net)" unless valid_6address $net; fatal_error "Invalid IPv6 address ($net)" unless valid_6address $net;
} else { } else {
fatal_error "Invalid Network address ($_[0])" if $_[0] =~ '/'; 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; $vlsm = 128;
} }
@ -778,6 +813,10 @@ sub validate_net ( $$ ) {
$validate_net->(@_); $validate_net->(@_);
} }
sub resolve_dnsname( $ ) {
$resolve_dnsname->(@_);
}
sub validate_range ($$ ) { sub validate_range ($$ ) {
$validate_range->(@_); $validate_range->(@_);
} }
@ -809,6 +848,7 @@ sub initialize( $ ) {
$validate_net = \&validate_4net; $validate_net = \&validate_4net;
$validate_range = \&validate_4range; $validate_range = \&validate_4range;
$validate_host = \&validate_4host; $validate_host = \&validate_4host;
$resolve_dnsname = \&resolve_4dnsname;
} else { } else {
$allip = ALLIPv6; $allip = ALLIPv6;
@allip = @allipv6; @allip = @allipv6;
@ -819,6 +859,7 @@ sub initialize( $ ) {
$validate_net = \&validate_6net; $validate_net = \&validate_6net;
$validate_range = \&validate_6range; $validate_range = \&validate_6range;
$validate_host = \&validate_6host; $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 '-'; 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 '-'; validate_address ( $gateway, 1 ) if $gateway ne '-';

View File

@ -1200,7 +1200,7 @@ sub process_interface( $$ ) {
$hostoptions{broadcast} = 1; $hostoptions{broadcast} = 1;
} elsif ( $option eq 'sfilter' ) { } elsif ( $option eq 'sfilter' ) {
$filterref = [ split_list $value, 'address' ]; $filterref = [ split_list $value, 'address' ];
$_ = validate_net( $_, 1) for @{$filterref} validate_net( $_, 0) for @{$filterref}
} else { } else {
assert(0); assert(0);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -539,19 +539,31 @@
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<blockquote> <para>If CONFIG_PATH is not given or if it is set to the empty value
<para></para> 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 <varlistentry>
value then the contents of /usr/share/shorewall/configpath are <term><emphasis role="bold">DEFER_DNS_RESOLUTION=</emphasis>[<emphasis
used. As released from shorewall.net, that file sets the role="bold">Yes</emphasis>|<emphasis role="bold">No</emphasis>]</term>
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>
<para>Note that the setting in /usr/share/shorewall/configpath is <listitem>
always used to locate shorewall.conf.</para> <para>Added in Shorewall 4.5.12. When set to 'Yes' (the default),
</blockquote> 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> </listitem>
</varlistentry> </varlistentry>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -478,19 +478,31 @@
</listitem> </listitem>
</itemizedlist> </itemizedlist>
<blockquote> <para>If CONFIG_PATH is not given or if it is set to the empty value
<para>If CONFIG_PATH is not given or if it is set to the empty then the contents of /usr/share/shorewall6/configpath are used. As
value then the contents of /usr/share/shorewall6/configpath are released from shorewall.net, that file sets the CONFIG_PATH to
used. As released from shorewall.net, that file sets the /etc/shorewall6:/usr/share/shorewall6:/usr/share/shorewall but your
CONFIG_PATH to particular distribution may set it differently. See the output of
/etc/shorewall6:/usr/share/shorewall6:/usr/share/shorewall but shorewall6 show config for the default on your system.</para>
your particular distribution may set it differently. See the </listitem>
output of shorewall6 show config for the default on your </varlistentry>
system.</para>
<para>Note that the setting in /usr/share/shorewall6/configpath is <varlistentry>
always used to locate shorewall6.conf.</para> <term><emphasis role="bold">DEFER_DNS_RESOLUTION=</emphasis>[<emphasis
</blockquote> 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> </listitem>
</varlistentry> </varlistentry>
@ -1177,8 +1189,8 @@ net all DROP info</programlisting>then the chain name is 'net2all'
<programlisting>#ACTION SOURCE DEST <programlisting>#ACTION SOURCE DEST
LOG:info:foo,bar net fw</programlisting> LOG:info:foo,bar net fw</programlisting>
<para> would generate the following log prefix when using the <para>would generate the following log prefix when using the default
default LOGFORMAT setting:</para> LOGFORMAT setting:</para>
<simplelist> <simplelist>
<member>Shorewall:foo:bar:</member> <member>Shorewall:foo:bar:</member>