From owner-svn-src-vendor@freebsd.org Mon Jun 15 13:44:40 2020 Return-Path: Delivered-To: svn-src-vendor@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 332EF334463; Mon, 15 Jun 2020 13:44:40 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49lsyJ0yMRz4cSK; Mon, 15 Jun 2020 13:44:40 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 1BCD71E72D; Mon, 15 Jun 2020 13:44:40 +0000 (UTC) (envelope-from emaste@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05FDieLX067005; Mon, 15 Jun 2020 13:44:40 GMT (envelope-from emaste@FreeBSD.org) Received: (from emaste@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05FDibMt066990; Mon, 15 Jun 2020 13:44:37 GMT (envelope-from emaste@FreeBSD.org) Message-Id: <202006151344.05FDibMt066990@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: emaste set sender to emaste@FreeBSD.org using -f From: Ed Maste Date: Mon, 15 Jun 2020 13:44:37 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org Subject: svn commit: r362197 - in vendor/blocklist/dist: . bin diff etc etc/rc.d include lib libexec port test X-SVN-Group: vendor X-SVN-Commit-Author: emaste X-SVN-Commit-Paths: in vendor/blocklist/dist: . bin diff etc etc/rc.d include lib libexec port test X-SVN-Commit-Revision: 362197 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-vendor@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: SVN commit messages for the vendor work area tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 15 Jun 2020 13:44:40 -0000 Author: emaste Date: Mon Jun 15 13:44:37 2020 New Revision: 362197 URL: https://svnweb.freebsd.org/changeset/base/362197 Log: blocklist: update to 2020-06-15 snapshot Upstream hash 7093cd90cc9eae6bf9fa6b66f679ea6b15451c1e Obtained from: https://github.com/zoulasc/blocklist Sponsored by: The FreeBSD Foundation Added: vendor/blocklist/dist/diff/postfix.diff Modified: vendor/blocklist/dist/Makefile vendor/blocklist/dist/Makefile.inc vendor/blocklist/dist/README vendor/blocklist/dist/TODO vendor/blocklist/dist/bin/Makefile vendor/blocklist/dist/bin/blocklistctl.8 vendor/blocklist/dist/bin/blocklistctl.c vendor/blocklist/dist/bin/blocklistd.8 vendor/blocklist/dist/bin/blocklistd.c vendor/blocklist/dist/bin/blocklistd.conf.5 vendor/blocklist/dist/bin/conf.c vendor/blocklist/dist/bin/conf.h vendor/blocklist/dist/bin/internal.c vendor/blocklist/dist/bin/internal.h vendor/blocklist/dist/bin/run.c vendor/blocklist/dist/bin/run.h vendor/blocklist/dist/bin/state.c vendor/blocklist/dist/bin/state.h vendor/blocklist/dist/bin/support.c vendor/blocklist/dist/bin/support.h vendor/blocklist/dist/diff/ftpd.diff vendor/blocklist/dist/diff/named.diff vendor/blocklist/dist/diff/proftpd.diff vendor/blocklist/dist/diff/ssh.diff vendor/blocklist/dist/etc/Makefile vendor/blocklist/dist/etc/npf.conf vendor/blocklist/dist/etc/rc.d/Makefile vendor/blocklist/dist/etc/rc.d/blocklistd vendor/blocklist/dist/include/Makefile vendor/blocklist/dist/include/bl.h vendor/blocklist/dist/include/blocklist.h vendor/blocklist/dist/lib/Makefile vendor/blocklist/dist/lib/bl.c vendor/blocklist/dist/lib/blocklist.c vendor/blocklist/dist/lib/libblocklist.3 vendor/blocklist/dist/libexec/Makefile vendor/blocklist/dist/libexec/blocklistd-helper vendor/blocklist/dist/port/Makefile.am vendor/blocklist/dist/port/_strtoi.h vendor/blocklist/dist/port/configure.ac vendor/blocklist/dist/port/fgetln.c vendor/blocklist/dist/port/fparseln.c vendor/blocklist/dist/port/pidfile.c vendor/blocklist/dist/port/popenve.c vendor/blocklist/dist/port/port.h vendor/blocklist/dist/port/sockaddr_snprintf.c vendor/blocklist/dist/port/strlcat.c vendor/blocklist/dist/port/strlcpy.c vendor/blocklist/dist/port/strtoi.c vendor/blocklist/dist/test/Makefile vendor/blocklist/dist/test/cltest.c vendor/blocklist/dist/test/srvtest.c Modified: vendor/blocklist/dist/Makefile ============================================================================== --- vendor/blocklist/dist/Makefile Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/Makefile Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2 2015/01/22 17:49:41 christos Exp $ +# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $ SUBDIR = lib .WAIT include bin etc libexec Modified: vendor/blocklist/dist/Makefile.inc ============================================================================== --- vendor/blocklist/dist/Makefile.inc Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/Makefile.inc Mon Jun 15 13:44:37 2020 (r362197) @@ -1,9 +1,9 @@ -# $NetBSD: Makefile.inc,v 1.3 2015/01/23 03:57:22 christos Exp $ +# $NetBSD: Makefile.inc,v 1.2 2015/01/22 04:20:50 christos Exp $ WARNS=6 .if !defined(LIB) -LDADD+= -lblacklist -DPADD+= ${LIBBLACKLIST} +LDADD+= -lblocklist +DPADD+= ${LIBBLOCKLIST} .endif CPPFLAGS+= -I${.CURDIR}/../include CPPFLAGS+=-DHAVE_STRUCT_SOCKADDR_SA_LEN -DHAVE_UTIL_H -DHAVE_DB_H Modified: vendor/blocklist/dist/README ============================================================================== --- vendor/blocklist/dist/README Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/README Mon Jun 15 13:44:37 2020 (r362197) @@ -1,21 +1,21 @@ -# $NetBSD: README,v 1.8 2017/04/13 17:59:34 christos Exp $ +# $NetBSD: README,v 1.7 2015/01/26 00:34:50 christos Exp $ This package contains library that can be used by network daemons to communicate with a packet filter via a daemon to enforce opening and closing ports dynamically based on policy. -The interface to the packet filter is in libexec/blacklistd-helper +The interface to the packet filter is in libexec/blocklistd-helper (this is currently designed for npf) and the configuration file -(inspired from inetd.conf) is in etc/blacklistd.conf. +(inspired from inetd.conf) is in etc/blocklistd.conf. -On NetBSD you can find an example npf.conf and blacklistd.conf in -/usr/share/examples/blacklistd; you need to adjust the interface +On NetBSD you can find an example npf.conf and blocklistd.conf in +/usr/share/examples/blocklistd; you need to adjust the interface in npf.conf and copy both files to /etc; then you just enable -blacklistd=YES in /etc/rc.conf, start it up, and you are all set. +blocklistd=YES in /etc/rc.conf, start it up, and you are all set. -There is also a startup file in etc/rc.d/blacklistd +There is also a startup file in etc/rc.d/blocklistd -Patches to various daemons to add blacklisting capabilitiers are in the +Patches to various daemons to add blocklisting capabilitiers are in the "diff" directory: - OpenSSH: diff/ssh.diff [tcp socket example] - Bind: diff/named.diff [both tcp and udp] @@ -23,21 +23,21 @@ Patches to various daemons to add blacklisting capabil These patches have been applied to NetBSD-current. -The network daemon (for example sshd) communicates to blacklistd, via +The network daemon (for example sshd) communicates to blocklistd, via a unix socket like syslog. The library calls are simple and everything is handled by the library. In the simplest form the only thing the daemon needs to do is to call: - blacklist(action, acceptedfd, message); + blocklist(action, acceptedfd, message); Where: - action = 0 -> successful login clear blacklist state + action = 0 -> successful login clear blocklist state 1 -> failed login, add to the failed count acceptedfd -> the file descriptor where the server is connected to the remote client. It is used to determine the listening socket, and the remote address. This allows any program to - contact the blacklist daemon, since the verification + contact the blocklist daemon, since the verification if the program has access to the listening socket is done by virtue that the port number is retrieved from the kernel. @@ -46,9 +46,9 @@ Where: Unfortunately there is no way to get information about the "peer" from a udp socket, because there is no connection and that information is kept with the server. In that case the daemon can provide the -peer information to blacklistd via: +peer information to blocklistd via: - blacklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message); + blocklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message); The configuration file contains entries of the form: @@ -70,8 +70,8 @@ will let us have 2 connections before blocking. Finall for an hour; we could block forever too by specifying * in the duration column. -blacklistd and the library use syslog(3) to report errors. The -blacklist filter state is persisted automatically in /var/db/blacklistd.db +blocklistd and the library use syslog(3) to report errors. The +blocklist filter state is persisted automatically in /var/db/blocklistd.db so that if the daemon is restarted, it remembers what connections is currently handling. To start from a fresh state (if you restart npf too for example), you can use -f. To watch the daemon at work, @@ -80,25 +80,25 @@ you can use -d. The current control file is designed for npf, and it uses the dynamic rule feature. You need to create a dynamic rule in your /etc/npf.conf on the group referring to the interface you want to block -called blacklistd as follows: +called blocklistd as follows: ext_if=bge0 int_if=sk0 group "external" on $ext_if { ... - ruleset "blacklistd-ext" - ruleset "blacklistd" + ruleset "blocklistd-ext" + ruleset "blocklistd" ... } group "internal" on $int_if { ... - ruleset "blacklistd-int" + ruleset "blocklistd-int" ... } -You can use 'blacklistctl dump -a' to list all the current entries +You can use 'blocklistctl dump -a' to list all the current entries in the database; the ones that have nfail / where urrent >= otal, should have an id assosiated with them; this means that there is a packet filter rule added for that entry. For npf, you Modified: vendor/blocklist/dist/TODO ============================================================================== --- vendor/blocklist/dist/TODO Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/TODO Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -# $NetBSD: TODO,v 1.7 2015/01/23 21:34:01 christos Exp $ +# $NetBSD: TODO,v 1.6 2015/01/22 18:15:56 christos Exp $ - don't poll periodically, find the next timeout - use the socket also for commands? Or separate socket? @@ -17,5 +17,5 @@ -n block unblock -- do we need an api in blacklistctl to perform maintenance -- fix the blacklistctl output to be more user friendly +- do we need an api in blocklistctl to perform maintenance +- fix the blocklistctl output to be more user friendly Modified: vendor/blocklist/dist/bin/Makefile ============================================================================== --- vendor/blocklist/dist/bin/Makefile Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/Makefile Mon Jun 15 13:44:37 2020 (r362197) @@ -1,12 +1,12 @@ -# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 christos Exp $ +# $NetBSD: Makefile,v 1.10 2015/01/22 17:49:41 christos Exp $ BINDIR=/sbin -PROGS=blacklistd blacklistctl -MAN.blacklistd=blacklistd.8 blacklistd.conf.5 -MAN.blacklistctl=blacklistctl.8 -SRCS.blacklistd = blacklistd.c conf.c run.c state.c support.c internal.c -SRCS.blacklistctl = blacklistctl.c conf.c state.c support.c internal.c +PROGS=blocklistd blocklistctl +MAN.blocklistd=blocklistd.8 blocklistd.conf.5 +MAN.blocklistctl=blocklistctl.8 +SRCS.blocklistd = blocklistd.c conf.c run.c state.c support.c internal.c +SRCS.blocklistctl = blocklistctl.c conf.c state.c support.c internal.c DBG=-g LDADD+=-lutil Modified: vendor/blocklist/dist/bin/blocklistctl.8 ============================================================================== --- vendor/blocklist/dist/bin/blocklistctl.8 Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/blocklistctl.8 Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistctl.8,v 1.9 2016/06/08 12:48:37 wiz Exp $ +.\" $NetBSD: blocklistctl.8,v 1.8 2016/06/07 17:31:02 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -28,11 +28,11 @@ .\" POSSIBILITY OF SUCH DAMAGE. .\" .Dd June 7, 2016 -.Dt BLACKLISTCTL 8 +.Dt BLOCKLISTCTL 8 .Os .Sh NAME -.Nm blacklistctl -.Nd display and change the state of blacklistd +.Nm blocklistctl +.Nd display and change the state of blocklistd .Sh SYNOPSIS .Nm .Cm dump @@ -40,7 +40,7 @@ .Sh DESCRIPTION .Nm is a program used to display the state of -.Xr blacklistd 8 +.Xr blocklistd 8 .Pp The following options are available: .Bl -tag -width indent @@ -60,17 +60,17 @@ Normally the width of addresses is good for IPv4, the flag, makes the display wide enough for IPv6 addresses. .El .Sh SEE ALSO -.Xr blacklistd 8 +.Xr blocklistd 8 .Sh NOTES Sometimes the reported number of failed attempts can exceed the number of attempts that -.Xr blacklistd 8 +.Xr blocklistd 8 is configured to block. This can happen either because the rule has been removed manually, or because there were more attempts in flight while the rule block was being added. This condition is normal; in that case -.Xr blacklistd 8 +.Xr blocklistd 8 will first attempt to remove the existing rule, and then it will re-add it to make sure that there is only one rule active. .Sh HISTORY Modified: vendor/blocklist/dist/bin/blocklistctl.c ============================================================================== --- vendor/blocklist/dist/bin/blocklistctl.c Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/blocklistctl.c Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $ */ +/* $NetBSD: blocklistctl.c,v 1.22 2018/05/24 19:19:37 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include -__RCSID("$NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $"); +__RCSID("$NetBSD: blocklistctl.c,v 1.22 2018/05/24 19:19:37 christos Exp $"); #include #include Modified: vendor/blocklist/dist/bin/blocklistd.8 ============================================================================== --- vendor/blocklist/dist/bin/blocklistd.8 Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/blocklistd.8 Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.8,v 1.18 2016/07/30 06:09:29 dholland Exp $ +.\" $NetBSD: blocklistd.8,v 1.23 2020/04/21 13:57:12 christos Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,11 +27,11 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 7, 2016 -.Dt BLACKLISTD 8 +.Dd April 21, 2020 +.Dt BLOCKLISTD 8 .Os .Sh NAME -.Nm blacklistd +.Nm blocklistd .Nd block and release ports on demand to avoid DoS abuse .Sh SYNOPSIS .Nm @@ -55,16 +55,52 @@ If no such file is specified, then it only listens to specified by .Ar sockspath or if that is not specified to -.Pa /var/run/blacklistd.sock . +.Pa /var/run/blocklistd.sock . Each notification contains an (action, port, protocol, address, owner) tuple that identifies the remote connection and the action. This tuple is consulted against entries in .Ar configfile with syntax specified in -.Xr blacklistd.conf 5 . +.Xr blocklistd.conf 5 . If an entry is matched, a state entry is created for that tuple. Each entry contains a number of tries limit and a duration. .Pp +The way +.Nm +does configuration entry matching is by having the client side pass the +file descriptor associated with the connection the client wants to blocklist +as well as passing socket credentials. +.Pp +The file descriptor is used to retrieve information (address and port) +about the remote side with +.Xr getpeername 2 +and the local side with +.Xr getsockname 2 . +.Pp +By examining the port of the local side, +.Nm +can determine if the client program +.Dq owns +the port. +By examining the optional address portion on the local side, it can match +interfaces. +By examining the remote address, it can match specific allow or deny rules. +.Pp +Finally +.Nm +can examine the socket credentials to match the user in the configuration file. +.Pp +While this works well for TCP sockets, it cannot be relied on for unbound +UDP sockets. +It is also less meaningful when it comes to connections using non-privileged +ports. +On the other hand, if we receive a request that has a local endpoint indicating +a UDP privileged port, we can presume that the client was privileged to be +able to acquire that port. +.Pp +Once an entry is matched +.Nm +can perform various actions. If the action is .Dq add and the number of tries limit is reached, then a @@ -80,17 +116,17 @@ specified by the arguments. The .Ar rulename argument can be set from the command line (default -.Dv blacklistd ) . +.Dv blocklistd ) . The script could print a numerical id to stdout as a handle for the rule that can be used later to remove that connection, but that is not required as all information to remove the rule is kept. .Pp If the action is -.Dq remove +.Dq rem Then the same control script is invoked as: .Bd -literal -offset indent -control remove
+control rem
.Ed .Pp where @@ -117,7 +153,7 @@ The following options are available: Use .Ar controlprog to communicate with the packet filter, usually -.Pa /libexec/blacklistd-helper . +.Pa /libexec/blocklistd-helper . The following arguments are passed to the control program: .Bl -tag -width protocol .It action @@ -148,12 +184,12 @@ The add command is expected to return the rule identif .El .It Fl c Ar configuration The name of the configuration file to read, usually -.Pa /etc/blacklistd.conf . +.Pa /etc/blocklistd.conf . .It Fl D Ar dbfile The Berkeley DB file where .Nm stores its state, usually -.Pa /var/run/blacklistd.db . +.Pa /var/db/blocklistd.db . .It Fl d Normally, .Nm @@ -174,11 +210,11 @@ will create sockets to listen to. This is useful for chrooted environments. .It Fl R Ar rulename Specify the default rule name for the packet filter rules, usually -.Dv blacklistd . +.Dv blocklistd . .It Fl r Re-read the firewall rules from the internal database, then remove and re-add them. -This helps for packet filters that don't retain state across reboots. +This helps for packet filters that do not retain state across reboots. .It Fl s Ar sockpath Add .Ar sockpath @@ -198,20 +234,41 @@ diagnostic messages to instead of .Xr syslogd 8 . .El +.Sh SIGNAL HANDLING +.Nm +deals with the following signals: +.Bl -tag -width "USR2" +.It Dv HUP +Receipt of this signal causes +.Nm +to re-read the configuration file. +.It Dv INT , Dv TERM & Dv QUIT +These signals tell +.Nm +to exit in an orderly fashion. +.It Dv USR1 +This signal tells +.Nm +to increase the internal debugging level by 1. +.It Dv USR2 +This signal tells +.Nm +to decrease the internal debugging level by 1. +.El .Sh FILES -.Bl -tag -width /libexec/blacklistd-helper -compact -.It Pa /libexec/blacklistd-helper +.Bl -tag -width /libexec/blocklistd-helper -compact +.It Pa /libexec/blocklistd-helper Shell script invoked to interface with the packet filter. -.It Pa /etc/blacklistd.conf +.It Pa /etc/blocklistd.conf Configuration file. -.It Pa /var/db/blacklistd.db +.It Pa /var/db/blocklistd.db Database of current connection entries. -.It Pa /var/run/blacklistd.sock +.It Pa /var/run/blocklistd.sock Socket to receive connection notifications. .El .Sh SEE ALSO -.Xr blacklistd.conf 5 , -.Xr blacklistctl 8 , +.Xr blocklistd.conf 5 , +.Xr blocklistctl 8 , .Xr npfctl 8 , .Xr syslogd 8 .Sh HISTORY Modified: vendor/blocklist/dist/bin/blocklistd.c ============================================================================== --- vendor/blocklist/dist/bin/blocklistd.c Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/blocklistd.c Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -/* $NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $ */ +/* $NetBSD: blocklistd.c,v 1.42 2020/03/11 02:33:18 roy Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ #include "config.h" #endif #include -__RCSID("$NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $"); +__RCSID("$NetBSD: blocklistd.c,v 1.42 2020/03/11 02:33:18 roy Exp $"); #include #include @@ -123,7 +123,7 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storag return 0; if (errno != ENOTCONN) { - (*lfun)(LOG_ERR, "getpeername failed (%m)"); + (*lfun)(LOG_ERR, "getpeername failed (%m)"); return -1; } @@ -141,13 +141,13 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storag break; default: (*lfun)(LOG_ERR, "bad client passed socket family %u", - (unsigned)bi->bi_ss.ss_family); + (unsigned)bi->bi_ss.ss_family); return -1; } if (*rsl != bi->bi_slen) { (*lfun)(LOG_ERR, "bad client passed socket length %u != %u", - (unsigned)*rsl, (unsigned)bi->bi_slen); + (unsigned)*rsl, (unsigned)bi->bi_slen); return -1; } @@ -157,7 +157,7 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storag if (*rsl != rss->ss_len) { (*lfun)(LOG_ERR, "bad client passed socket internal length %u != %u", - (unsigned)*rsl, (unsigned)rss->ss_len); + (unsigned)*rsl, (unsigned)rss->ss_len); return -1; } #endif @@ -176,12 +176,12 @@ process(bl_t bl) struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { - (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); + (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); return; } if ((bi = bl_recv(bl)) == NULL) { - (*lfun)(LOG_ERR, "no message (%m)"); + (*lfun)(LOG_ERR, "no message (%m)"); return; } @@ -214,33 +214,38 @@ process(bl_t bl) } switch (bi->bi_type) { + case BL_ABUSE: + /* + * If the application has signaled abusive behavior, + * set the number of fails to be one less than the + * configured limit. Fallthrough to the normal BL_ADD + * processing, which will increment the failure count + * to the threshhold, and block the abusive address. + */ + if (c.c_nfail != -1) + dbi.count = c.c_nfail - 1; + /*FALLTHROUGH*/ case BL_ADD: dbi.count++; dbi.last = ts.tv_sec; - if (dbi.id[0]) { + if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { /* - * We should not be getting this since the rule - * should have blocked the address. A possible - * explanation is that someone removed that rule, - * and another would be that we got another attempt - * before we added the rule. In anycase, we remove - * and re-add the rule because we don't want to add - * it twice, because then we'd lose track of it. + * No point in re-adding the rule. + * It might exist already due to latency in processing + * and removing the rule is the wrong thing to do as + * it allows a window to attack again. */ - (*lfun)(LOG_DEBUG, "rule exists %s", dbi.id); - (void)run_change("rem", &c, dbi.id, 0); - dbi.id[0] = '\0'; - } - if (c.c_nfail != -1 && dbi.count >= c.c_nfail) { - int res = run_change("add", &c, dbi.id, sizeof(dbi.id)); - if (res == -1) - goto out; + if (dbi.id[0] == '\0') { + int res = run_change("add", &c, + dbi.id, sizeof(dbi.id)); + if (res == -1) + goto out; + } sockaddr_snprintf(rbuf, sizeof(rbuf), "%a", (void *)&rss); (*lfun)(LOG_INFO, "blocked %s/%d:%d for %d seconds", rbuf, c.c_lmask, c.c_port, c.c_duration); - } break; case BL_DELETE: @@ -249,8 +254,11 @@ process(bl_t bl) dbi.count = 0; dbi.last = 0; break; + case BL_BADUSER: + /* ignore for now */ + break; default: - (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); + (*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); } state_put(state, &c, &dbi); @@ -292,7 +300,7 @@ update(void) void *ss = &c.c_ss; if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { - (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); + (*lfun)(LOG_ERR, "clock_gettime failed (%m)"); return; } Modified: vendor/blocklist/dist/bin/blocklistd.conf.5 ============================================================================== --- vendor/blocklist/dist/bin/blocklistd.conf.5 Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/blocklistd.conf.5 Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -.\" $NetBSD: blacklistd.conf.5,v 1.7 2017/06/07 13:50:57 wiz Exp $ +.\" $NetBSD: blocklistd.conf.5,v 1.9 2019/11/06 20:33:30 para Exp $ .\" .\" Copyright (c) 2015 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -27,17 +27,17 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd June 5, 2017 -.Dt BLACKLISTD.CONF 5 +.Dd May 18, 2020 +.Dt BLOCKLISTD.CONF 5 .Os .Sh NAME -.Nm blacklistd.conf -.Nd configuration file format for blacklistd +.Nm blocklistd.conf +.Nd configuration file format for blocklistd .Sh DESCRIPTION The .Nm -files contains configuration entries for -.Xr blacklistd 8 +file contains configuration entries for +.Xr blocklistd 8 in a fashion similar to .Xr inetd.conf 5 . Only one entry per line is permitted. @@ -125,18 +125,18 @@ The second field is the socket .Dv dgram , or numeric. The third field is the -.Va prococol : +.Va protocol : .Dv tcp , .Dv udp , .Dv tcp6 , .Dv udp6 , or numeric. -The fourth file is the effective user +The fourth field is the effective user .Va ( owner ) of the daemon process reporting the event, either as a username or a userid. .Pp -The rest of the fields are controlling the behavior of the filter. +The rest of the fields control the behavior of the filter. .Pp The .Va name @@ -192,12 +192,12 @@ rule that matched. .Pp The .Va remote -rules can be used for whitelisting specific addresses, changing the mask +rules can be used for allowing specific addresses, changing the mask size, the rule that the packet filter uses, the number of failed attempts, or the block duration. .Sh FILES -.Bl -tag -width /etc/blacklistd.conf -compact -.It Pa /etc/blacklistd.conf +.Bl -tag -width /etc/blocklistd.conf -compact +.It Pa /etc/blocklistd.conf Configuration file. .El .Sh EXAMPLES @@ -214,8 +214,8 @@ bnx0:ssh * * * * 3 6h 8.8.0.0/16:ssh * * * /24 = = .Ed .Sh SEE ALSO -.Xr blacklistctl 8 , -.Xr blacklistd 8 +.Xr blocklistctl 8 , +.Xr blocklistd 8 .Sh HISTORY .Nm first appeared in Modified: vendor/blocklist/dist/bin/conf.c ============================================================================== --- vendor/blocklist/dist/bin/conf.c Mon Jun 15 13:17:22 2020 (r362196) +++ vendor/blocklist/dist/bin/conf.c Mon Jun 15 13:44:37 2020 (r362197) @@ -1,4 +1,4 @@ -/* $NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $ */ +/* $NetBSD: conf.c,v 1.30 2020/03/12 19:47:32 christos Exp $ */ /*- * Copyright (c) 2015 The NetBSD Foundation, Inc. @@ -33,7 +33,7 @@ #endif #include -__RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $"); +__RCSID("$NetBSD: conf.c,v 1.30 2020/03/12 19:47:32 christos Exp $"); #include #ifdef HAVE_LIBUTIL_H @@ -46,6 +46,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 ch #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 ch #include #include #include +#include #include #include "bl.h" @@ -90,7 +92,7 @@ advance(char **p) } static int -getnum(const char *f, size_t l, bool local, void *rp, const char *name, +conf_getnum(const char *f, size_t l, bool local, void *rp, const char *name, const char *p) { int e; @@ -127,13 +129,14 @@ out: } static int -getnfail(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_getnfail(const char *f, size_t l, bool local, struct conf *c, + const char *p) { - return getnum(f, l, local, &c->c_nfail, "nfail", p); + return conf_getnum(f, l, local, &c->c_nfail, "nfail", p); } static int -getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_getsecs(const char *f, size_t l, bool local, struct conf *c, const char *p) { int e; char *ep; @@ -173,9 +176,9 @@ again: } break; } - } else + } else tot = im; - + if (e == 0) { c->c_duration = (int)tot; return 0; @@ -193,7 +196,7 @@ out: } static int -getport(const char *f, size_t l, bool local, void *r, const char *p) +conf_getport(const char *f, size_t l, bool local, void *r, const char *p) { struct servent *sv; @@ -207,14 +210,14 @@ getport(const char *f, size_t l, bool local, void *r, return 0; } - return getnum(f, l, local, r, "service", p); + return conf_getnum(f, l, local, r, "service", p); } static int -getmask(const char *f, size_t l, bool local, const char **p, int *mask) +conf_getmask(const char *f, size_t l, bool local, const char **p, int *mask) { char *d; - const char *s = *p; + const char *s = *p; if ((d = strchr(s, ':')) != NULL) { *d++ = '\0'; @@ -226,11 +229,12 @@ getmask(const char *f, size_t l, bool local, const cha } *d++ = '\0'; - return getnum(f, l, local, mask, "mask", d); + return conf_getnum(f, l, local, mask, "mask", d); } static int -gethostport(const char *f, size_t l, bool local, struct conf *c, const char *p) +conf_gethostport(const char *f, size_t l, bool local, struct conf *c, + const char *p) { char *d; // XXX: Ok to write to string. in_port_t *port = NULL; @@ -249,7 +253,7 @@ gethostport(const char *f, size_t l, bool local, struc } else pstr = p; - if (getmask(f, l, local, &pstr, &c->c_lmask) == -1) + if (conf_getmask(f, l, local, &pstr, &c->c_lmask) == -1) goto out; if (d) { @@ -264,7 +268,7 @@ gethostport(const char *f, size_t l, bool local, struc sin6->sin6_len = sizeof(*sin6); #endif port = &sin6->sin6_port; - } + } } else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) { if (pstr == p) pstr = "*"; @@ -300,7 +304,7 @@ gethostport(const char *f, size_t l, bool local, struc } } - if (getport(f, l, local, &c->c_port, pstr) == -1) + if (conf_getport(f, l, local, &c->c_port, pstr) == -1) return -1; if (port && c->c_port != FSTAR && c->c_port != FEQUAL) @@ -320,7 +324,7 @@ out2: } static int -getproto(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getproto(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { if (strcmp(p, "stream") == 0) { @@ -331,22 +335,22 @@ getproto(const char *f, size_t l, bool local __unused, c->c_proto = IPPROTO_UDP; return 0; } - return getnum(f, l, local, &c->c_proto, "protocol", p); + return conf_getnum(f, l, local, &c->c_proto, "protocol", p); } static int -getfamily(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getfamily(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { if (strncmp(p, "tcp", 3) == 0 || strncmp(p, "udp", 3) == 0) { c->c_family = p[3] == '6' ? AF_INET6 : AF_INET; return 0; } - return getnum(f, l, local, &c->c_family, "family", p); + return conf_getnum(f, l, local, &c->c_family, "family", p); } static int -getuid(const char *f, size_t l, bool local __unused, struct conf *c, +conf_getuid(const char *f, size_t l, bool local __unused, struct conf *c, const char *p) { struct passwd *pw; @@ -356,21 +360,22 @@ getuid(const char *f, size_t l, bool local __unused, s return 0; } - return getnum(f, l, local, &c->c_uid, "user", p); + return conf_getnum(f, l, local, &c->c_uid, "user", p); } static int -getname(const char *f, size_t l, bool local, struct conf *c, +conf_getname(const char *f, size_t l, bool local, struct conf *c, const char *p) { - if (getmask(f, l, local, &p, &c->c_rmask) == -1) + if (conf_getmask(f, l, local, &p, &c->c_rmask) == -1) return -1; - + if (strcmp(p, "*") == 0) { strlcpy(c->c_name, rulename, CONFNAMESZ); return 0; } + if (strcmp(p, "=") == 0) { if (local) goto out; @@ -406,19 +411,19 @@ conf_parseline(const char *f, size_t l, char *p, struc p++; memset(c, 0, sizeof(*c)); - e = getvalue(f, l, local, c, &p, gethostport); + e = getvalue(f, l, local, c, &p, conf_gethostport); if (e) return -1; - e = getvalue(f, l, local, c, &p, getproto); + e = getvalue(f, l, local, c, &p, conf_getproto); if (e) return -1; - e = getvalue(f, l, local, c, &p, getfamily); + e = getvalue(f, l, local, c, &p, conf_getfamily); if (e) return -1; - e = getvalue(f, l, local, c, &p, getuid); + e = getvalue(f, l, local, c, &p, conf_getuid); if (e) return -1; - e = getvalue(f, l, local, c, &p, getname); + e = getvalue(f, l, local, c, &p, conf_getname); if (e) return -1; - e = getvalue(f, l, local, c, &p, getnfail); + e = getvalue(f, l, local, c, &p, conf_getnfail); if (e) return -1; - e = getvalue(f, l, local, c, &p, getsecs); + e = getvalue(f, l, local, c, &p, conf_getsecs); if (e) return -1; return 0; @@ -473,7 +478,6 @@ conf_amask_eq(const void *v1, const void *v2, size_t l return 1; goto out; case FEQUAL: - (*lfun)(LOG_CRIT, "%s: Internal error: bad mask %d", __func__, mask); abort(); @@ -687,7 +691,7 @@ conf_addr_eq(const struct sockaddr_storage *s1, static int conf_eq(const struct conf *c1, const struct conf *c2) { - + if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, c2->c_lmask)) return 0; @@ -744,7 +748,7 @@ fmtport(char *b, size_t l, int port) if (port == FSTAR) return; - if (b[0] == '\0' || strcmp(b, "*") == 0) + if (b[0] == '\0' || strcmp(b, "*") == 0) snprintf(b, l, "%d", port); else { snprintf(buf, sizeof(buf), ":%d", port); @@ -820,7 +824,7 @@ conf_print(char *buf, size_t len, const char *pref, co fmtmask(ha, sizeof(ha), c->c_family, c->c_lmask); fmtport(ha, sizeof(ha), c->c_port); - + sp = *delim == '\t' ? 20 : -1; hb[0] = '\0'; if (*delim) @@ -878,7 +882,7 @@ conf_merge(struct conf *c, const struct conf *sc) (*lfun)(LOG_DEBUG, "%s: %s", __func__, conf_print(buf, sizeof(buf), "to:\t", "", c)); } - + if (sc->c_name[0]) memcpy(c->c_name, sc->c_name, CONFNAMESZ); if (sc->c_uid != FEQUAL) @@ -998,32 +1002,73 @@ confset_match(const struct confset *cs, struct conf *c return i; } -const struct conf * -conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss, - struct conf *cr) -{ - int proto; - socklen_t slen; - struct sockaddr_storage lss; - size_t i; - char buf[BUFSIZ]; +#ifdef AF_ROUTE +static int +conf_route_perm(int fd) { +/* Disable for now, the access check in the routing socket uses curlwp */ +#if defined(RTM_IFANNOUNCE) && defined(RT_ROUNDUP) + /* + * Send a routing message that is not supported to check for access + * We expect EOPNOTSUPP for having access, since we are sending a + * request the system does not understand and EACCES if we don't have + * access. + */ + static struct sockaddr_in sin = { +#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN + .sin_len = sizeof(sin), +#endif + .sin_family = AF_INET, + }; + char buf[4096]; + struct rt_msghdr *rtm = (void *)buf; + char *cp = (char *)(rtm + 1); + size_t l; - memset(cr, 0, sizeof(*cr)); - slen = sizeof(lss); - memset(&lss, 0, slen); - if (getsockname(fd, (void *)&lss, &slen) == -1) { - (*lfun)(LOG_ERR, "getsockname failed (%m)"); - return NULL; +#define NEXTADDR(s) \ + l = RT_ROUNDUP(sizeof(*s)); memmove(cp, s, l); cp += l; + memset(buf, 0, sizeof(buf)); + rtm->rtm_type = RTM_IFANNOUNCE; + rtm->rtm_flags = 0; + rtm->rtm_addrs = RTA_DST|RTA_GATEWAY; + rtm->rtm_version = RTM_VERSION; + rtm->rtm_seq = 666; + NEXTADDR(&sin); + NEXTADDR(&sin); + rtm->rtm_msglen = (u_short)((char *)cp - (char *)rtm); + if (write(fd, rtm, rtm->rtm_msglen) != -1) { + (*lfun)(LOG_ERR, "Writing to routing socket succeeded!"); + return 0; } + switch (errno) { + case EACCES: + return 0; + case EOPNOTSUPP: + return 1; + default: + (*lfun)(LOG_ERR, + "Unexpected error writing to routing socket (%m)"); + return 0; + } +#else + return 0; +#endif +} +#endif *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***