Implement DEFER_DNS_RESOLUTION

This commit is contained in:
Tom Eastep 2013-01-13 13:23:38 -08:00
parent 54dbbaaa2d
commit c26db29244
15 changed files with 173 additions and 40 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

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

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

@ -539,19 +539,43 @@
</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 two advantages:</para>
<orderedlist>
<listitem>
<para>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>
<para>The <command>restore</command> command (including the
automatic <command>restore</command> performed when
<command>start</command> or <command>restart</command> fails)
will succeed even if no DNS server is reachable.</para>
</listitem>
</orderedlist>
</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,43 @@
</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 two advantages:</para>
<orderedlist>
<listitem>
<para>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>
<para>The <command>restore</command> command (including the
automatic <command>restore</command> performed when
<command>start</command> or <command>restart</command> fails)
will succeed even if no DNS server is reachable.</para>
</listitem>
</orderedlist>
</listitem>
</varlistentry>
@ -1177,8 +1201,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>