Add a 'nodbl' option for the hosts file.

Signed-off-by: Tom Eastep <teastep@shorewall.net>
This commit is contained in:
Tom Eastep 2024-03-02 08:33:36 -08:00
parent 1377fc8897
commit a3abafa98b
4 changed files with 99 additions and 20 deletions

View File

@ -186,6 +186,8 @@ our %EXPORT_TAGS = (
use_forward_chain use_forward_chain
input_chain input_chain
input_option_chain input_option_chain
nodbl_src_chain
nodbl_dst_chain
zone_input_chain zone_input_chain
use_interface_chain use_interface_chain
output_chain output_chain
@ -2438,6 +2440,22 @@ sub output_option_chain($) {
( $config{USE_PHYSICAL_NAMES} ? chain_base( get_physical( $interface ) ) : get_logical( $interface ) ) . '_oop'; ( $config{USE_PHYSICAL_NAMES} ? chain_base( get_physical( $interface ) ) : get_logical( $interface ) ) . '_oop';
} }
#
# Blacklist Source Exclusion Chain for an interface
#
sub nodbl_src_chain($$) {
my ( $interface, $end ) = ( $_[0], $_[1] );
( $config{USE_PHYSICAL_NAMES} ? chain_base( get_physical( $interface ) ) : get_logical( $interface ) ) . '_' . $end;
}
#
# Blacklist Destination Exclusion Chain for an interface
#
sub nodbl_dst_chain($$) {
my ($interface, $end) = ( $_[0], $_[1] );
( $config{USE_PHYSICAL_NAMES} ? chain_base( get_physical( $interface ) ) : get_logical( $interface ) ) . '_' . $end;
}
# #
# Forward Option Chain for an interface # Forward Option Chain for an interface
# #

View File

@ -951,25 +951,61 @@ sub add_common_rules ( $ ) {
} }
} }
my @nodbl = @{$interfaceref->{nodbl}};
if ( $dbl_ipset && ( ( my $setting = get_interface_option( $interface, 'dbl' ) ) ne '0:0' ) ) { if ( $dbl_ipset && ( ( my $setting = get_interface_option( $interface, 'dbl' ) ) ne '0:0' ) ) {
my ( $in, $out ) = split /:/, $setting; my ( $in, $out ) = split /:/, $setting;
my ( $src_target, $dst_target ) = ( $dbl_src_target, $dbl_dst_target );
my ( @src_exclude, @dst_exclude );
if ( @nodbl ) {
if ( @nodbl > 1 ) {
#
# We need to create an intermediate chain
#
$chainref = new_standard_chain( $src_target = nodbl_src_chain( $interface , $dbl_src_target ));
for (@nodbl) {
add_ijump( $chainref, j => 'RETURN', s => $_ );
}
add_ijump( $chainref, j => $dbl_src_target );
if ( $dbl_src_target ne $dbl_dst_target ) {
$chainref = new_standard_chain( $dst_target = nodbl_dst_chain( $interface , $dbl_dst_target ));
for ( @nodbl ){
add_ijump( $chainref, j => 'RETURN', -d => $_ );
}
add_ijump( $chainref, j => $dbl_dst_target );
}
} else {
#
# Easy case
#
@src_exclude = ( s => "! $nodbl[0]" );
@dst_exclude = ( d => "! $nodbl[0]" );
}
}
if ( $in == 1 ) { if ( $in == 1 ) {
# #
# src # src
# #
add_ijump_extended( $filter_table->{input_option_chain($interface)}, j => $dbl_src_target, $origin{DYNAMIC_BLACKLIST}, @state, set => "--match-set $dbl_ipset src" ); add_ijump_extended( $filter_table->{input_option_chain($interface)}, j => $src_target, $origin{DYNAMIC_BLACKLIST}, @src_exclude, @state, set => "--match-set $dbl_ipset src" );
add_ijump_extended( $filter_table->{forward_option_chain($interface)}, j => $dbl_src_target, $origin{DYNAMIC_BLACKLIST}, @state, set => "--match-set $dbl_ipset src" ); add_ijump_extended( $filter_table->{forward_option_chain($interface)}, j => $src_target, $origin{DYNAMIC_BLACKLIST}, @dst_exclude, @state, set => "--match-set $dbl_ipset src" );
} elsif ( $in == 2 ) { } elsif ( $in == 2 ) {
add_ijump_extended( $filter_table->{forward_option_chain($interface)}, j => $dbl_dst_target, $origin{DYNAMIC_BLACKLIST}, @state, set => "--match-set $dbl_ipset dst" ); add_ijump_extended( $filter_table->{forward_option_chain($interface)}, j => $dst_target, $origin{DYNAMIC_BLACKLIST}, @dst_exclude, @state, set => "--match-set $dbl_ipset dst" );
} }
if ( $out == 2 ) { if ( $out == 2 ) {
# #
# dst # dst
# #
add_ijump_extended( $filter_table->{output_option_chain($interface)}, j => $dbl_dst_target, $origin{DYNAMIC_BLACKLIST}, @state, set => "--match-set $dbl_ipset dst" ); add_ijump_extended( $filter_table->{output_option_chain($interface)}, j => $dbl_dst_target, $origin{DYNAMIC_BLACKLIST}, @dst_exclude, @state, set => "--match-set $dbl_ipset dst" );
} }
} }

View File

@ -410,6 +410,7 @@ sub initialize( $$ ) {
destonly => 1, destonly => 1,
sourceonly => 1, sourceonly => 1,
mss => 1, mss => 1,
nodbl => 1
); );
%zonetypes = ( 1 => 'firewall', %zonetypes = ( 1 => 'firewall',
@ -456,6 +457,7 @@ sub initialize( $$ ) {
routeback => 1, routeback => 1,
tcpflags => 1, tcpflags => 1,
mss => 1, mss => 1,
nodbl => 1
); );
%zonetypes = ( 1 => 'firewall', %zonetypes = ( 1 => 'firewall',
@ -1541,6 +1543,7 @@ sub process_interface( $$ ) {
origin => shortlineinfo( '' ), origin => shortlineinfo( '' ),
wildcard => $wildcard, wildcard => $wildcard,
physwild => $physwild, physwild => $physwild,
nodbl => [],
}; };
$interfaces{$physical} = $interfaceref if $physical ne $interface; $interfaces{$physical} = $interfaceref if $physical ne $interface;
@ -2229,6 +2232,11 @@ sub process_host( ) {
require_capability 'TCPMSS_TARGET', $option, 's'; require_capability 'TCPMSS_TARGET', $option, 's';
$options{mss} = $1; $options{mss} = $1;
$zoneref->{options}{complex} = 1; $zoneref->{options}{complex} = 1;
} elsif ( $option eq 'nodbl' ) {
fatal_error "The 'nodbl' option is only allowed when using ipset-based dynamic blacklisting" unless $config{DYNAMIC_BLACKLIST} =~ /^ipset/;
fatal_error "The 'nodbl' option is only allowed in 'ip' zones" unless $type & IP;
push @{$interfaceref->{nodbl}}, $hosts;
$options{nodbl} = 1;
} elsif ( $validhostoptions{$option}) { } elsif ( $validhostoptions{$option}) {
fatal_error qq(The "$option" option is not allowed with Vserver zones) if $type & VSERVER && ! ( $validhostoptions{$option} & IF_OPTION_VSERVER ); fatal_error qq(The "$option" option is not allowed with Vserver zones) if $type & VSERVER && ! ( $validhostoptions{$option} & IF_OPTION_VSERVER );
$options{$option} = 1; $options{$option} = 1;

View File

@ -31,8 +31,8 @@
<para>The order of entries in this file is not significant in determining <para>The order of entries in this file is not significant in determining
zone composition. Rather, the order that the zones are declared in <ulink zone composition. Rather, the order that the zones are declared in <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5) determines url="shorewall-zones.html">shorewall-zones</ulink>(5) determines the order
the order in which the records in this file are interpreted.</para> in which the records in this file are interpreted.</para>
<warning> <warning>
<para>The only time that you need this file is when you have more than <para>The only time that you need this file is when you have more than
@ -41,9 +41,9 @@
<warning> <warning>
<para>If you have an entry for a zone and interface in <ulink <para>If you have an entry for a zone and interface in <ulink
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) then do
then do not include any entries in this file for that same (zone, not include any entries in this file for that same (zone, interface)
interface) pair.</para> pair.</para>
</warning> </warning>
<para>The columns in the file are as follows.</para> <para>The columns in the file are as follows.</para>
@ -55,8 +55,8 @@
<listitem> <listitem>
<para>The name of a zone declared in <ulink <para>The name of a zone declared in <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5). You url="shorewall-zones.html">shorewall-zones</ulink>(5). You may not
may not list the firewall zone in this column.</para> list the firewall zone in this column.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -69,9 +69,9 @@
<listitem> <listitem>
<para>The name of an interface defined in the <ulink <para>The name of an interface defined in the <ulink
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) file
file followed by a colon (":") and a comma-separated list whose followed by a colon (":") and a comma-separated list whose elements
elements are either:</para> are either:</para>
<orderedlist numeration="loweralpha"> <orderedlist numeration="loweralpha">
<listitem> <listitem>
@ -171,8 +171,8 @@
<para>The zone is accessed via a kernel 2.6 ipsec SA. Note <para>The zone is accessed via a kernel 2.6 ipsec SA. Note
that if the zone named in the ZONE column is specified as an that if the zone named in the ZONE column is specified as an
IPSEC zone in the <ulink IPSEC zone in the <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5) url="shorewall-zones.html">shorewall-zones</ulink>(5) file
file then you do NOT need to specify the 'ipsec' option then you do NOT need to specify the 'ipsec' option
here.</para> here.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -183,8 +183,8 @@
<listitem> <listitem>
<para>Connection requests from these hosts are compared <para>Connection requests from these hosts are compared
against the contents of <ulink against the contents of <ulink
url="shorewall-maclist.html">shorewall-maclist</ulink>(5). url="shorewall-maclist.html">shorewall-maclist</ulink>(5). If
If this option is specified, the interface must be an Ethernet this option is specified, the interface must be an Ethernet
NIC or equivalent and must be up before Shorewall is NIC or equivalent and must be up before Shorewall is
started.</para> started.</para>
</listitem> </listitem>
@ -214,8 +214,8 @@
<para>Smurfs will be optionally logged based on the setting of <para>Smurfs will be optionally logged based on the setting of
SMURF_LOG_LEVEL in <ulink SMURF_LOG_LEVEL in <ulink
url="shorewall.conf.html">shorewall.conf</ulink>(5). url="shorewall.conf.html">shorewall.conf</ulink>(5). After
After logging, the packets are dropped.</para> logging, the packets are dropped.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
@ -243,6 +243,23 @@
according to the setting of TCP_FLAGS_LOG_LEVEL.</para> according to the setting of TCP_FLAGS_LOG_LEVEL.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>nodbl</term>
<listitem>
<para>This option was added in Shorewall 5.2.9. It causes
addresses in the HOSTS column to be exempted from ipset-based
dynamic blacklisting
(DYNAMIC_BLACKLIST={<option>ipset</option>|<option>ipsec-only</option>)...
in <ulink
url="shorewall.conf.html">Shorewall.conf</ulink>(5)). It may
only be specified if the <replaceable>zone-name</replaceable>
listed in the ZONE column is defined as an <option>ip</option>
zone in <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5).</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</listitem> </listitem>
</varlistentry> </varlistentry>