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
input_chain
input_option_chain
nodbl_src_chain
nodbl_dst_chain
zone_input_chain
use_interface_chain
output_chain
@ -2438,6 +2440,22 @@ sub output_option_chain($) {
( $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
#

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' ) ) {
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 ) {
#
# 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->{forward_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 => $src_target, $origin{DYNAMIC_BLACKLIST}, @dst_exclude, @state, set => "--match-set $dbl_ipset src" );
} 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 ) {
#
# 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,
sourceonly => 1,
mss => 1,
nodbl => 1
);
%zonetypes = ( 1 => 'firewall',
@ -456,6 +457,7 @@ sub initialize( $$ ) {
routeback => 1,
tcpflags => 1,
mss => 1,
nodbl => 1
);
%zonetypes = ( 1 => 'firewall',
@ -1541,6 +1543,7 @@ sub process_interface( $$ ) {
origin => shortlineinfo( '' ),
wildcard => $wildcard,
physwild => $physwild,
nodbl => [],
};
$interfaces{$physical} = $interfaceref if $physical ne $interface;
@ -2229,6 +2232,11 @@ sub process_host( ) {
require_capability 'TCPMSS_TARGET', $option, 's';
$options{mss} = $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}) {
fatal_error qq(The "$option" option is not allowed with Vserver zones) if $type & VSERVER && ! ( $validhostoptions{$option} & IF_OPTION_VSERVER );
$options{$option} = 1;

View File

@ -31,8 +31,8 @@
<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
url="shorewall-zones.html">shorewall-zones</ulink>(5) determines
the order in which the records in this file are interpreted.</para>
url="shorewall-zones.html">shorewall-zones</ulink>(5) determines the order
in which the records in this file are interpreted.</para>
<warning>
<para>The only time that you need this file is when you have more than
@ -41,9 +41,9 @@
<warning>
<para>If you have an entry for a zone and interface in <ulink
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5)
then do not include any entries in this file for that same (zone,
interface) pair.</para>
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) then do
not include any entries in this file for that same (zone, interface)
pair.</para>
</warning>
<para>The columns in the file are as follows.</para>
@ -55,8 +55,8 @@
<listitem>
<para>The name of a zone declared in <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5). You
may not list the firewall zone in this column.</para>
url="shorewall-zones.html">shorewall-zones</ulink>(5). You may not
list the firewall zone in this column.</para>
</listitem>
</varlistentry>
@ -69,9 +69,9 @@
<listitem>
<para>The name of an interface defined in the <ulink
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5)
file followed by a colon (":") and a comma-separated list whose
elements are either:</para>
url="shorewall-interfaces.html">shorewall-interfaces</ulink>(5) file
followed by a colon (":") and a comma-separated list whose elements
are either:</para>
<orderedlist numeration="loweralpha">
<listitem>
@ -171,8 +171,8 @@
<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
IPSEC zone in the <ulink
url="shorewall-zones.html">shorewall-zones</ulink>(5)
file then you do NOT need to specify the 'ipsec' option
url="shorewall-zones.html">shorewall-zones</ulink>(5) file
then you do NOT need to specify the 'ipsec' option
here.</para>
</listitem>
</varlistentry>
@ -183,8 +183,8 @@
<listitem>
<para>Connection requests from these hosts are compared
against the contents of <ulink
url="shorewall-maclist.html">shorewall-maclist</ulink>(5).
If this option is specified, the interface must be an Ethernet
url="shorewall-maclist.html">shorewall-maclist</ulink>(5). If
this option is specified, the interface must be an Ethernet
NIC or equivalent and must be up before Shorewall is
started.</para>
</listitem>
@ -214,8 +214,8 @@
<para>Smurfs will be optionally logged based on the setting of
SMURF_LOG_LEVEL in <ulink
url="shorewall.conf.html">shorewall.conf</ulink>(5).
After logging, the packets are dropped.</para>
url="shorewall.conf.html">shorewall.conf</ulink>(5). After
logging, the packets are dropped.</para>
</listitem>
</varlistentry>
@ -243,6 +243,23 @@
according to the setting of TCP_FLAGS_LOG_LEVEL.</para>
</listitem>
</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>
</listitem>
</varlistentry>