TODO and ipfilter improvements from Greg A. Woods
This commit is contained in:
parent
f525b84e77
commit
0449daef3f
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,7 +17,7 @@ if [ -f "/etc/ipfw-blocklist.rc" ]; then
|
|||
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 @@ if [ -z "$pf" ]; then
|
|||
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 @@ case "$1" in
|
|||
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 @@ add)
|
|||
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 @@ add)
|
|||
/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
|
||||
# _while_ the command arguments are being processed!
|
||||
/sbin/ipf -s && echo OK
|
||||
/sbin/ipf -Z -I -Fi -s > /dev/null && echo OK
|
||||
;;
|
||||
|
||||
ipfw)
|
||||
/sbin/ipfw table "port$6" flush 2>/dev/null && echo OK
|
||||
;;
|
||||
|
||||
iptables)
|
||||
if /sbin/iptables --list "$2" >/dev/null 2>&1; then
|
||||
/sbin/iptables --flush "$2"
|
||||
fi
|
||||
echo OK
|
||||
;;
|
||||
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" flush
|
||||
;;
|
||||
|
||||
pf)
|
||||
/sbin/pfctl -a "$2/$6" -t "port$6" -T flush && echo OK
|
||||
;;
|
||||
|
|
Loading…
Reference in New Issue