diff --git a/Shorewall/Perl/Shorewall/Chains.pm b/Shorewall/Perl/Shorewall/Chains.pm
index cd8d124fa..1c1711670 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -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
#
diff --git a/Shorewall/Perl/Shorewall/Misc.pm b/Shorewall/Perl/Shorewall/Misc.pm
index 87e02e6ba..3424d1ed6 100644
--- a/Shorewall/Perl/Shorewall/Misc.pm
+++ b/Shorewall/Perl/Shorewall/Misc.pm
@@ -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" );
}
}
diff --git a/Shorewall/Perl/Shorewall/Zones.pm b/Shorewall/Perl/Shorewall/Zones.pm
index 3be33ecf7..5558ff8b7 100644
--- a/Shorewall/Perl/Shorewall/Zones.pm
+++ b/Shorewall/Perl/Shorewall/Zones.pm
@@ -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;
diff --git a/Shorewall/manpages/shorewall-hosts.xml b/Shorewall/manpages/shorewall-hosts.xml
index 6f3d8e807..7c9c14177 100644
--- a/Shorewall/manpages/shorewall-hosts.xml
+++ b/Shorewall/manpages/shorewall-hosts.xml
@@ -31,8 +31,8 @@
The order of entries in this file is not significant in determining
zone composition. Rather, the order that the zones are declared in shorewall-zones(5) determines
- the order in which the records in this file are interpreted.
+ url="shorewall-zones.html">shorewall-zones(5) determines the order
+ in which the records in this file are interpreted.
The only time that you need this file is when you have more than
@@ -41,9 +41,9 @@
If you have an entry for a zone and interface in shorewall-interfaces(5)
- then do not include any entries in this file for that same (zone,
- interface) pair.
+ url="shorewall-interfaces.html">shorewall-interfaces(5) then do
+ not include any entries in this file for that same (zone, interface)
+ pair.The columns in the file are as follows.
@@ -55,8 +55,8 @@
The name of a zone declared in shorewall-zones(5). You
- may not list the firewall zone in this column.
+ url="shorewall-zones.html">shorewall-zones(5). You may not
+ list the firewall zone in this column.
@@ -69,9 +69,9 @@
The name of an interface defined in the shorewall-interfaces(5)
- file followed by a colon (":") and a comma-separated list whose
- elements are either:
+ url="shorewall-interfaces.html">shorewall-interfaces(5) file
+ followed by a colon (":") and a comma-separated list whose elements
+ are either:
@@ -171,8 +171,8 @@
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 shorewall-zones(5)
- file then you do NOT need to specify the 'ipsec' option
+ url="shorewall-zones.html">shorewall-zones(5) file
+ then you do NOT need to specify the 'ipsec' option
here.
@@ -183,8 +183,8 @@
Connection requests from these hosts are compared
against the contents of shorewall-maclist(5).
- If this option is specified, the interface must be an Ethernet
+ url="shorewall-maclist.html">shorewall-maclist(5). If
+ this option is specified, the interface must be an Ethernet
NIC or equivalent and must be up before Shorewall is
started.
@@ -214,8 +214,8 @@
Smurfs will be optionally logged based on the setting of
SMURF_LOG_LEVEL in shorewall.conf(5).
- After logging, the packets are dropped.
+ url="shorewall.conf.html">shorewall.conf(5). After
+ logging, the packets are dropped.
@@ -243,6 +243,23 @@
according to the setting of TCP_FLAGS_LOG_LEVEL.
+
+
+ nodbl
+
+
+ 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={|)...
+ in Shorewall.conf(5)). It may
+ only be specified if the zone-name
+ listed in the ZONE column is defined as an
+ zone in shorewall-zones(5).
+
+