Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/blocklist TODO and ipfilter improvements from G...
details: https://anonhg.NetBSD.org/src/rev/89396771f851
branches: trunk
changeset: 953348:89396771f851
user: christos <christos%NetBSD.org@localhost>
date: Sun Mar 07 00:46:39 2021 +0000
description:
TODO and ipfilter improvements from Greg A. Woods
diffstat:
external/bsd/blocklist/TODO | 88 ++++++++++++++++-
external/bsd/blocklist/etc/rc.d/blocklistd | 4 +-
external/bsd/blocklist/libexec/blocklistd-helper | 125 +++++++++++++++++++++-
3 files changed, 205 insertions(+), 12 deletions(-)
diffs (truncated from 323 to 300 lines):
diff -r 9aabd9378307 -r 89396771f851 external/bsd/blocklist/TODO
--- a/external/bsd/blocklist/TODO Sun Mar 07 00:23:06 2021 +0000
+++ b/external/bsd/blocklist/TODO Sun Mar 07 00:46:39 2021 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: TODO,v 1.1.1.1 2020/06/15 01:52:52 christos Exp $
+# $NetBSD: TODO,v 1.2 2021/03/07 00:46:39 christos Exp $
- don't poll periodically, find the next timeout
- use the socket also for commands? Or separate socket?
@@ -19,3 +19,89 @@
unblock
- do we need an api in blocklistctl to perform maintenance
- fix the blocklistctl output to be more user friendly
+
+- figure out some way to do distributed operation securely (perhaps with
+ a helper daemon that authenticates local sockets and then communicates
+ local DB changes to the central server over a secure channel --
+ perhaps blocklistd-helper can have a back-end that can send updates to
+ a central server)
+
+- add "blocklistd -l" to enable filter logging on all rules by default
+
+- add some new options in the config file
+
+ "/all" - block both TCP and UDP (on the proto field?)
+
+ "/log" - enable filter logging (if not the default) (on the name field?)
+ "/nolog"- disable filter logging (if not the default) (on the name field?)
+
+ The latter two probably require a new parameter for blocklistd-helper.
+
+- "blocklistd -f" should (also?) be a blocklistctl function!?!?!
+
+- if blocklistd was started with '-r' then a SIGHUP should also do a
+ "control flush $rulename" and then re-add all the filter rules?
+
+- should/could /etc/rc.conf.d/ipfilter be created with the following?
+
+ reload_postcmd=blocklistd_reload
+ start_postcmd=blocklistd_start
+ stop_precmd=blocklistd_stop
+ blocklistd_reload ()
+ {
+ /etc/rc.d/blocklistd reload # IFF SIGHUP does flush/re-add
+ # /etc/rc.d/blocklistd restart
+ }
+ blocklistd_stop ()
+ {
+ /etc/rc.d/blocklistd stop
+ }
+ blocklistd_start ()
+ {
+ /etc/rc.d/blocklistd start
+ }
+
+ or is there a better way?
+
+- figure out some way to do distributed operation securely (perhaps with
+ a helper daemon that authenticates local sockets and then communicates
+ local DB changes to the central server over a secure channel --
+ perhaps blocklistd-helper can have a back-end that can send updates to
+ a central server)
+
+- add "blocklistd -l" to enable filter logging on all rules by default
+
+- add some new options in the config file
+
+ "/all" - block both TCP and UDP (on the proto field?)
+
+ "/log" - enable filter logging (if not the default) (on the name field?)
+ "/nolog"- disable filter logging (if not the default) (on the name field?)
+
+ The latter two probably require a new parameter for blocklistd-helper.
+
+- "blocklistd -f" should (also?) be a blocklistctl function!?!?!
+
+- if blocklistd was started with '-r' then a SIGHUP should also do a
+ "control flush $rulename" and then re-add all the filter rules?
+
+- should/could /etc/rc.conf.d/ipfilter be created with the following?
+
+ reload_postcmd=blocklistd_reload
+ start_postcmd=blocklistd_start
+ stop_precmd=blocklistd_stop
+ blocklistd_reload ()
+ {
+ /etc/rc.d/blocklistd reload # IFF SIGHUP does flush/re-add
+ # /etc/rc.d/blocklistd restart
+ }
+ blocklistd_stop ()
+ {
+ /etc/rc.d/blocklistd stop
+ }
+ blocklistd_start ()
+ {
+ /etc/rc.d/blocklistd start
+ }
+
+ or is there a better way?
diff -r 9aabd9378307 -r 89396771f851 external/bsd/blocklist/etc/rc.d/blocklistd
--- a/external/bsd/blocklist/etc/rc.d/blocklistd Sun Mar 07 00:23:06 2021 +0000
+++ b/external/bsd/blocklist/etc/rc.d/blocklistd Sun Mar 07 00:46:39 2021 +0000
@@ -1,10 +1,10 @@
#!/bin/sh
#
-# $NetBSD: blocklistd,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
+# $NetBSD: blocklistd,v 1.2 2021/03/07 00:46:39 christos Exp $
#
# PROVIDE: blocklistd
-# REQUIRE: npf
+# REQUIRE: npf pf ipfilter
# BEFORE: SERVERS
$_rc_subr_loaded . /etc/rc.subr
diff -r 9aabd9378307 -r 89396771f851 external/bsd/blocklist/libexec/blocklistd-helper
--- a/external/bsd/blocklist/libexec/blocklistd-helper Sun Mar 07 00:23:06 2021 +0000
+++ b/external/bsd/blocklist/libexec/blocklistd-helper Sun Mar 07 00:46:39 2021 +0000
@@ -17,7 +17,7 @@
fi
if [ -z "$pf" ]; then
- for f in npf pf ipf; do
+ for f in npf pf ipfilter; do
if [ -f "/etc/$f.conf" ]; then
pf="$f"
break
@@ -25,16 +25,26 @@
done
fi
+if [ -z "$pf" -a -x "/sbin/iptables" ]; then
+ pf="iptables"
+fi
+
if [ -z "$pf" ]; then
echo "$0: Unsupported packet filter" 1>&2
exit 1
fi
+flags=
if [ -n "$3" ]; then
+ raw_proto="$3"
proto="proto $3"
+ if [ $3 = "tcp" ]; then
+ flags="flags S/SAFR"
+ fi
fi
if [ -n "$6" ]; then
+ raw_port="$6"
port="port $6"
fi
@@ -52,11 +62,59 @@
add)
case "$pf" in
ipf)
- /sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1
- echo block in quick $proto from $addr/$mask to \
- any port=$6 head port$6 | \
- /sbin/ipf -I -f - -s >/dev/null 2>&1 && echo OK
+ # N.B.: If you reload /etc/ipf.conf then you need to stop and
+ # restart blocklistd (and make sure blocklistd_flags="-r"):
+ #
+ # /etc/rc.d/ipfilter reload
+ # /etc/rc.d/blocklistd restart
+ #
+ # XXX we assume the following rule is present in /etc/ipf.conf:
+ #
+ # block in proto tcp/udp from any to any head blocklistd
+ #
+ # where "blocklistd" is the default rulename (i.e. "$2")
+ #
+ # This rule can come before any rule that logs connections,
+ # etc., and should be followed by final rules such as:
+ #
+ # # log all as-yet unblocked incoming TCP connection
+ # # attempts
+ # log in proto tcp from any to any flags S/SAFR
+ # # last "pass" match wins for all non-blocked packets
+ # pass in all
+ # pass out all
+ #
+ # I.e. a "pass" rule which will be the final match and override
+ # the "block". This way the rules added by blocklistd will
+ # actually block packets, and prevent logging of them as
+ # connections, because they include the "quick" flag.
+ #
+ # N.b.: $port is not included -- abusers are cut off completely
+ # from all services!
+ #
+ # Note RST packets are not returned for blocked SYN packets of
+ # active attacks, so the port will not appear to be closed.
+ # This will probably give away the fact that a firewall has been
+ # triggered to block connections, but it prevents generating
+ # extra outbound traffic, and it may also slow down the attacker
+ # somewhat.
+ #
+ # Note also that we don't block all packets, just new attempts
+ # to open connections (see $flags above). This allows us to do
+ # counterespionage against the attacker (or continue to make use
+ # of any other services that might be on the same subnet as the
+ # attacker). However it does not kill any active connections --
+ # we rely on the reporting daemon to do its own protection and
+ # cleanup.
+ #
+ # N.B.: The generated must exactly match the rule generated for
+ # the "rem" command below!
+ #
+ echo block in log quick $proto \
+ from $addr/$mask to any $flags group $2 | \
+ /sbin/ipf -A -f - >/dev/null 2>&1 && echo OK
;;
+
ipfw)
# use $ipfw_offset+$port for rule number
rule=$(($ipfw_offset + $6))
@@ -69,10 +127,23 @@
table"("$tname")" to any dst-port $6 >/dev/null && \
echo OK
;;
+
+ iptables)
+ if ! /sbin/iptables --list "$2" >/dev/null 2>&1; then
+ /sbin/iptables --new-chain "$2"
+ fi
+ /sbin/iptables --append INPUT --proto "$raw_proto" \
+ --dport "$raw_port" --jump "$2"
+ /sbin/iptables --append "$2" --proto "$raw_proto" \
+ --source "$addr/$mask" --dport "$raw_port" --jump DROP
+ echo OK
+ ;;
+
npf)
/sbin/npfctl rule "$2" add block in final $proto from \
"$addr/$mask" to any $port
;;
+
pf)
# if the filtering rule does not exist, create it
/sbin/pfctl -a "$2/$6" -sr 2>/dev/null | \
@@ -83,40 +154,76 @@
/sbin/pfctl -a "$2/$6" -t "port$6" -T add "$addr/$mask" && \
echo OK
;;
+
esac
;;
rem)
case "$pf" in
ipf)
- /sbin/ipfstat -io | /sbin/ipf -I -f - >/dev/null 2>&1
- echo block in quick $proto from $addr/$mask to \
- any port=$6 head port$6 | \
- /sbin/ipf -I -r -f - -s >/dev/null 2>&1 && echo OK
+ echo block in log quick $proto \
+ from $addr/$mask to any $flags group $2 | \
+ /sbin/ipf -A -r -f - >/dev/null 2>&1 && echo OK
;;
+
ipfw)
/sbin/ipfw table "port$6" delete "$addr/$mask" 2>/dev/null && \
echo OK
;;
+
+ iptables)
+ if /sbin/iptables --list "$2" >/dev/null 2>&1; then
+ /sbin/iptables --delete "$2" --proto "$raw_proto" \
+ --source "$addr/$mask" --dport "$raw_port" \
+ --jump DROP
+ fi
+ echo OK
+ ;;
+
npf)
/sbin/npfctl rule "$2" rem-id "$7"
;;
+
pf)
/sbin/pfctl -a "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
echo OK
;;
+
esac
;;
flush)
case "$pf" in
ipf)
+ #
+ # XXX this is a slightly convoluted way to remove all the rules
+ # in the group added for "$2" (i.e. normally by default
+ # "blocklistd").
+ #
+ # N.B. WARNING: This is obviously not reentrant!
+ #
+ /sbin/ipf -I -F a
+ /usr/sbin/ipfstat -io | fgrep -v "group $2" | \
+ /sbin/ipf -I -f - >/dev/null 2>&1
+ # XXX this MUST be done last and separately as "-s" is executed
Home |
Main Index |
Thread Index |
Old Index