diff --git a/Shorewall/Perl/Shorewall/Rules.pm b/Shorewall/Perl/Shorewall/Rules.pm
index 3114d0663..eb3412687 100644
--- a/Shorewall/Perl/Shorewall/Rules.pm
+++ b/Shorewall/Perl/Shorewall/Rules.pm
@@ -261,14 +261,23 @@ sub setup_blacklist() {
$first_entry = 0;
}
- my ( $networks, $protocol, $ports ) = split_line 1, 3, 'blacklist file';
+ my ( $networks, $protocol, $ports, $options ) = split_line 1, 4, 'blacklist file';
+
+ my $direction = 'from';
+
+ $options = 'from' if $options eq '-';
+
+ for ( split /,/, $options ) {
+ fatal_error "Invalid OPTION ($_)" unless /^(from|to)$/;
+ $direction = $_;
+ }
expand_rule(
$chainref ,
NO_RESTRICT ,
do_proto( $protocol , $ports, '' ) ,
- $networks ,
- '' ,
+ $direction eq 'from' ? $networks : '',
+ $direction eq 'to' ? $networks : '',
'' ,
"-j $target" ,
'' ,
diff --git a/Shorewall/changelog.txt b/Shorewall/changelog.txt
index 08981cfc2..fda0a973e 100644
--- a/Shorewall/changelog.txt
+++ b/Shorewall/changelog.txt
@@ -20,6 +20,8 @@ Changes in Shorewall 4.4.12
10) Support new set match syntax.
+11) Blacklisting by DEST IP.
+
Changes in Shorewall 4.4.11
1) Apply patch from Gabriel.
diff --git a/Shorewall/configfiles/blacklist b/Shorewall/configfiles/blacklist
index d2d992f7f..9bb785124 100644
--- a/Shorewall/configfiles/blacklist
+++ b/Shorewall/configfiles/blacklist
@@ -7,4 +7,5 @@
# information.
#
###############################################################################
-#ADDRESS/SUBNET PROTOCOL PORT
+#ADDRESS/SUBNET PROTOCOL PORT OPTIONS
+
diff --git a/Shorewall/lib.cli b/Shorewall/lib.cli
index 7eea7b53f..eb8c7352a 100644
--- a/Shorewall/lib.cli
+++ b/Shorewall/lib.cli
@@ -1066,6 +1066,10 @@ block() # $1 = command, $2 = Finished, $3 - $n addresses
chain=$1
local finished
finished=$2
+ local which
+ which='-s'
+ local range
+ range='--src-range'
if ! chain_exists dynamic; then
echo "Dynamic blacklisting is not enabled in the current $g_product configuration" >&2
@@ -1077,19 +1081,31 @@ block() # $1 = command, $2 = Finished, $3 - $n addresses
while [ $# -gt 0 ]; do
case $1 in
+ from)
+ which='-s'
+ range='--src-range'
+ shift
+ continue
+ ;;
+ to)
+ which='-d'
+ range='--dst-range'
+ shift
+ continue
+ ;;
*-*)
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j reject
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j DROP
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j logreject
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j logdrop
- $IPTABLES -A dynamic -m iprange --src-range $1 -j $chain || break 1
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j reject
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j DROP
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j logreject
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j logdrop
+ $IPTABLES -A dynamic -m iprange $range $1 -j $chain || break 1
;;
*)
- qt $IPTABLES -D dynamic -s $1 -j reject
- qt $IPTABLES -D dynamic -s $1 -j DROP
- qt $IPTABLES -D dynamic -s $1 -j logreject
- qt $IPTABLES -D dynamic -s $1 -j logdrop
- $IPTABLES -A dynamic -s $1 -j $chain || break 1
+ qt $IPTABLES -D dynamic $which $1 -j reject
+ qt $IPTABLES -D dynamic $which $1 -j DROP
+ qt $IPTABLES -D dynamic $which $1 -j logreject
+ qt $IPTABLES -D dynamic $which $1 -j logdrop
+ $IPTABLES -A dynamic $which $1 -j $chain || break 1
;;
esac
@@ -1379,6 +1395,11 @@ allow_command() {
[ -n "$g_debugging" ] && set -x
[ $# -eq 1 ] && usage 1
if shorewall_is_started ; then
+ local which
+ which='-s'
+ local range
+ range='--src-range'
+
if ! chain_exists dynamic; then
echo "Dynamic blacklisting is not enabled in the current $g_product configuration" >&2
exit 2
@@ -1388,11 +1409,21 @@ allow_command() {
while [ $# -gt 1 ]; do
shift
case $1 in
+ from)
+ which='-s'
+ range='--src-range'
+ continue
+ ;;
+ to)
+ which='-d'
+ range='--dst-range'
+ continue
+ ;;
*-*)
- if qt $IPTABLES -D dynamic -m iprange --src-range $1 -j reject ||\
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j DROP ||\
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j logdrop ||\
- qt $IPTABLES -D dynamic -m iprange --src-range $1 -j logreject
+ if qt $IPTABLES -D dynamic -m iprange $range $1 -j reject ||\
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j DROP ||\
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j logdrop ||\
+ qt $IPTABLES -D dynamic -m iprange $range $1 -j logreject
then
echo "$1 Allowed"
else
@@ -1400,10 +1431,10 @@ allow_command() {
fi
;;
*)
- if qt $IPTABLES -D dynamic -s $1 -j reject ||\
- qt $IPTABLES -D dynamic -s $1 -j DROP ||\
- qt $IPTABLES -D dynamic -s $1 -j logdrop ||\
- qt $IPTABLES -D dynamic -s $1 -j logreject
+ if qt $IPTABLES -D dynamic $which $1 -j reject ||\
+ qt $IPTABLES -D dynamic $which $1 -j DROP ||\
+ qt $IPTABLES -D dynamic $which $1 -j logdrop ||\
+ qt $IPTABLES -D dynamic $which $1 -j logreject
then
echo "$1 Allowed"
else
diff --git a/Shorewall/releasenotes.txt b/Shorewall/releasenotes.txt
index 0ca4badd1..34f3c4d04 100644
--- a/Shorewall/releasenotes.txt
+++ b/Shorewall/releasenotes.txt
@@ -314,6 +314,33 @@ None.
you use a capabilities file, be sure to regenerate it with 4.4.12
shorewall-lite or shorewall6-lite.
+6) Blacklisting can now be done by destination IP address as well as
+ by source address.
+
+ The /etc/shorewall/blacklist and /etc/shorewall6/blacklist files
+ now have an optional OPTIONS column. Initially, this column can
+ contain either 'from' (the default) or 'to'; the latter causes the
+ address(es) in the ADDRESS/SUBNET column to be interpreted as a
+ DESTINATION address rather than a source address.
+
+ Note that static blacklisting is still restricted to traffic
+ ARRIVING on an interface that has the 'blacklist' option set. So to
+ block traffic from your local network to an internet host, you must
+ specify 'blacklist' on your internal interface.
+
+ Similarly, dynamic blacklisting has been enhanced to recognize the
+ 'from' and 'to' keywords.
+
+ Example:
+
+ shorewall drop to 1.2.3.4
+
+ This command will silently drop connection requests from 1.2.3.4.
+
+ The reciprocal of that command would be:
+
+ shorewall allow to 1.2.3.4
+
----------------------------------------------------------------------------
V I. P R O B L E M S C O R R E C T E D A N D N E W F E A T U R E S
I N P R I O R R E L E A S E S
diff --git a/Shorewall6/blacklist b/Shorewall6/blacklist
index 6b519040e..4edfd1505 100755
--- a/Shorewall6/blacklist
+++ b/Shorewall6/blacklist
@@ -7,4 +7,4 @@
# information.
#
###############################################################################
-#ADDRESS/SUBNET PROTOCOL PORT
+#ADDRESS/SUBNET PROTOCOL PORT OPTIONS
diff --git a/Shorewall6/lib.cli b/Shorewall6/lib.cli
index 7c61be08e..d90be730f 100644
--- a/Shorewall6/lib.cli
+++ b/Shorewall6/lib.cli
@@ -958,6 +958,10 @@ block() # $1 = command, $2 = Finished, $3 - $n addresses
chain=$1
local finished
finished=$2
+ local which
+ which='-s'
+ local range
+ range='--src-range'
if ! chain_exists dynamic; then
echo "Dynamic blacklisting is not enabled in the current $g_product configuration" >&2
@@ -969,19 +973,31 @@ block() # $1 = command, $2 = Finished, $3 - $n addresses
while [ $# -gt 0 ]; do
case $1 in
+ from)
+ which='-s'
+ range='--src-range'
+ shift
+ continue
+ ;;
+ to)
+ which='-d'
+ range='--dst-range'
+ shift
+ continue
+ ;;
*-*)
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j reject
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j DROP
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j logreject
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j logdrop
- $IP6TABLES -A dynamic -m iprange --src-range $1 -j $chain || break 1
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j reject
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j DROP
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j logreject
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j logdrop
+ $IP6TABLES -A dynamic -m iprange $range $1 -j $chain || break 1
;;
*)
- qt $IP6TABLES -D dynamic -s $1 -j reject
- qt $IP6TABLES -D dynamic -s $1 -j DROP
- qt $IP6TABLES -D dynamic -s $1 -j logreject
- qt $IP6TABLES -D dynamic -s $1 -j logdrop
- $IP6TABLES -A dynamic -s $1 -j $chain || break 1
+ qt $IP6TABLES -D dynamic $which $1 -j reject
+ qt $IP6TABLES -D dynamic $which $1 -j DROP
+ qt $IP6TABLES -D dynamic $which $1 -j logreject
+ qt $IP6TABLES -D dynamic $which $1 -j logdrop
+ $IP6TABLES -A dynamic $which $1 -j $chain || break 1
;;
esac
@@ -1086,6 +1102,11 @@ allow_command() {
[ -n "$g_debugging" ] && set -x
[ $# -eq 1 ] && usage 1
if shorewall6_is_started ; then
+ local which
+ which='-s'
+ local range
+ range='--src-range'
+
if ! chain_exists dynamic; then
echo "Dynamic blacklisting is not enabled in the current $g_product configuration" >&2
exit 2
@@ -1095,11 +1116,21 @@ allow_command() {
while [ $# -gt 1 ]; do
shift
case $1 in
+ from)
+ which='-s'
+ range='--src-range'
+ continue
+ ;;
+ to)
+ which='-d'
+ range='--dst-range'
+ continue
+ ;;
*-*)
- if qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j reject ||\
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j DROP ||\
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j logdrop ||\
- qt $IP6TABLES -D dynamic -m iprange --src-range $1 -j logreject
+ if qt $IP6TABLES -D dynamic -m iprange $range $1 -j reject ||\
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j DROP ||\
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j logdrop ||\
+ qt $IP6TABLES -D dynamic -m iprange $range $1 -j logreject
then
echo "$1 Allowed"
else
@@ -1107,10 +1138,10 @@ allow_command() {
fi
;;
*)
- if qt $IP6TABLES -D dynamic -s $1 -j reject ||\
- qt $IP6TABLES -D dynamic -s $1 -j DROP ||\
- qt $IP6TABLES -D dynamic -s $1 -j logdrop ||\
- qt $IP6TABLES -D dynamic -s $1 -j logreject
+ if qt $IP6TABLES -D dynamic $which $1 -j reject ||\
+ qt $IP6TABLES -D dynamic $which $1 -j DROP ||\
+ qt $IP6TABLES -D dynamic $which $1 -j logdrop ||\
+ qt $IP6TABLES -D dynamic $which $1 -j logreject
then
echo "$1 Allowed"
else
diff --git a/docs/blacklisting_support.xml b/docs/blacklisting_support.xml
index ed8cd0242..e841193c3 100644
--- a/docs/blacklisting_support.xml
+++ b/docs/blacklisting_support.xml
@@ -20,6 +20,8 @@
2002-2006
+ 2010
+
Thomas M. Eastep
@@ -61,6 +63,20 @@
the blacklists. Blacklists only stop blacklisted hosts from
connecting to you — they do not stop you or your users from connecting
to blacklisted hosts .
+
+
+
+ UPDATE
+
+
+ Beginning with Shorewall 4.4.12, you can also blacklist by
+ destination address. See shorewall-blacklist
+ (5) and shorewall (8)
+ for details.
+
+
+
@@ -161,25 +177,28 @@ ipset -B Blacklist 206.124.146.177 -b SMTP
Prior to that release, the feature is always enabled.
Once enabled, dynamic blacklisting doesn't use any configuration
- parameters but is rather controlled using /sbin/shorewall[-lite]
- commands:
+ parameters but is rather controlled using /sbin/shorewall[-lite] commands.
+ Note that to and from may
+ only be specified when running Shorewall 4.4.12 or
+ later.
- drop <ip address list> - causes
- packets from the listed IP addresses to be silently dropped by the
+ drop [to|from] <ip address list> -
+ causes packets from the listed IP addresses to be silently dropped by
+ the firewall.
+
+
+
+ reject [to|from]<ip address list> -
+ causes packets from the listed IP addresses to be rejected by the
firewall.
- reject <ip address list> - causes
- packets from the listed IP addresses to be rejected by the
- firewall.
-
-
-
- allow <ip address list> - re-enables
- receipt of packets from hosts previously blacklisted by a
+ allow [to|from] <ip address list> -
+ re-enables receipt of packets from hosts previously blacklisted by a
drop or reject
command.
@@ -201,19 +220,19 @@ ipset -B Blacklist 206.124.146.177 -b SMTP
- logdrop <ip address list> - causes
- packets from the listed IP addresses to be dropped and logged by the
- firewall. Logging will occur at the level specified by the
+ logdrop [to|from] <ip address list> -
+ causes packets from the listed IP addresses to be dropped and logged
+ by the firewall. Logging will occur at the level specified by the
BLACKLIST_LOGLEVEL setting at the last [re]start (logging will be at
the 'info' level if no BLACKLIST_LOGLEVEL was given).
- logreject <ip address list> - causes
- packets from the listed IP addresses to be rejected and logged by the
- firewall. Logging will occur at the level specified by the
- BLACKLIST_LOGLEVEL setting at the last [re]start (logging will be at
- the 'info' level if no BLACKLIST_LOGLEVEL was given).
+ logreject [to|from}<ip address list>
+ - causes packets from the listed IP addresses to be rejected and
+ logged by the firewall. Logging will occur at the level specified by
+ the BLACKLIST_LOGLEVEL setting at the last [re]start (logging will be
+ at the 'info' level if no BLACKLIST_LOGLEVEL was given).
diff --git a/manpages/shorewall-blacklist.xml b/manpages/shorewall-blacklist.xml
index 1eedc42f6..d35c74a51 100644
--- a/manpages/shorewall-blacklist.xml
+++ b/manpages/shorewall-blacklist.xml
@@ -72,6 +72,28 @@
from services(5).
+
+
+ OPTIONS (Optional - Added in 4.4.12) - {-|to|from|}
+
+
+ If specified, indicates whether traffic to or from
+ the ADDRESS/SUBNET should be blacklisted. The default is from. If the ADDRESS/SUBNET column is empty,
+ then this column has no effect on the generated rule.
+
+
+ Blacklisting is still restricted to traffic
+ arriving on an interface that has the
+ 'blacklist' option set. So to block traffic from your local
+ network to an internet host, you must specify
+ on your internal interface in shorewall-interfaces
+ (5).
+
+
+ When a packet arrives on an interface that has the
+
+
+ OPTIONS (Optional - Added in Shorewall 4.4.12) -
+ {-|to|from|}
+
+
+ If specified, indicates whether traffic or
+ the ADDRESS/SUBNET should be blacklisted. The
+ default is from. If the
+ ADDRESS/SUBNET column is empty, then this column has no effect on
+ the generated rule.
+
+
+ Blacklisting is still restricted to traffic
+ arriving on an interface that has the
+ 'blacklist' option set. So to block traffic from your local
+ network to an internet host, you must specify
+ on your internal interface in shorewall6-interfaces
+ (5).
+
+
+ When a packet arrives on an interface that has the