MFV: Import blocklist 2025-04-28 (8aa81bf)
Merge commit '70f30afd4e9af5a51ee324d97e4d8c5f2124ec15'
Breaking changes:
- Upstream commit 24932b6 ("blocklistd: log the conf file line number
with bad protocol errors") breaks backward database compatibility.
An error will be displayed:
Key size mismatch 296 != 288
A new and compatible database, with the new name, will be created when the
service starts (committed separately).
- Upstream commit ddf6d71 ("implement BLOCKLIST_BAD_USER as a
"one-count" failure") introduced BLOCKLIST_BAD_USER with a one-count
failure mechanism. BLOCKLIST_AUTH_FAIL was implemented with a
two-count failure mechanism. Since we utilize BLOCKLIST_AUTH_FAIL, the
number of failed attempts now doubles towards the maximum limit
(nfails). This commit will be reverted separately.
Changes:
https://github.com/zoulasc/blocklist/compare/7093cd9...8aa81bf
Approved by: emaste (mentor)
MFC after: 2 days
Differential Revision: https://reviews.freebsd.org/D52869
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.2 2015/01/22 17:49:41 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:52 christos Exp $
|
||||
|
||||
SUBDIR = lib .WAIT include bin etc libexec
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
# $NetBSD: Makefile.inc,v 1.3 2015/01/23 03:57:22 christos Exp $
|
||||
# $NetBSD: Makefile.inc,v 1.3 2025/02/11 17:48:30 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
|
||||
CPPFLAGS+=-DHAVE_SYS_CDEFS_H
|
||||
|
||||
|
||||
+26
-26
@@ -1,21 +1,21 @@
|
||||
# $NetBSD: README,v 1.8 2017/04/13 17:59:34 christos Exp $
|
||||
# $NetBSD: README,v 1.3 2024/02/09 00:53:30 wiz 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 capabilities 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 capabilitiers are in the
|
||||
|
||||
These patches have been applied to NetBSD-current.
|
||||
|
||||
The network daemon (for example sshd) communicates to blacklistd, via
|
||||
a unix socket like syslog. The library calls are simple and everything
|
||||
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,13 +46,13 @@ 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:
|
||||
|
||||
# Blacklist rule
|
||||
# Blocklist rule
|
||||
# host/Port type protocol owner name nfail disable
|
||||
192.168.1.1:ssh stream tcp * -int 10 1m
|
||||
8.8.8.8:ssh stream tcp * -ext 6 60m
|
||||
@@ -60,18 +60,18 @@ ssh stream tcp6 * * 6 60m
|
||||
http stream tcp * * 6 60m
|
||||
|
||||
Here note that owner is * because the connection is done from the
|
||||
child ssh socket which runs with user privs. We treat ipv4 connections
|
||||
child ssh socket which runs with user privs. We treat IPv4 connections
|
||||
differently by maintaining two different rules one for the external
|
||||
interface and one from the internal We also register for both tcp
|
||||
and tcp6 since those are different listening sockets and addresses;
|
||||
we don't bother with ipv6 and separate rules. We use nfail = 6,
|
||||
we don't bother with IPv6 and separate rules. We use nfail = 6,
|
||||
because ssh allows 3 password attempts per connection, and this
|
||||
will let us have 2 connections before blocking. Finally we block
|
||||
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,27 +80,27 @@ 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 <c>/<t> where <c>urrent
|
||||
>= <t>otal, should have an id assosiated with them; this means that
|
||||
>= <t>otal, should have an id associated with them; this means that
|
||||
there is a packet filter rule added for that entry. For npf, you
|
||||
can examine the packet filter dynamic rule entries using 'npfctl
|
||||
rule <rulename> list'. The number of current entries can exceed
|
||||
|
||||
+46
-3
@@ -1,4 +1,4 @@
|
||||
# $NetBSD: TODO,v 1.7 2015/01/23 21:34:01 christos Exp $
|
||||
# $NetBSD: TODO,v 1.3 2025/02/05 20:22:26 christos Exp $
|
||||
|
||||
- don't poll periodically, find the next timeout
|
||||
- use the socket also for commands? Or separate socket?
|
||||
@@ -17,5 +17,48 @@
|
||||
-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
|
||||
|
||||
- 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,12 +1,12 @@
|
||||
# $NetBSD: Makefile,v 1.11 2015/01/27 19:40:36 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:52 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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: blacklistctl.8,v 1.9 2016/06/08 12:48:37 wiz Exp $
|
||||
.\" $NetBSD: blocklistctl.8,v 1.4 2025/02/07 01:35:38 kre Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
@@ -27,27 +27,43 @@
|
||||
.\" 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 BLACKLISTCTL 8
|
||||
.Dd January 27, 2025
|
||||
.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 the blocklistd database
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Cm dump
|
||||
.Op Fl abdnrw
|
||||
.Op Fl D Ar dbname
|
||||
.Sh DESCRIPTION
|
||||
.Nm
|
||||
is a program used to display the state of
|
||||
.Xr blacklistd 8
|
||||
is a program used to display and change the state of the
|
||||
.Xr blocklistd 8
|
||||
database.
|
||||
The following sub-commands are supported:
|
||||
.Ss dump
|
||||
.Pp
|
||||
The following options are available:
|
||||
The following options are available for the
|
||||
.Cm dump
|
||||
sub-command:
|
||||
.Bl -tag -width indent
|
||||
.It Fl a
|
||||
Show all database entries, by default it shows only the embryonic ones.
|
||||
Show all database entries, by default it shows only the active ones.
|
||||
Inactive entries will be shown with a last-access (or, with
|
||||
.Fl r ,
|
||||
the remaining) time of
|
||||
.Ql never .
|
||||
.It Fl b
|
||||
Show only the blocked entries.
|
||||
.It Fl D Ar dbname
|
||||
Specify the location of the
|
||||
.Ic blocklistd
|
||||
database file to use.
|
||||
The default is
|
||||
.Pa /var/db/blocklistd.db .
|
||||
.It Fl d
|
||||
Increase debugging level.
|
||||
.It Fl n
|
||||
@@ -59,18 +75,47 @@ Normally the width of addresses is good for IPv4, the
|
||||
.Fl w
|
||||
flag, makes the display wide enough for IPv6 addresses.
|
||||
.El
|
||||
.Pp
|
||||
The output of the
|
||||
.Cm dump
|
||||
sub-command consists of a header (unless
|
||||
.Fl n
|
||||
was given) and one line for each record in the database, where each line
|
||||
has the following columns:
|
||||
.Bl -tag -width indent
|
||||
.It Ql address/ma:port
|
||||
The remote address, mask, and local port number of the client connection
|
||||
associated with the database entry.
|
||||
.It Ql id
|
||||
column will show the identifier for the packet filter rule associated
|
||||
with the database entry, though this may only be the word
|
||||
.Ql OK
|
||||
for packet filters which do not creat a unique identifier for each rule.
|
||||
.It Ql nfail
|
||||
The number of
|
||||
.Em failures
|
||||
reported for the client on the noted port, as well as the number of
|
||||
failures allowed before blocking (or, with
|
||||
.Fl a ,
|
||||
an asterisk
|
||||
.Aq * )
|
||||
.It So last access Sc | So remaining time Sc
|
||||
The last time a the client was reported as attempting access, or, with
|
||||
.Fl r ,
|
||||
the time remaining before the rule blocking the client will be removed.
|
||||
.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
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $ */
|
||||
/* $NetBSD: blocklistctl.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklistctl.c,v 1.23 2018/05/24 19:21:01 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: blocklistctl.c,v 1.4 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@@ -63,7 +65,8 @@ usage(int c)
|
||||
warnx("Missing/unknown command");
|
||||
else if (c != '?')
|
||||
warnx("Unknown option `%c'", (char)c);
|
||||
fprintf(stderr, "Usage: %s dump [-abdnrw]\n", getprogname());
|
||||
fprintf(stderr,
|
||||
"Usage: %s dump [-abdnrw] [-D dbname]\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: blacklistd.8,v 1.23 2020/04/21 13:57:12 christos Exp $
|
||||
.\" $NetBSD: blocklistd.8,v 1.8 2025/02/25 22:13:34 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 April 21, 2020
|
||||
.Dt BLACKLISTD 8
|
||||
.Dd February 25, 2025
|
||||
.Dt BLOCKLISTD 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklistd
|
||||
.Nm blocklistd
|
||||
.Nd block and release ports on demand to avoid DoS abuse
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
@@ -53,22 +53,35 @@ for notifications from other daemons about successful or failed connection
|
||||
attempts.
|
||||
If no such file is specified, then it only listens to the socket path
|
||||
specified by
|
||||
.Ar sockspath
|
||||
.Ar sockpath
|
||||
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 .
|
||||
This tuple is consulted against entries from the
|
||||
.Ar configfile ,
|
||||
with the syntax specified in
|
||||
.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
|
||||
If
|
||||
.Ar configfile
|
||||
is a directory, or a directory exists with the same name as
|
||||
.Ar configfile
|
||||
with
|
||||
.Qq .d
|
||||
appended to it, each file in the directory will be read as configuration file.
|
||||
If
|
||||
.Ar configfile
|
||||
exists as a file it will be processed before the contents of the
|
||||
.Ar configfile Ns .d
|
||||
directory if that also exists.
|
||||
.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 blacklist
|
||||
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)
|
||||
@@ -116,7 +129,7 @@ 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
|
||||
@@ -152,8 +165,8 @@ The following options are available:
|
||||
.It Fl C Ar controlprog
|
||||
Use
|
||||
.Ar controlprog
|
||||
to communicate with the packet filter, usually
|
||||
.Pa /usr/libexec/blacklistd-helper .
|
||||
to communicate with the packet filter, instead of the default, which is
|
||||
.Pa /usr/libexec/blocklistd-helper .
|
||||
The following arguments are passed to the control program:
|
||||
.Bl -tag -width protocol
|
||||
.It action
|
||||
@@ -161,7 +174,7 @@ The action to perform:
|
||||
.Dv add ,
|
||||
.Dv rem ,
|
||||
or
|
||||
.Dv flush
|
||||
.Dv flush ;
|
||||
to add, remove or flush a firewall rule.
|
||||
.It name
|
||||
The rule name.
|
||||
@@ -183,13 +196,17 @@ identifier of the rule to be removed.
|
||||
The add command is expected to return the rule identifier string to stdout.
|
||||
.El
|
||||
.It Fl c Ar configuration
|
||||
The name of the configuration file to read, usually
|
||||
.Pa /etc/blacklistd.conf .
|
||||
The name of the configuration file to read.
|
||||
The default when
|
||||
.Fl c
|
||||
is not given is
|
||||
.Pa /etc/blocklistd.conf .
|
||||
.It Fl D Ar dbfile
|
||||
The Berkeley DB file where
|
||||
.Nm
|
||||
stores its state, usually
|
||||
.Pa /var/db/blacklistd.db .
|
||||
stores its state.
|
||||
It defaults to
|
||||
.Pa /var/db/blocklistd.db .
|
||||
.It Fl d
|
||||
Normally,
|
||||
.Nm
|
||||
@@ -203,14 +220,14 @@ are deleted by invoking the control script as:
|
||||
.Bd -literal -offset indent
|
||||
control flush <rulename>
|
||||
.Ed
|
||||
.It Fl P Ar sockspathsfile
|
||||
.It Fl P Ar sockpathsfile
|
||||
A file containing a list of pathnames, one per line that
|
||||
.Nm
|
||||
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.
|
||||
@@ -256,19 +273,21 @@ This signal tells
|
||||
to decrease the internal debugging level by 1.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width /usr/libexec/blacklistd-helper -compact
|
||||
.It Pa /usr/libexec/blacklistd-helper
|
||||
.Bl -tag -width /usr/libexec/blocklistd-helper -compact
|
||||
.It Pa /usr/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 ipf 8 ,
|
||||
.Xr ipfw 8 ,
|
||||
.Xr pfctl 8 ,
|
||||
.Xr syslogd 8
|
||||
.Sh HISTORY
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $ */
|
||||
/* $NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -31,8 +31,11 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklistd.c,v 1.38 2019/02/27 02:20:18 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: blocklistd.c,v 1.10 2025/03/26 17:09:35 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -175,6 +178,8 @@ process(bl_t bl)
|
||||
struct dbinfo dbi;
|
||||
struct timespec ts;
|
||||
|
||||
memset(&dbi, 0, sizeof(dbi));
|
||||
memset(&c, 0, sizeof(c));
|
||||
if (clock_gettime(CLOCK_REALTIME, &ts) == -1) {
|
||||
(*lfun)(LOG_ERR, "clock_gettime failed (%m)");
|
||||
return;
|
||||
@@ -188,10 +193,11 @@ process(bl_t bl)
|
||||
if (getremoteaddress(bi, &rss, &rsl) == -1)
|
||||
goto out;
|
||||
|
||||
if (debug) {
|
||||
if (debug || bi->bi_msg[0]) {
|
||||
sockaddr_snprintf(rbuf, sizeof(rbuf), "%a:%p", (void *)&rss);
|
||||
(*lfun)(LOG_DEBUG, "processing type=%d fd=%d remote=%s msg=%s"
|
||||
" uid=%lu gid=%lu", bi->bi_type, bi->bi_fd, rbuf,
|
||||
(*lfun)(bi->bi_msg[0] ? LOG_INFO : LOG_DEBUG,
|
||||
"processing type=%d fd=%d remote=%s msg=%s uid=%lu gid=%lu",
|
||||
bi->bi_type, bi->bi_fd, rbuf,
|
||||
bi->bi_msg, (unsigned long)bi->bi_uid,
|
||||
(unsigned long)bi->bi_gid);
|
||||
}
|
||||
@@ -216,16 +222,19 @@ 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 the application has signaled abusive behavior, set the
|
||||
* number of fails to be two less than the configured limit.
|
||||
* Fall through to the normal BL_ADD and BL_BADUSER 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;
|
||||
dbi.count = c.c_nfail - 2;
|
||||
/*FALLTHROUGH*/
|
||||
case BL_ADD:
|
||||
dbi.count++; /* will become += 2 */
|
||||
/*FALLTHROUGH*/
|
||||
case BL_BADUSER:
|
||||
dbi.count++;
|
||||
dbi.last = ts.tv_sec;
|
||||
if (c.c_nfail != -1 && dbi.count >= c.c_nfail) {
|
||||
@@ -254,9 +263,6 @@ 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);
|
||||
}
|
||||
@@ -334,7 +340,7 @@ static void
|
||||
addfd(struct pollfd **pfdp, bl_t **blp, size_t *nfd, size_t *maxfd,
|
||||
const char *path)
|
||||
{
|
||||
bl_t bl = bl_create(true, path, vflag ? vdlog : vsyslog);
|
||||
bl_t bl = bl_create(true, path, vflag ? vdlog : vsyslog_r);
|
||||
if (bl == NULL || !bl_isconnected(bl))
|
||||
exit(EXIT_FAILURE);
|
||||
if (*nfd >= *maxfd) {
|
||||
@@ -395,15 +401,25 @@ rules_flush(void)
|
||||
static void
|
||||
rules_restore(void)
|
||||
{
|
||||
DB *db;
|
||||
struct conf c;
|
||||
struct dbinfo dbi;
|
||||
unsigned int f;
|
||||
|
||||
for (f = 1; state_iterate(state, &c, &dbi, f) == 1; f = 0) {
|
||||
db = state_open(dbfile, O_RDONLY, 0);
|
||||
if (db == NULL) {
|
||||
(*lfun)(LOG_ERR, "Can't open `%s' to restore state (%m)",
|
||||
dbfile);
|
||||
return;
|
||||
}
|
||||
for (f = 1; state_iterate(db, &c, &dbi, f) == 1; f = 0) {
|
||||
if (dbi.id[0] == '\0')
|
||||
continue;
|
||||
(void)run_change("add", &c, dbi.id, sizeof(dbi.id));
|
||||
state_put(state, &c, &dbi);
|
||||
}
|
||||
state_close(db);
|
||||
state_sync(state);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" $NetBSD: blacklistd.conf.5,v 1.9 2019/11/06 20:33:30 para Exp $
|
||||
.\" $NetBSD: blocklistd.conf.5,v 1.7 2025/02/11 17:47:05 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
.\" Copyright (c) 2015, 2025 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to The NetBSD Foundation
|
||||
@@ -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 May 18, 2020
|
||||
.Dt BLACKLISTD.CONF 5
|
||||
.Dd February 5, 2025
|
||||
.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
|
||||
file contains configuration entries for
|
||||
.Xr blacklistd 8
|
||||
.Xr blocklistd 8
|
||||
in a fashion similar to
|
||||
.Xr inetd.conf 5 .
|
||||
Only one entry per line is permitted.
|
||||
@@ -48,34 +48,34 @@ Comments are denoted by a
|
||||
at the beginning of a line.
|
||||
.Pp
|
||||
There are two kinds of configuration lines,
|
||||
.Va local
|
||||
.Va [local]
|
||||
and
|
||||
.Va remote .
|
||||
.Va [remote] .
|
||||
By default, configuration lines are
|
||||
.Va local ,
|
||||
.Va [local] ,
|
||||
i.e. the address specified refers to the addresses on the local machine.
|
||||
To switch to between
|
||||
.Va local
|
||||
.Va [local]
|
||||
and
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
configuration lines you can specify the stanzas:
|
||||
.Dq [local]
|
||||
and
|
||||
.Dq [remote] .
|
||||
.Pp
|
||||
On
|
||||
.Va local
|
||||
.Va [local]
|
||||
and
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
lines
|
||||
.Dq *
|
||||
means use the default, or wildcard match.
|
||||
In addition, for
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
lines
|
||||
.Dq =
|
||||
means use the values from the matched
|
||||
.Va local
|
||||
.Va [local]
|
||||
configuration line.
|
||||
.Pp
|
||||
The first four fields,
|
||||
@@ -85,9 +85,9 @@ The first four fields,
|
||||
and
|
||||
.Va owner
|
||||
are used to match the
|
||||
.Va local
|
||||
.Va [local]
|
||||
or
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
addresses, whereas the last 3 fields
|
||||
.Va name ,
|
||||
.Va nfail ,
|
||||
@@ -110,8 +110,8 @@ The
|
||||
can be an IPv4 address in numeric format, an IPv6 address
|
||||
in numeric format and enclosed by square brackets, or an interface name.
|
||||
Mask modifiers are not allowed on interfaces because interfaces
|
||||
can have multiple addresses in different protocols where the mask has a different
|
||||
size.
|
||||
can have multiple addresses in different protocols where the mask has a
|
||||
different size.
|
||||
.Pp
|
||||
The
|
||||
.Dv mask
|
||||
@@ -143,8 +143,8 @@ The
|
||||
field, is the name of the packet filter rule to be used.
|
||||
If the
|
||||
.Va name
|
||||
starts with a
|
||||
.Dq - ,
|
||||
starts with a hyphen
|
||||
.Pq Dq - ,
|
||||
then the default rulename is prepended to the given name.
|
||||
If the
|
||||
.Dv name
|
||||
@@ -160,13 +160,13 @@ field contains the number of failed attempts before access is blocked,
|
||||
defaulting to
|
||||
.Dq *
|
||||
meaning never, and the last field
|
||||
.Va disable
|
||||
.Va duration
|
||||
specifies the amount of time since the last access that the blocking
|
||||
rule should be active, defaulting to
|
||||
.Dq *
|
||||
meaning forever.
|
||||
The default unit for
|
||||
.Va disable
|
||||
.Va duration
|
||||
is seconds, but one can specify suffixes for different units, such as
|
||||
.Dq m
|
||||
for minutes
|
||||
@@ -176,28 +176,34 @@ for hours and
|
||||
for days.
|
||||
.Pp
|
||||
Matching is done first by checking the
|
||||
.Va local
|
||||
.Va [local]
|
||||
rules individually, in the order of the most specific to the least specific.
|
||||
If a match is found, then the
|
||||
.Va remote
|
||||
If a match is found, then the matching
|
||||
.Va [remote]
|
||||
rules are applied.
|
||||
The
|
||||
.Va name ,
|
||||
.Va nfail ,
|
||||
and
|
||||
.Va disable
|
||||
.Va duration
|
||||
fields can be altered by the
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
rule that matched.
|
||||
.Pp
|
||||
The
|
||||
.Va remote
|
||||
.Va [remote]
|
||||
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.
|
||||
size (via
|
||||
.Va name ) ,
|
||||
the rule that the packet filter uses (also via
|
||||
.Va name ) ,
|
||||
the number of failed attempts (via
|
||||
.Va nfail ) ,
|
||||
or the duration to block (via
|
||||
.Va 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
|
||||
@@ -209,13 +215,15 @@ bnx0:ssh * * * * 3 6h
|
||||
[remote]
|
||||
# Never block 1.2.3.4
|
||||
1.2.3.4:ssh * * * * * *
|
||||
# For addresses coming from 8.8.0.0/16 block whole /24 networks instead of
|
||||
# Never block the example IPv6 subnet either
|
||||
[2001:db8::]/32:ssh * * * * * *
|
||||
# For addresses coming from 8.8.0.0/16 block whole /24 networks instead
|
||||
# individual hosts, but keep the rest of the blocking parameters the same.
|
||||
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
|
||||
+169
-31
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $ */
|
||||
/* $NetBSD: conf.c,v 1.10 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: conf.c,v 1.10 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
@@ -58,6 +60,7 @@ __RCSID("$NetBSD: conf.c,v 1.24 2016/04/04 15:52:56 christos Exp $");
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <sys/socket.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "bl.h"
|
||||
#include "internal.h"
|
||||
@@ -261,7 +264,7 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c,
|
||||
if (debug)
|
||||
(*lfun)(LOG_DEBUG, "%s: host6 %s", __func__, p);
|
||||
if (strcmp(p, "*") != 0) {
|
||||
if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == -1)
|
||||
if (inet_pton(AF_INET6, p, &sin6->sin6_addr) != 1)
|
||||
goto out;
|
||||
sin6->sin6_family = AF_INET6;
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
@@ -269,6 +272,8 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c,
|
||||
#endif
|
||||
port = &sin6->sin6_port;
|
||||
}
|
||||
if (!*pstr)
|
||||
pstr = "*";
|
||||
} else if (pstr != p || strchr(p, '.') || conf_is_interface(p)) {
|
||||
if (pstr == p)
|
||||
pstr = "*";
|
||||
@@ -311,7 +316,7 @@ conf_gethostport(const char *f, size_t l, bool local, struct conf *c,
|
||||
*port = htons((in_port_t)c->c_port);
|
||||
return 0;
|
||||
out:
|
||||
(*lfun)(LOG_ERR, "%s: %s, %zu: Bad address [%s]", __func__, f, l, pstr);
|
||||
(*lfun)(LOG_ERR, "%s: %s, %zu: Bad address [%s]", __func__, f, l, p);
|
||||
return -1;
|
||||
out1:
|
||||
(*lfun)(LOG_ERR, "%s: %s, %zu: Can't specify mask %d with "
|
||||
@@ -407,6 +412,8 @@ conf_parseline(const char *f, size_t l, char *p, struct conf *c, bool local)
|
||||
{
|
||||
int e;
|
||||
|
||||
c->c_lineno = l;
|
||||
|
||||
while (*p && isspace((unsigned char)*p))
|
||||
p++;
|
||||
|
||||
@@ -471,7 +478,6 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask)
|
||||
uint32_t m;
|
||||
int omask = mask;
|
||||
|
||||
len >>= 2;
|
||||
switch (mask) {
|
||||
case FSTAR:
|
||||
if (memcmp(v1, v2, len) == 0)
|
||||
@@ -485,7 +491,7 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask)
|
||||
break;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
for (size_t i = 0; i < (len >> 2); i++) {
|
||||
if (mask > 32) {
|
||||
m = htonl((uint32_t)~0);
|
||||
mask -= 32;
|
||||
@@ -501,7 +507,6 @@ conf_amask_eq(const void *v1, const void *v2, size_t len, int mask)
|
||||
out:
|
||||
if (debug > 1) {
|
||||
char b1[256], b2[256];
|
||||
len <<= 2;
|
||||
blhexdump(b1, sizeof(b1), "a1", v1, len);
|
||||
blhexdump(b2, sizeof(b2), "a2", v2, len);
|
||||
(*lfun)(LOG_DEBUG, "%s: %s != %s [0x%x]", __func__,
|
||||
@@ -690,6 +695,25 @@ 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, FSTAR))
|
||||
return 0;
|
||||
|
||||
#define CMP(a, b, f) \
|
||||
if ((a)->f != (b)->f) \
|
||||
return 0;
|
||||
|
||||
CMP(c1, c2, c_port);
|
||||
CMP(c1, c2, c_proto);
|
||||
CMP(c1, c2, c_family);
|
||||
CMP(c1, c2, c_uid);
|
||||
#undef CMP
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
conf_match(const struct conf *c1, const struct conf *c2)
|
||||
{
|
||||
|
||||
if (!conf_addr_eq(&c1->c_ss, &c2->c_ss, c2->c_lmask))
|
||||
@@ -953,13 +977,54 @@ confset_free(struct confset *cs)
|
||||
}
|
||||
|
||||
static void
|
||||
confset_replace(struct confset *dc, struct confset *sc)
|
||||
confset_merge(struct confset *dc, struct confset *sc)
|
||||
{
|
||||
struct confset tc;
|
||||
tc = *dc;
|
||||
*dc = *sc;
|
||||
confset_init(sc);
|
||||
confset_free(&tc);
|
||||
size_t i, j;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
/* Check each rule of the src confset (sc) */
|
||||
for (i = 0; i < sc->cs_n; i++) {
|
||||
/* Compare to each rule in the dest confset (dc) */
|
||||
for (j = 0; j < dc->cs_n; j++) {
|
||||
if (conf_eq(&dc->cs_c[j], &sc->cs_c[i])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == dc->cs_n) {
|
||||
/* This is a new rule to add to the dest confset. */
|
||||
if (confset_full(dc) && confset_grow(dc) == -1)
|
||||
return;
|
||||
|
||||
*confset_get(dc) = sc->cs_c[i];
|
||||
confset_add(dc);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We had a match above. */
|
||||
/*
|
||||
* Check whether the rule from the src confset is more
|
||||
* restrictive than the existing one. Adjust the
|
||||
* existing rule if necessary.
|
||||
*/
|
||||
if (sc->cs_c[i].c_nfail == dc->cs_c[j].c_nfail &&
|
||||
sc->cs_c[i].c_duration && dc->cs_c[j].c_duration) {
|
||||
(*lfun)(LOG_DEBUG, "skipping existing rule: %s",
|
||||
conf_print(buf, sizeof (buf), "", "\t", &sc->cs_c[i]));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sc->cs_c[i].c_nfail < dc->cs_c[j].c_nfail)
|
||||
dc->cs_c[j].c_nfail = sc->cs_c[i].c_nfail;
|
||||
|
||||
if (sc->cs_c[i].c_duration > dc->cs_c[j].c_duration)
|
||||
dc->cs_c[j].c_duration = sc->cs_c[i].c_duration;
|
||||
|
||||
(*lfun)(LOG_DEBUG, "adjusted existing rule: %s",
|
||||
conf_print(buf, sizeof (buf), "", "\t", &dc->cs_c[j]));
|
||||
}
|
||||
|
||||
confset_free(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -990,7 +1055,7 @@ confset_match(const struct confset *cs, struct conf *c,
|
||||
if (debug)
|
||||
(*lfun)(LOG_DEBUG, "%s", conf_print(buf, sizeof(buf),
|
||||
"check:\t", "", &cs->cs_c[i]));
|
||||
if (conf_eq(c, &cs->cs_c[i])) {
|
||||
if (conf_match(c, &cs->cs_c[i])) {
|
||||
if (debug)
|
||||
(*lfun)(LOG_DEBUG, "%s",
|
||||
conf_print(buf, sizeof(buf),
|
||||
@@ -1160,21 +1225,14 @@ conf_find(int fd, uid_t uid, const struct sockaddr_storage *rss,
|
||||
return cr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
conf_parse(const char *f)
|
||||
static void
|
||||
conf_parsefile(FILE *fp, const char *config_file)
|
||||
{
|
||||
FILE *fp;
|
||||
char *line;
|
||||
size_t lineno, len;
|
||||
struct confset lc, rc, *cs;
|
||||
|
||||
if ((fp = fopen(f, "r")) == NULL) {
|
||||
(*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__, f);
|
||||
return;
|
||||
}
|
||||
|
||||
lineno = 1;
|
||||
lineno = 0;
|
||||
|
||||
confset_init(&rc);
|
||||
confset_init(&lc);
|
||||
@@ -1197,23 +1255,103 @@ conf_parse(const char *f)
|
||||
if (confset_grow(cs) == -1) {
|
||||
confset_free(&lc);
|
||||
confset_free(&rc);
|
||||
fclose(fp);
|
||||
free(line);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (conf_parseline(f, lineno, line, confset_get(cs),
|
||||
if (conf_parseline(config_file, lineno, line, confset_get(cs),
|
||||
cs == &lc) == -1)
|
||||
continue;
|
||||
confset_add(cs);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
confset_sort(&lc);
|
||||
confset_sort(&rc);
|
||||
confset_merge(&rconf, &rc);
|
||||
confset_merge(&lconf, &lc);
|
||||
}
|
||||
|
||||
confset_replace(&rconf, &rc);
|
||||
confset_replace(&lconf, &lc);
|
||||
|
||||
static void
|
||||
conf_parsedir(DIR *dir, const char *config_path)
|
||||
{
|
||||
long path_max;
|
||||
struct dirent *dent;
|
||||
char *path;
|
||||
FILE *fp;
|
||||
|
||||
if ((path_max = pathconf(config_path, _PC_PATH_MAX)) == -1)
|
||||
path_max = 2048;
|
||||
|
||||
if ((path = malloc((size_t)path_max)) == NULL) {
|
||||
(*lfun)(LOG_ERR, "%s: Failed to allocate memory for path (%m)",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
while ((dent = readdir(dir)) != NULL) {
|
||||
if (strcmp(dent->d_name, ".") == 0 ||
|
||||
strcmp(dent->d_name, "..") == 0)
|
||||
continue;
|
||||
|
||||
(void) snprintf(path, (size_t)path_max, "%s/%s", config_path,
|
||||
dent->d_name);
|
||||
if ((fp = fopen(path, "r")) == NULL) {
|
||||
(*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__,
|
||||
path);
|
||||
continue;
|
||||
}
|
||||
conf_parsefile(fp, path);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
free(path);
|
||||
}
|
||||
|
||||
void
|
||||
conf_parse(const char *config_path)
|
||||
{
|
||||
char *path;
|
||||
DIR *dir;
|
||||
FILE *fp;
|
||||
|
||||
if ((dir = opendir(config_path)) != NULL) {
|
||||
/*
|
||||
* If config_path is a directory, parse the configuration files
|
||||
* in the directory. Then we're done here.
|
||||
*/
|
||||
conf_parsedir(dir, config_path);
|
||||
closedir(dir);
|
||||
goto out;
|
||||
} else if ((fp = fopen(config_path, "r")) != NULL) {
|
||||
/* If config_path is a file, parse it. */
|
||||
conf_parsefile(fp, config_path);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append ".d" to config_path, and if that is a directory, parse the
|
||||
* configuration files in the directory.
|
||||
*/
|
||||
if (asprintf(&path, "%s.d", config_path) < 0) {
|
||||
(*lfun)(LOG_ERR, "%s: Failed to allocate memory for path (%m)",
|
||||
__func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((dir = opendir(path)) != NULL) {
|
||||
conf_parsedir(dir, path);
|
||||
closedir(dir);
|
||||
}
|
||||
free(path);
|
||||
|
||||
out:
|
||||
if (dir == NULL && fp == NULL) {
|
||||
(*lfun)(LOG_ERR, "%s: Cannot open `%s' (%m)", __func__,
|
||||
config_path);
|
||||
return;
|
||||
}
|
||||
|
||||
confset_sort(&lconf);
|
||||
confset_sort(&rconf);
|
||||
|
||||
if (debug) {
|
||||
confset_list(&lconf, "local", "target");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: conf.h,v 1.6 2015/01/27 19:40:36 christos Exp $ */
|
||||
/* $NetBSD: conf.h,v 1.2 2025/02/05 20:09:33 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct conf {
|
||||
size_t c_lineno;
|
||||
struct sockaddr_storage c_ss;
|
||||
int c_lmask;
|
||||
int c_port;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
/* $NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: internal.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
@@ -41,7 +43,7 @@ __RCSID("$NetBSD: internal.c,v 1.5 2015/01/27 19:40:37 christos Exp $");
|
||||
#include "internal.h"
|
||||
|
||||
int debug;
|
||||
const char *rulename = "blacklistd";
|
||||
const char *rulename = "blocklistd";
|
||||
const char *controlprog = _PATH_BLCONTROL;
|
||||
struct confset lconf, rconf;
|
||||
struct ifaddrs *ifas;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: internal.h,v 1.14 2016/04/04 15:52:56 christos Exp $ */
|
||||
/* $NetBSD: internal.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,13 +32,13 @@
|
||||
#define _INTERNAL_H
|
||||
|
||||
#ifndef _PATH_BLCONF
|
||||
#define _PATH_BLCONF "/etc/blacklistd.conf"
|
||||
#define _PATH_BLCONF "/etc/blocklistd.conf"
|
||||
#endif
|
||||
#ifndef _PATH_BLCONTROL
|
||||
#define _PATH_BLCONTROL "/libexec/blacklistd-helper"
|
||||
#define _PATH_BLCONTROL "/usr/libexec/blocklistd-helper"
|
||||
#endif
|
||||
#ifndef _PATH_BLSTATE
|
||||
#define _PATH_BLSTATE "/var/db/blacklistd.db"
|
||||
#define _PATH_BLSTATE "/var/db/blocklistd.db"
|
||||
#endif
|
||||
|
||||
extern struct confset rconf, lconf;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $ */
|
||||
/* $NetBSD: run.c,v 1.3 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: run.c,v 1.14 2016/04/04 15:52:56 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: run.c,v 1.3 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef HAVE_LIBUTIL_H
|
||||
@@ -131,7 +133,8 @@ run_change(const char *how, const struct conf *c, char *id, size_t len)
|
||||
prname = "udp";
|
||||
break;
|
||||
default:
|
||||
(*lfun)(LOG_ERR, "%s: bad protocol %d", __func__, c->c_proto);
|
||||
(*lfun)(LOG_ERR, "%s: bad protocol %d (line %zu)", __func__,
|
||||
c->c_proto, c->c_lineno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: run.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
/* $NetBSD: run.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $ */
|
||||
/* $NetBSD: state.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: state.c,v 1.19 2016/09/26 19:43:43 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: state.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: state.h,v 1.5 2015/01/27 19:40:37 christos Exp $ */
|
||||
/* $NetBSD: state.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: support.c,v 1.9 2018/09/18 22:12:19 christos Exp $ */
|
||||
/* $NetBSD: support.c,v 1.3 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: support.c,v 1.9 2018/09/18 22:12:19 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: support.c,v 1.3 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
@@ -66,7 +68,8 @@ expandm(char *buf, size_t len, const char *fmt)
|
||||
}
|
||||
|
||||
void
|
||||
vdlog(int level __unused, const char *fmt, va_list ap)
|
||||
vdlog(int level __unused, struct syslog_data *sd __unused,
|
||||
const char *fmt, va_list ap)
|
||||
{
|
||||
char buf[BUFSIZ];
|
||||
|
||||
@@ -81,7 +84,7 @@ dlog(int level, const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vdlog(level, fmt, ap);
|
||||
vdlog(level, NULL, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: support.h,v 1.7 2016/04/04 15:52:56 christos Exp $ */
|
||||
/* $NetBSD: support.h,v 1.2 2024/08/02 17:11:55 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -34,8 +34,9 @@
|
||||
__BEGIN_DECLS
|
||||
const char *fmttime(char *, size_t, time_t);
|
||||
const char *fmtydhms(char *, size_t, time_t);
|
||||
void vdlog(int, const char *, va_list)
|
||||
__attribute__((__format__(__printf__, 2, 0)));
|
||||
struct syslog_data;
|
||||
void vdlog(int, struct syslog_data *, const char *, va_list)
|
||||
__attribute__((__format__(__printf__, 3, 0)));
|
||||
void dlog(int, const char *, ...)
|
||||
__attribute__((__format__(__printf__, 2, 3)));
|
||||
ssize_t blhexdump(char *, size_t, const char *, const void *, size_t);
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
+++ pfilter.c 2015-01-23 17:12:02.000000000 -0500
|
||||
@@ -0,0 +1,24 @@
|
||||
+#include <stdio.h>
|
||||
+#include <blacklist.h>
|
||||
+#include <blocklist.h>
|
||||
+
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+static struct blocklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_open(void)
|
||||
+{
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+ blstate = blocklist_open();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
@@ -23,7 +23,7 @@
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ blacklist_r(blstate, what, 0, msg);
|
||||
+ blocklist_r(blstate, what, 0, msg);
|
||||
+}
|
||||
--- /dev/null 2015-01-23 17:30:40.000000000 -0500
|
||||
+++ pfilter.h 2015-01-23 17:07:25.000000000 -0500
|
||||
@@ -42,8 +42,8 @@ diff -u -p -u -r1.63 Makefile
|
||||
MLINKS= ftpusers.5 ftpchroot.5
|
||||
|
||||
+SRCS+= pfilter.c
|
||||
+LDADD+= -lblacklist
|
||||
+DPADD+= ${LIBBLACKLIST}
|
||||
+LDADD+= -lblocklist
|
||||
+DPADD+= ${LIBBLOCKLIST}
|
||||
+
|
||||
.if defined(NO_INTERNAL_LS)
|
||||
CPPFLAGS+=-DNO_INTERNAL_LS
|
||||
|
||||
@@ -8,17 +8,17 @@
|
||||
+#include <named/types.h>
|
||||
+#include <named/client.h>
|
||||
+
|
||||
+#include <blacklist.h>
|
||||
+#include <blocklist.h>
|
||||
+
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+static struct blocklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_open(void)
|
||||
+{
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+ blstate = blocklist_open();
|
||||
+}
|
||||
+
|
||||
+#define TCP_CLIENT(c) (((c)->attributes & NS_CLIENTATTR_TCP) != 0)
|
||||
@@ -39,7 +39,7 @@
|
||||
+ }
|
||||
+ if (socket == NULL)
|
||||
+ return;
|
||||
+ blacklist_sa_r(blstate,
|
||||
+ blocklist_sa_r(blstate,
|
||||
+ res != ISC_R_SUCCESS, isc_socket_getfd(socket),
|
||||
+ &client->peeraddr.type.sa, client->peeraddr.length, msg);
|
||||
+}
|
||||
@@ -63,8 +63,8 @@ diff -u -u -r1.8 Makefile
|
||||
+ pfilter.c tkeyconf.c tsigconf.c \
|
||||
update.c xfrout.c zoneconf.c ${SRCS_UNIX}
|
||||
|
||||
+LDADD+=-lblacklist
|
||||
+DPADD+=${LIBBLACKLIST}
|
||||
+LDADD+=-lblocklist
|
||||
+DPADD+=${LIBBLOCKLIST}
|
||||
.include <bsd.prog.mk>
|
||||
Index: dist/bin/named/client.c
|
||||
===================================================================
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
Index: dist/src/smtpd/pfilter.c
|
||||
===================================================================
|
||||
RCS file: dist/src/smtpd/pfilter.c
|
||||
diff -N dist/src/smtpd/pfilter.c
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ dist/src/smtpd/pfilter.c 1 Feb 2018 03:29:09 -0000
|
||||
@@ -0,0 +1,19 @@
|
||||
+#include "pfilter.h"
|
||||
+#include <stdio.h> /* for NULL */
|
||||
+#include <blocklist.h>
|
||||
+
|
||||
+static struct blocklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(int a, int fd)
|
||||
+{
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blocklist_open();
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+ (void)blocklist_r(blstate, a, fd, "smtpd");
|
||||
+ if (a == 0) {
|
||||
+ blocklist_close(blstate);
|
||||
+ blstate = NULL;
|
||||
+ }
|
||||
+}
|
||||
Index: dist/src/smtpd/pfilter.h
|
||||
===================================================================
|
||||
RCS file: dist/src/smtpd/pfilter.h
|
||||
diff -N dist/src/smtpd/pfilter.h
|
||||
--- /dev/null 1 Jan 1970 00:00:00 -0000
|
||||
+++ dist/src/smtpd/pfilter.h 1 Feb 2018 03:29:09 -0000
|
||||
@@ -0,0 +1,2 @@
|
||||
+
|
||||
+void pfilter_notify(int, int);
|
||||
Index: dist/src/smtpd/smtpd.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/ibm-public/postfix/dist/src/smtpd/smtpd.c,v
|
||||
retrieving revision 1.14
|
||||
diff -u -r1.14 smtpd.c
|
||||
--- dist/src/smtpd/smtpd.c 14 Feb 2017 01:16:48 -0000 1.14
|
||||
+++ dist/src/smtpd/smtpd.c 1 Feb 2018 03:29:09 -0000
|
||||
@@ -1197,6 +1197,8 @@
|
||||
#include <smtpd_milter.h>
|
||||
#include <smtpd_expand.h>
|
||||
|
||||
+#include "pfilter.h"
|
||||
+
|
||||
/*
|
||||
* Tunable parameters. Make sure that there is some bound on the length of
|
||||
* an SMTP command, so that the mail system stays in control even when a
|
||||
@@ -5048,6 +5050,7 @@
|
||||
if (state->error_count >= var_smtpd_hard_erlim) {
|
||||
state->reason = REASON_ERROR_LIMIT;
|
||||
state->error_mask |= MAIL_ERROR_PROTOCOL;
|
||||
+ pfilter_notify(1, vstream_fileno(state->client));
|
||||
smtpd_chat_reply(state, "421 4.7.0 %s Error: too many errors",
|
||||
var_myhostname);
|
||||
break;
|
||||
Index: libexec/smtpd/Makefile
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/ibm-public/postfix/libexec/smtpd/Makefile,v
|
||||
retrieving revision 1.6
|
||||
diff -u -r1.6 Makefile
|
||||
--- libexec/smtpd/Makefile 21 May 2017 15:28:40 -0000 1.6
|
||||
+++ libexec/smtpd/Makefile 1 Feb 2018 03:29:09 -0000
|
||||
@@ -13,11 +13,14 @@
|
||||
SRCS= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
|
||||
smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
|
||||
smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c \
|
||||
- smtpd_expand.c smtpd_haproxy.c
|
||||
+ smtpd_expand.c smtpd_haproxy.c pfilter.c
|
||||
|
||||
DPADD+= ${LIBPMASTER} ${LIBPMILTER} ${LIBPGLOBAL} ${LIBPDNS} ${LIBPXSASL}
|
||||
LDADD+= ${LIBPMASTER} ${LIBPMILTER} ${LIBPGLOBAL} ${LIBPDNS} ${LIBPXSASL}
|
||||
|
||||
+DPADD+= ${LIBBLOCKLIST}
|
||||
+LDADD+= -lblocklist
|
||||
+
|
||||
DPADD+= ${LIBPTLS} ${LIBSSL} ${LIBCRYPTO}
|
||||
LDADD+= ${LIBPTLS} -lssl -lcrypto
|
||||
|
||||
Index: dist/src/smtpd/smtpd.c
|
||||
===================================================================
|
||||
RCS file: /cvsroot/src/external/ibm-public/postfix/dist/src/smtpd/smtpd.c,v
|
||||
retrieving revision 1.17
|
||||
diff -u -u -r1.17 smtpd.c
|
||||
--- dist/src/smtpd/smtpd.c 18 Mar 2020 19:05:20 -0000 1.17
|
||||
+++ dist/src/smtpd/smtpd.c 25 Sep 2020 12:51:52 -0000
|
||||
@@ -5795,6 +5795,8 @@
|
||||
|| strcmp(state->reason, REASON_LOST_CONNECTION)) {
|
||||
msg_info("%s after %s from %s",
|
||||
state->reason, state->where, state->namaddr);
|
||||
+ if (strcmp(state->where, SMTPD_CMD_AUTH) == 0)
|
||||
+ pfilter_notify(1, vstream_fileno(state->client));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
--- Make.rules.in.orig 2015-05-27 20:25:54.000000000 -0400
|
||||
+++ Make.rules.in 2016-01-25 21:48:47.000000000 -0500
|
||||
@@ -110,3 +110,8 @@
|
||||
|
||||
|
||||
FTPWHO_OBJS=ftpwho.o scoreboard.o misc.o
|
||||
BUILD_FTPWHO_OBJS=utils/ftpwho.o utils/scoreboard.o utils/misc.o
|
||||
+
|
||||
+CPPFLAGS+=-DHAVE_BLACKLIST
|
||||
+LIBS+=-lblacklist
|
||||
+CPPFLAGS+=-DHAVE_BLOCKLIST
|
||||
+LIBS+=-lblocklist
|
||||
+OBJS+= pfilter.o
|
||||
+BUILD_OBJS+= src/pfilter.o
|
||||
--- /dev/null 2016-01-22 17:30:55.000000000 -0500
|
||||
@@ -84,25 +84,25 @@
|
||||
+#include "pfilter.h"
|
||||
+#include "conf.h"
|
||||
+#include "privs.h"
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+#include <blacklist.h>
|
||||
+#ifdef HAVE_BLOCKLIST
|
||||
+#include <blocklist.h>
|
||||
+#endif
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+static struct blocklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_init(void)
|
||||
+{
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+#ifdef HAVE_BLOCKLIST
|
||||
+ if (blstate == NULL)
|
||||
+ blstate = blacklist_open();
|
||||
+ blstate = blocklist_open();
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+pfilter_notify(int a)
|
||||
+{
|
||||
+#ifdef HAVE_BLACKLIST
|
||||
+#ifdef HAVE_BLOCKLIST
|
||||
+ conn_t *c = session.c;
|
||||
+ int fd;
|
||||
+
|
||||
@@ -119,6 +119,6 @@
|
||||
+ pfilter_init();
|
||||
+ if (blstate == NULL)
|
||||
+ return;
|
||||
+ (void)blacklist_r(blstate, a, fd, "proftpd");
|
||||
+ (void)blocklist_r(blstate, a, fd, "proftpd");
|
||||
+#endif
|
||||
+}
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
+#include "packet.h"
|
||||
+#include "log.h"
|
||||
+#include "pfilter.h"
|
||||
+#include <blacklist.h>
|
||||
+#include <blocklist.h>
|
||||
+
|
||||
+static struct blacklist *blstate;
|
||||
+static struct blocklist *blstate;
|
||||
+
|
||||
+void
|
||||
+pfilter_init(void)
|
||||
+{
|
||||
+ blstate = blacklist_open();
|
||||
+ blstate = blocklist_open();
|
||||
+}
|
||||
+
|
||||
+void
|
||||
@@ -27,9 +27,9 @@
|
||||
+ return;
|
||||
+ // XXX: 3?
|
||||
+ fd = packet_connection_is_on_socket() ? packet_get_connection_in() : 3;
|
||||
+ (void)blacklist_r(blstate, a, fd, "ssh");
|
||||
+ (void)blocklist_r(blstate, a, fd, "ssh");
|
||||
+ if (a == 0) {
|
||||
+ blacklist_close(blstate);
|
||||
+ blocklist_close(blstate);
|
||||
+ blstate = NULL;
|
||||
+ }
|
||||
+}
|
||||
@@ -60,8 +60,8 @@ diff -u -u -r1.10 Makefile
|
||||
LDADD+= -lwrap
|
||||
DPADD+= ${LIBWRAP}
|
||||
+
|
||||
+LDADD+= -lblacklist
|
||||
+DPADD+= ${LIBBLACKLIST}
|
||||
+LDADD+= -lblocklist
|
||||
+DPADD+= ${LIBBLOCKLIST}
|
||||
diff -ru openssh-7.7p1/auth-pam.c dist/auth-pam.c
|
||||
--- openssh-7.7p1/auth-pam.c 2018-04-02 01:38:28.000000000 -0400
|
||||
+++ dist/auth-pam.c 2018-05-23 11:56:22.206661484 -0400
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.3 2015/01/26 00:18:40 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.2 2025/02/05 20:24:26 christos Exp $
|
||||
|
||||
SUBDIR=rc.d
|
||||
SUBDIR= rc.d
|
||||
|
||||
FILESDIR= /usr/share/examples/blacklist
|
||||
FILESMODE= 644
|
||||
FILES= blacklistd.conf npf.conf
|
||||
FILESDIR= /usr/share/examples/blocklist
|
||||
FILESMODE= 644
|
||||
FILES= blocklistd.conf ipf.conf npf.conf
|
||||
|
||||
.include <bsd.files.mk>
|
||||
.include <bsd.subdir.mk>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Blacklist rule
|
||||
# adr/mask:port type proto owner name nfail disable
|
||||
# Blocklist rule
|
||||
# adr/mask:port type proto owner name nfail duration
|
||||
[local]
|
||||
ssh stream * * * 3 6h
|
||||
ftp stream * * * 3 6h
|
||||
@@ -7,8 +7,9 @@ domain * * named * 3 12h
|
||||
#6161 stream tcp6 christos * 2 10m
|
||||
* * * * * 3 60
|
||||
|
||||
# adr/mask:port type proto owner name nfail disable
|
||||
# adr/mask:port type proto owner name nfail duration
|
||||
[remote]
|
||||
#129.168.0.0/16 * * * = * *
|
||||
#[2001:db8::]/32:ssh * * * = * *
|
||||
#6161 = = = =/24 = =
|
||||
#* stream tcp * = = =
|
||||
@@ -0,0 +1,45 @@
|
||||
#========================================
|
||||
#
|
||||
# subsection for abuse blocking
|
||||
#
|
||||
#========================================
|
||||
#
|
||||
# This section should be included early in the main /etc/ipf.conf file, right
|
||||
# after any basic generic accounting ("count") rules, and any cleanup rules to
|
||||
# block invalid fragments, invalid options (e.g. "ssrr"), etc.
|
||||
#
|
||||
# Note these will not actually block anything since they don't include the
|
||||
# "quick" flag, and are thus part of a last-match group. They simply set up a
|
||||
# group such that any connection logging rule further below won't also match if
|
||||
# one of the rules in the group matches, no matter when or where the subsequent
|
||||
# matching rule is added. I.e. all rules in the group are checked for a match
|
||||
# (and a possible "first match" with "quick") before any subsequent rules
|
||||
# further below are used. Note group rules can be added at any time, including
|
||||
# at runtime after all other rules have been added -- they will still belong to
|
||||
# the group and once added will be checked as part of the group.
|
||||
#
|
||||
# head of "blocklistd" group:
|
||||
#
|
||||
# The "blocklistd" group will be used by blocklistd(8).
|
||||
#
|
||||
block in proto tcp/udp from any to any head blocklistd
|
||||
#
|
||||
# head of "attackers" group to block all attackers:
|
||||
#
|
||||
# The "attackers" group is intended to be used for manually maintained rules
|
||||
# e.g. as could be added like this:
|
||||
#
|
||||
# echo 'block return-rst in log quick proto tcp from 118.136.0.0/15 to any flags S/SAFR group attackers' >> /etc/ipf.conf
|
||||
# /etc/rc.d/ipfliter reload
|
||||
#
|
||||
# Note the choice in this example is to return RST packets for blocked SYN
|
||||
# packets to help the other end close. This is not necessary, but it better
|
||||
# mimics what the kernel does by default, thus perhaps hiding the fact a
|
||||
# firewall is present.
|
||||
#
|
||||
# XXX This example still allows UDP services, but we would need to duplicate
|
||||
# each rule with "proto udp" (and without "flags blah") due to IPF parsing
|
||||
# limitations....
|
||||
#
|
||||
block in proto tcp/udp from any to any head attackers
|
||||
#
|
||||
@@ -1,4 +1,4 @@
|
||||
# Transparent firewall example for blacklistd
|
||||
# Transparent firewall example for blocklistd
|
||||
|
||||
$ext_if = "bnx0"
|
||||
|
||||
@@ -6,7 +6,7 @@ set bpf.jit on;
|
||||
alg "icmp"
|
||||
|
||||
group "external" on $ext_if {
|
||||
ruleset "blacklistd"
|
||||
ruleset "blocklistd"
|
||||
pass final all
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
|
||||
|
||||
SCRIPTS=blacklistd
|
||||
SCRIPTS=blocklistd
|
||||
SCRIPTSDIR=/etc/rc.d
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# $NetBSD: blacklistd,v 1.2 2016/10/17 22:47:16 christos Exp $
|
||||
# $NetBSD: blocklistd,v 1.2 2021/03/07 00:46:39 christos Exp $
|
||||
#
|
||||
|
||||
# PROVIDE: blacklistd
|
||||
# REQUIRE: npf
|
||||
# PROVIDE: blocklistd
|
||||
# REQUIRE: npf pf ipfilter
|
||||
# BEFORE: SERVERS
|
||||
|
||||
$_rc_subr_loaded . /etc/rc.subr
|
||||
|
||||
name="blacklistd"
|
||||
name="blocklistd"
|
||||
rcvar=$name
|
||||
command="/sbin/${name}"
|
||||
pidfile="/var/run/${name}.pid"
|
||||
@@ -18,17 +18,17 @@ start_precmd="${name}_precmd"
|
||||
extra_commands="reload"
|
||||
|
||||
_sockfile="/var/run/${name}.sockets"
|
||||
_sockname="blacklistd.sock"
|
||||
_sockname="blocklistd.sock"
|
||||
|
||||
blacklistd_precmd()
|
||||
blocklistd_precmd()
|
||||
{
|
||||
# Create default list of blacklistd sockets to watch
|
||||
# Create default list of blocklistd sockets to watch
|
||||
#
|
||||
( umask 022 ; > $_sockfile )
|
||||
|
||||
# Find /etc/rc.d scripts with "chrootdir" rcorder(8) keyword,
|
||||
# and if $${app}_chrootdir is a directory, add appropriate
|
||||
# blacklistd socket to list of sockets to watch.
|
||||
# blocklistd socket to list of sockets to watch.
|
||||
#
|
||||
for _lr in $(rcorder -k chrootdir /etc/rc.d/*); do
|
||||
(
|
||||
@@ -42,8 +42,8 @@ blacklistd_precmd()
|
||||
done
|
||||
|
||||
# If other sockets have been provided, change run_rc_command()'s
|
||||
# internal copy of $blacklistd_flags to force use of specific
|
||||
# blacklistd sockets.
|
||||
# internal copy of $blocklistd_flags to force use of specific
|
||||
# blocklistd sockets.
|
||||
#
|
||||
if [ -s $_sockfile ]; then
|
||||
echo "/var/run/${_sockname}" >> $_sockfile
|
||||
@@ -1,10 +1,10 @@
|
||||
# $NetBSD: Makefile,v 1.1 2015/01/21 16:16:00 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
|
||||
|
||||
# Doing a make includes builds /usr/include
|
||||
|
||||
NOOBJ= # defined
|
||||
|
||||
INCS= blacklist.h
|
||||
INCS= blocklist.h
|
||||
INCSDIR= /usr/include
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bl.h,v 1.13 2016/03/11 17:16:40 christos Exp $ */
|
||||
/* $NetBSD: bl.h,v 1.2 2024/08/02 17:11:55 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
@@ -35,7 +35,7 @@
|
||||
#include <stdarg.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include "blacklist.h"
|
||||
#include "blocklist.h"
|
||||
|
||||
typedef enum {
|
||||
BL_INVALID,
|
||||
@@ -58,14 +58,15 @@ typedef struct {
|
||||
#define bi_cred bi_u._bi_cred
|
||||
|
||||
#ifndef _PATH_BLSOCK
|
||||
#define _PATH_BLSOCK "/var/run/blacklistd.sock"
|
||||
#define _PATH_BLSOCK "/var/run/blocklistd.sock"
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
typedef struct blacklist *bl_t;
|
||||
typedef struct blocklist *bl_t;
|
||||
|
||||
bl_t bl_create(bool, const char *, void (*)(int, const char *, va_list));
|
||||
bl_t bl_create(bool, const char *,
|
||||
void (*)(int, struct syslog_data *, const char *, va_list));
|
||||
void bl_destroy(bl_t);
|
||||
int bl_send(bl_t, bl_type_t, int, const struct sockaddr *, socklen_t,
|
||||
const char *);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: blacklist.h,v 1.3 2015/01/23 18:48:56 christos Exp $ */
|
||||
/* $NetBSD: blocklist.h,v 1.4 2025/02/11 17:42:17 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
@@ -28,28 +28,38 @@
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _BLACKLIST_H
|
||||
#define _BLACKLIST_H
|
||||
#ifndef _BLOCKLIST_H
|
||||
#define _BLOCKLIST_H
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <syslog.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
struct blacklist *blacklist_open(void);
|
||||
void blacklist_close(struct blacklist *);
|
||||
int blacklist(int, int, const char *);
|
||||
int blacklist_r(struct blacklist *, int, int, const char *);
|
||||
int blacklist_sa(int, int, const struct sockaddr *, socklen_t, const char *);
|
||||
int blacklist_sa_r(struct blacklist *, int, int,
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct syslog_data;
|
||||
struct blocklist *blocklist_open(void);
|
||||
struct blocklist *blocklist_open2(
|
||||
void (*)(int, struct syslog_data *, const char *, va_list));
|
||||
void blocklist_close(struct blocklist *);
|
||||
int blocklist(int, int, const char *);
|
||||
int blocklist_r(struct blocklist *, int, int, const char *);
|
||||
int blocklist_sa(int, int, const struct sockaddr *, socklen_t, const char *);
|
||||
int blocklist_sa_r(struct blocklist *, int, int,
|
||||
const struct sockaddr *, socklen_t, const char *);
|
||||
__END_DECLS
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/* action values for user applications */
|
||||
#define BLACKLIST_API_ENUM 1
|
||||
#define BLOCKLIST_API_ENUM 1
|
||||
enum {
|
||||
BLACKLIST_AUTH_OK = 0,
|
||||
BLACKLIST_AUTH_FAIL,
|
||||
BLACKLIST_ABUSIVE_BEHAVIOR,
|
||||
BLACKLIST_BAD_USER
|
||||
BLOCKLIST_AUTH_OK = 0,
|
||||
BLOCKLIST_AUTH_FAIL,
|
||||
BLOCKLIST_ABUSIVE_BEHAVIOR,
|
||||
BLOCKLIST_BAD_USER
|
||||
};
|
||||
|
||||
#endif /* _BLACKLIST_H */
|
||||
#endif /* _BLOCKLIST_H */
|
||||
@@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.7 2019/03/08 20:40:05 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
|
||||
|
||||
.include <bsd.own.mk>
|
||||
|
||||
@@ -6,14 +6,14 @@ USE_SHLIBDIR= yes
|
||||
|
||||
CPPFLAGS+=-D_REENTRANT
|
||||
#LIBDPLIBS+=pthread ${NETBSDSRCDIR}/lib/libpthread
|
||||
LIB=blacklist
|
||||
SRCS=bl.c blacklist.c
|
||||
MAN=libblacklist.3
|
||||
MLINKS+=libblacklist.3 blacklist_open.3
|
||||
MLINKS+=libblacklist.3 blacklist_close.3
|
||||
MLINKS+=libblacklist.3 blacklist.3
|
||||
MLINKS+=libblacklist.3 blacklist_r.3
|
||||
MLINKS+=libblacklist.3 blacklist_sa.3
|
||||
MLINKS+=libblacklist.3 blacklist_sa_r.3
|
||||
LIB=blocklist
|
||||
SRCS=bl.c blocklist.c
|
||||
MAN=libblocklist.3
|
||||
MLINKS+=libblocklist.3 blocklist_open.3
|
||||
MLINKS+=libblocklist.3 blocklist_close.3
|
||||
MLINKS+=libblocklist.3 blocklist.3
|
||||
MLINKS+=libblocklist.3 blocklist_r.3
|
||||
MLINKS+=libblocklist.3 blocklist_sa.3
|
||||
MLINKS+=libblocklist.3 blocklist_sa_r.3
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
+67
-45
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $ */
|
||||
/* $NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: bl.c,v 1.9 2025/03/30 01:53:59 christos Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
@@ -57,6 +59,10 @@ __RCSID("$NetBSD: bl.c,v 1.28 2016/07/29 17:13:09 christos Exp $");
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(SO_RECVUCRED)
|
||||
#include <ucred.h>
|
||||
#endif
|
||||
|
||||
#include "bl.h"
|
||||
|
||||
typedef struct {
|
||||
@@ -68,7 +74,7 @@ typedef struct {
|
||||
char bl_data[];
|
||||
} bl_message_t;
|
||||
|
||||
struct blacklist {
|
||||
struct blocklist {
|
||||
#ifdef _REENTRANT
|
||||
pthread_mutex_t b_mutex;
|
||||
# define BL_INIT(b) pthread_mutex_init(&b->b_mutex, NULL)
|
||||
@@ -82,7 +88,8 @@ struct blacklist {
|
||||
int b_fd;
|
||||
int b_connected;
|
||||
struct sockaddr_un b_sun;
|
||||
void (*b_fun)(int, const char *, va_list);
|
||||
struct syslog_data b_syslog_data;
|
||||
void (*b_fun)(int, struct syslog_data *, const char *, va_list);
|
||||
bl_info_t b_info;
|
||||
};
|
||||
|
||||
@@ -115,14 +122,16 @@ bl_reset(bl_t b, bool locked)
|
||||
}
|
||||
|
||||
static void
|
||||
bl_log(void (*fun)(int, const char *, va_list), int level,
|
||||
const char *fmt, ...)
|
||||
bl_log(bl_t b, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int serrno = errno;
|
||||
|
||||
if (b->b_fun == NULL)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
(*fun)(level, fmt, ap);
|
||||
(*b->b_fun)(level, &b->b_syslog_data, fmt, ap);
|
||||
va_end(ap);
|
||||
errno = serrno;
|
||||
}
|
||||
@@ -152,7 +161,7 @@ bl_init(bl_t b, bool srv)
|
||||
b->b_fd = socket(PF_LOCAL,
|
||||
SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK|SOCK_NOSIGPIPE, 0);
|
||||
if (b->b_fd == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: socket failed (%s)",
|
||||
bl_log(b, LOG_ERR, "%s: socket failed (%s)",
|
||||
__func__, strerror(errno));
|
||||
BL_UNLOCK(b);
|
||||
return -1;
|
||||
@@ -186,7 +195,7 @@ bl_init(bl_t b, bool srv)
|
||||
rv = connect(b->b_fd, (const void *)sun, (socklen_t)sizeof(*sun));
|
||||
if (rv == 0) {
|
||||
if (srv) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
bl_log(b, LOG_ERR,
|
||||
"%s: another daemon is handling `%s'",
|
||||
__func__, sun->sun_path);
|
||||
goto out;
|
||||
@@ -199,7 +208,7 @@ bl_init(bl_t b, bool srv)
|
||||
* and only log once.
|
||||
*/
|
||||
if (b->b_connected != 1) {
|
||||
bl_log(b->b_fun, LOG_DEBUG,
|
||||
bl_log(b, LOG_DEBUG,
|
||||
"%s: connect failed for `%s' (%s)",
|
||||
__func__, sun->sun_path, strerror(errno));
|
||||
b->b_connected = 1;
|
||||
@@ -207,8 +216,7 @@ bl_init(bl_t b, bool srv)
|
||||
BL_UNLOCK(b);
|
||||
return -1;
|
||||
}
|
||||
bl_log(b->b_fun, LOG_DEBUG, "Connected to blacklist server",
|
||||
__func__);
|
||||
bl_log(b, LOG_DEBUG, "Connected to blocklist server", __func__);
|
||||
}
|
||||
|
||||
if (srv) {
|
||||
@@ -219,8 +227,7 @@ bl_init(bl_t b, bool srv)
|
||||
(void)umask(om);
|
||||
errno = serrno;
|
||||
if (rv == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
"%s: bind failed for `%s' (%s)",
|
||||
bl_log(b, LOG_ERR, "%s: bind failed for `%s' (%s)",
|
||||
__func__, sun->sun_path, strerror(errno));
|
||||
goto out;
|
||||
}
|
||||
@@ -231,8 +238,8 @@ bl_init(bl_t b, bool srv)
|
||||
#if defined(LOCAL_CREDS)
|
||||
#define CRED_LEVEL 0
|
||||
#define CRED_NAME LOCAL_CREDS
|
||||
#define CRED_SC_UID sc_euid
|
||||
#define CRED_SC_GID sc_egid
|
||||
#define CRED_SC_UID(x) (x)->sc_euid
|
||||
#define CRED_SC_GID(x) (x)->sc_egid
|
||||
#define CRED_MESSAGE SCM_CREDS
|
||||
#define CRED_SIZE SOCKCREDSIZE(NGROUPS_MAX)
|
||||
#define CRED_TYPE struct sockcred
|
||||
@@ -240,12 +247,21 @@ bl_init(bl_t b, bool srv)
|
||||
#elif defined(SO_PASSCRED)
|
||||
#define CRED_LEVEL SOL_SOCKET
|
||||
#define CRED_NAME SO_PASSCRED
|
||||
#define CRED_SC_UID uid
|
||||
#define CRED_SC_GID gid
|
||||
#define CRED_SC_UID(x) (x)->uid
|
||||
#define CRED_SC_GID(x) (x)->gid
|
||||
#define CRED_MESSAGE SCM_CREDENTIALS
|
||||
#define CRED_SIZE sizeof(struct ucred)
|
||||
#define CRED_TYPE struct ucred
|
||||
#define GOT_CRED 2
|
||||
#elif defined(SO_RECVUCRED)
|
||||
#define CRED_LEVEL SOL_SOCKET
|
||||
#define CRED_NAME SO_RECVUCRED
|
||||
#define CRED_SC_UID(x) ucred_geteuid(x)
|
||||
#define CRED_SC_GID(x) ucred_getegid(x)
|
||||
#define CRED_MESSAGE SCM_UCRED
|
||||
#define CRED_SIZE ucred_size()
|
||||
#define CRED_TYPE ucred_t
|
||||
#define GOT_CRED 2
|
||||
#else
|
||||
#define GOT_CRED 0
|
||||
/*
|
||||
@@ -259,7 +275,7 @@ bl_init(bl_t b, bool srv)
|
||||
#ifdef CRED_LEVEL
|
||||
if (setsockopt(b->b_fd, CRED_LEVEL, CRED_NAME,
|
||||
&one, (socklen_t)sizeof(one)) == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: setsockopt %s "
|
||||
bl_log(b, LOG_ERR, "%s: setsockopt %s "
|
||||
"failed (%s)", __func__, __STRING(CRED_NAME),
|
||||
strerror(errno));
|
||||
goto out;
|
||||
@@ -275,12 +291,15 @@ bl_init(bl_t b, bool srv)
|
||||
}
|
||||
|
||||
bl_t
|
||||
bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
|
||||
bl_create(bool srv, const char *path,
|
||||
void (*fun)(int, struct syslog_data *, const char *, va_list))
|
||||
{
|
||||
static struct syslog_data sd = SYSLOG_DATA_INIT;
|
||||
bl_t b = calloc(1, sizeof(*b));
|
||||
if (b == NULL)
|
||||
goto out;
|
||||
b->b_fun = fun == NULL ? vsyslog : fun;
|
||||
return NULL;
|
||||
b->b_fun = fun;
|
||||
b->b_syslog_data = sd;
|
||||
b->b_fd = -1;
|
||||
b->b_connected = -1;
|
||||
BL_INIT(b);
|
||||
@@ -295,11 +314,6 @@ bl_create(bool srv, const char *path, void (*fun)(int, const char *, va_list))
|
||||
|
||||
bl_init(b, srv);
|
||||
return b;
|
||||
out:
|
||||
free(b);
|
||||
bl_log(fun, LOG_ERR, "%s: malloc failed (%s)", __func__,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -327,7 +341,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
|
||||
family = AF_INET6;
|
||||
break;
|
||||
default:
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: invalid socket len %u (%s)",
|
||||
bl_log(b, LOG_ERR, "%s: invalid socket len %u (%s)",
|
||||
__func__, (unsigned)slen, ctx);
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
@@ -336,7 +350,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
|
||||
memcpy(ss, sa, slen);
|
||||
|
||||
if (ss->ss_family != family) {
|
||||
bl_log(b->b_fun, LOG_INFO,
|
||||
bl_log(b, LOG_INFO,
|
||||
"%s: correcting socket family %d to %d (%s)",
|
||||
__func__, ss->ss_family, family, ctx);
|
||||
ss->ss_family = family;
|
||||
@@ -344,7 +358,7 @@ bl_getsock(bl_t b, struct sockaddr_storage *ss, const struct sockaddr *sa,
|
||||
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
|
||||
if (ss->ss_len != slen) {
|
||||
bl_log(b->b_fun, LOG_INFO,
|
||||
bl_log(b, LOG_INFO,
|
||||
"%s: correcting socket len %u to %u (%s)",
|
||||
__func__, ss->ss_len, (unsigned)slen, ctx);
|
||||
ss->ss_len = (uint8_t)slen;
|
||||
@@ -424,10 +438,11 @@ bl_recv(bl_t b)
|
||||
union {
|
||||
char ctrl[CMSG_SPACE(sizeof(int)) + CMSG_SPACE(CRED_SIZE)];
|
||||
uint32_t fd;
|
||||
CRED_TYPE sc;
|
||||
} ua;
|
||||
struct cmsghdr *cmsg;
|
||||
#if GOT_CRED != 0
|
||||
CRED_TYPE *sc;
|
||||
#endif
|
||||
union {
|
||||
bl_message_t bl;
|
||||
char buf[512];
|
||||
@@ -450,18 +465,18 @@ bl_recv(bl_t b)
|
||||
msg.msg_flags = 0;
|
||||
|
||||
msg.msg_control = ua.ctrl;
|
||||
msg.msg_controllen = sizeof(ua.ctrl) + 100;
|
||||
msg.msg_controllen = sizeof(ua.ctrl);
|
||||
|
||||
rlen = recvmsg(b->b_fd, &msg, 0);
|
||||
if (rlen == -1) {
|
||||
bl_log(b->b_fun, LOG_ERR, "%s: recvmsg failed (%s)", __func__,
|
||||
bl_log(b, LOG_ERR, "%s: recvmsg failed (%s)", __func__,
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
|
||||
if (cmsg->cmsg_level != SOL_SOCKET) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
bl_log(b, LOG_ERR,
|
||||
"%s: unexpected cmsg_level %d",
|
||||
__func__, cmsg->cmsg_level);
|
||||
continue;
|
||||
@@ -469,10 +484,15 @@ bl_recv(bl_t b)
|
||||
switch (cmsg->cmsg_type) {
|
||||
case SCM_RIGHTS:
|
||||
if (cmsg->cmsg_len != CMSG_LEN(sizeof(int))) {
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
int *fd = (void *)CMSG_DATA(cmsg);
|
||||
size_t len = cmsg->cmsg_len / sizeof(int);
|
||||
bl_log(b, LOG_ERR,
|
||||
"%s: unexpected cmsg_len %d != %zu",
|
||||
__func__, cmsg->cmsg_len,
|
||||
CMSG_LEN(2 * sizeof(int)));
|
||||
CMSG_LEN(sizeof(int)));
|
||||
|
||||
for (size_t i = 0; i < len; i++)
|
||||
(void)close(fd[i]);
|
||||
continue;
|
||||
}
|
||||
memcpy(&bi->bi_fd, CMSG_DATA(cmsg), sizeof(bi->bi_fd));
|
||||
@@ -481,13 +501,13 @@ bl_recv(bl_t b)
|
||||
#ifdef CRED_MESSAGE
|
||||
case CRED_MESSAGE:
|
||||
sc = (void *)CMSG_DATA(cmsg);
|
||||
bi->bi_uid = sc->CRED_SC_UID;
|
||||
bi->bi_gid = sc->CRED_SC_GID;
|
||||
bi->bi_uid = CRED_SC_UID(sc);
|
||||
bi->bi_gid = CRED_SC_GID(sc);
|
||||
got |= GOT_CRED;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
bl_log(b->b_fun, LOG_ERR,
|
||||
bl_log(b, LOG_ERR,
|
||||
"%s: unexpected cmsg_type %d",
|
||||
__func__, cmsg->cmsg_type);
|
||||
continue;
|
||||
@@ -496,7 +516,7 @@ bl_recv(bl_t b)
|
||||
}
|
||||
|
||||
if (got != (GOT_CRED|GOT_FD)) {
|
||||
bl_log(b->b_fun, LOG_ERR, "message missing %s %s",
|
||||
bl_log(b, LOG_ERR, "message missing %s %s",
|
||||
#if GOT_CRED != 0
|
||||
(got & GOT_CRED) == 0 ? "cred" :
|
||||
#endif
|
||||
@@ -506,13 +526,13 @@ bl_recv(bl_t b)
|
||||
|
||||
rem = (size_t)rlen;
|
||||
if (rem < sizeof(ub.bl)) {
|
||||
bl_log(b->b_fun, LOG_ERR, "message too short %zd", rlen);
|
||||
bl_log(b, LOG_ERR, "message too short %zd", rlen);
|
||||
return NULL;
|
||||
}
|
||||
rem -= sizeof(ub.bl);
|
||||
|
||||
if (ub.bl.bl_version != BL_VERSION) {
|
||||
bl_log(b->b_fun, LOG_ERR, "bad version %d", ub.bl.bl_version);
|
||||
bl_log(b, LOG_ERR, "bad version %d", ub.bl.bl_version);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -523,10 +543,12 @@ bl_recv(bl_t b)
|
||||
bi->bi_uid = -1;
|
||||
bi->bi_gid = -1;
|
||||
#endif
|
||||
rem = MIN(sizeof(bi->bi_msg), rem);
|
||||
if (rem == 0)
|
||||
bi->bi_msg[0] = '\0';
|
||||
else
|
||||
strlcpy(bi->bi_msg, ub.bl.bl_data, rem);
|
||||
else {
|
||||
rem = MIN(sizeof(bi->bi_msg) - 1, rem);
|
||||
memcpy(bi->bi_msg, ub.bl.bl_data, rem);
|
||||
bi->bi_msg[rem] = '\0';
|
||||
}
|
||||
return bi;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $ */
|
||||
/* $NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2014 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: blocklist.c,v 1.4 2025/02/11 17:48:30 christos Exp $");
|
||||
|
||||
#include <stdio.h>
|
||||
#include <bl.h>
|
||||
@@ -45,36 +47,36 @@ __RCSID("$NetBSD: blacklist.c,v 1.5 2015/01/22 16:19:53 christos Exp $");
|
||||
#include <syslog.h>
|
||||
|
||||
int
|
||||
blacklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen,
|
||||
blocklist_sa(int action, int rfd, const struct sockaddr *sa, socklen_t salen,
|
||||
const char *msg)
|
||||
{
|
||||
struct blacklist *bl;
|
||||
struct blocklist *bl;
|
||||
int rv;
|
||||
if ((bl = blacklist_open()) == NULL)
|
||||
if ((bl = blocklist_open()) == NULL)
|
||||
return -1;
|
||||
rv = blacklist_sa_r(bl, action, rfd, sa, salen, msg);
|
||||
blacklist_close(bl);
|
||||
rv = blocklist_sa_r(bl, action, rfd, sa, salen, msg);
|
||||
blocklist_close(bl);
|
||||
return rv;
|
||||
}
|
||||
|
||||
int
|
||||
blacklist_sa_r(struct blacklist *bl, int action, int rfd,
|
||||
blocklist_sa_r(struct blocklist *bl, int action, int rfd,
|
||||
const struct sockaddr *sa, socklen_t slen, const char *msg)
|
||||
{
|
||||
bl_type_t internal_action;
|
||||
|
||||
/* internal values are not the same as user application values */
|
||||
switch (action) {
|
||||
case BLACKLIST_AUTH_FAIL:
|
||||
case BLOCKLIST_AUTH_FAIL:
|
||||
internal_action = BL_ADD;
|
||||
break;
|
||||
case BLACKLIST_AUTH_OK:
|
||||
case BLOCKLIST_AUTH_OK:
|
||||
internal_action = BL_DELETE;
|
||||
break;
|
||||
case BLACKLIST_ABUSIVE_BEHAVIOR:
|
||||
case BLOCKLIST_ABUSIVE_BEHAVIOR:
|
||||
internal_action = BL_ABUSE;
|
||||
break;
|
||||
case BLACKLIST_BAD_USER:
|
||||
case BLOCKLIST_BAD_USER:
|
||||
internal_action = BL_BADUSER;
|
||||
break;
|
||||
default:
|
||||
@@ -85,24 +87,31 @@ blacklist_sa_r(struct blacklist *bl, int action, int rfd,
|
||||
}
|
||||
|
||||
int
|
||||
blacklist(int action, int rfd, const char *msg)
|
||||
blocklist(int action, int rfd, const char *msg)
|
||||
{
|
||||
return blacklist_sa(action, rfd, NULL, 0, msg);
|
||||
return blocklist_sa(action, rfd, NULL, 0, msg);
|
||||
}
|
||||
|
||||
int
|
||||
blacklist_r(struct blacklist *bl, int action, int rfd, const char *msg)
|
||||
blocklist_r(struct blocklist *bl, int action, int rfd, const char *msg)
|
||||
{
|
||||
return blacklist_sa_r(bl, action, rfd, NULL, 0, msg);
|
||||
return blocklist_sa_r(bl, action, rfd, NULL, 0, msg);
|
||||
}
|
||||
|
||||
struct blacklist *
|
||||
blacklist_open(void) {
|
||||
return bl_create(false, NULL, vsyslog);
|
||||
struct blocklist *
|
||||
blocklist_open(void) {
|
||||
return bl_create(false, NULL, vsyslog_r);
|
||||
}
|
||||
|
||||
struct blocklist *
|
||||
blocklist_open2(
|
||||
void (*logger)(int, struct syslog_data *, const char *, va_list))
|
||||
{
|
||||
return bl_create(false, NULL, logger);
|
||||
}
|
||||
|
||||
void
|
||||
blacklist_close(struct blacklist *bl)
|
||||
blocklist_close(struct blocklist *bl)
|
||||
{
|
||||
bl_destroy(bl);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: libblacklist.3,v 1.10 2020/03/30 15:47:15 christos Exp $
|
||||
.\" $NetBSD: libblocklist.3,v 1.7 2025/02/05 20:14:30 christos Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
.\" All rights reserved.
|
||||
@@ -27,55 +27,71 @@
|
||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.Dd March 30, 2020
|
||||
.Dt LIBBLACKLIST 3
|
||||
.Dd February 5, 2025
|
||||
.Dt LIBBLOCKLIST 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm blacklist_open ,
|
||||
.Nm blacklist_close ,
|
||||
.Nm blacklist_r ,
|
||||
.Nm blacklist ,
|
||||
.Nm blacklist_sa ,
|
||||
.Nm blacklist_sa_r
|
||||
.Nd Blacklistd notification library
|
||||
.Nm blocklist_open ,
|
||||
.Nm blocklist_open2 ,
|
||||
.Nm blocklist_close ,
|
||||
.Nm blocklist_r ,
|
||||
.Nm blocklist ,
|
||||
.Nm blocklist_sa ,
|
||||
.Nm blocklist_sa_r
|
||||
.Nd Blocklistd notification library
|
||||
.Sh LIBRARY
|
||||
.Lb libblacklist
|
||||
.Lb libblocklist
|
||||
.Sh SYNOPSIS
|
||||
.In blacklist.h
|
||||
.Ft struct blacklist *
|
||||
.Fn blacklist_open "void"
|
||||
.In blocklist.h
|
||||
.Ft struct blocklist *
|
||||
.Fn blocklist_open "void"
|
||||
.Ft struct blocklist *
|
||||
.Fn blocklist_open2 "void (*logger)(int, struct syslog_data *, va_list)"
|
||||
.Ft void
|
||||
.Fn blacklist_close "struct blacklist *cookie"
|
||||
.Fn blocklist_close "struct blocklist *cookie"
|
||||
.Ft int
|
||||
.Fn blacklist "int action" "int fd" "const char *msg"
|
||||
.Fn blocklist "int action" "int fd" "const char *msg"
|
||||
.Ft int
|
||||
.Fn blacklist_r "struct blacklist *cookie" "int action" "int fd" "const char *msg"
|
||||
.Fn blocklist_r "struct blocklist *cookie" "int action" "int fd" "const char *msg"
|
||||
.Ft int
|
||||
.Fn blacklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg"
|
||||
.Fn blocklist_sa "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg"
|
||||
.Ft int
|
||||
.Fn blacklist_sa_r "struct blacklist *cookie" "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg"
|
||||
.Fn blocklist_sa_r "struct blocklist *cookie" "int action" "int fd" "const struct sockaddr *sa" "socklen_t salen" "const char *msg"
|
||||
.Sh DESCRIPTION
|
||||
These functions can be used by daemons to notify
|
||||
.Xr blacklistd 8
|
||||
about successful and failed remote connections so that blacklistd can
|
||||
.Xr blocklistd 8
|
||||
about successful and failed remote connections so that blocklistd can
|
||||
block or release port access to prevent Denial of Service attacks.
|
||||
.Pp
|
||||
The function
|
||||
.Fn blacklist_open
|
||||
.Fn blocklist_open
|
||||
creates the necessary state to communicate with
|
||||
.Xr blacklistd 8
|
||||
.Xr blocklistd 8
|
||||
and returns a pointer to it, or
|
||||
.Dv NULL
|
||||
on failure.
|
||||
.Pp
|
||||
The function
|
||||
.Fn blocklist_open2
|
||||
is similar to
|
||||
.Fn blocklist_open
|
||||
but allows a
|
||||
.Fa logger
|
||||
to be specified.
|
||||
If the
|
||||
.Fa logger
|
||||
is
|
||||
.Dv NULL ,
|
||||
then no logging is performed.
|
||||
.Pp
|
||||
The
|
||||
.Fn blacklist_close
|
||||
.Fn blocklist_close
|
||||
function frees all memory and resources used.
|
||||
.Pp
|
||||
The
|
||||
.Fn blacklist
|
||||
.Fn blocklist
|
||||
function sends a message to
|
||||
.Xr blacklistd 8 ,
|
||||
.Xr blocklistd 8 ,
|
||||
with an integer
|
||||
.Ar action
|
||||
argument specifying the type of notification,
|
||||
@@ -89,37 +105,31 @@ argument.
|
||||
The
|
||||
.Ar action
|
||||
parameter can take these values:
|
||||
.Bl -tag -width ".Va BLACKLIST_ABUSIVE_BEHAVIOR"
|
||||
.It Va BLACKLIST_AUTH_FAIL
|
||||
.Bl -tag -width ".Dv BLOCKLIST_ABUSIVE_BEHAVIOR"
|
||||
.It Va BLOCKLIST_BAD_USER
|
||||
The sending daemon has determined the username presented for
|
||||
authentication is invalid.
|
||||
This is considered as one failure count.
|
||||
.It Va BLOCKLIST_AUTH_FAIL
|
||||
There was an unsuccessful authentication attempt.
|
||||
.It Va BLACKLIST_AUTH_OK
|
||||
A user successfully authenticated.
|
||||
.It Va BLACKLIST_ABUSIVE_BEHAVIOR
|
||||
The sending daemon has detected abusive behavior
|
||||
from the remote system.
|
||||
The remote address should
|
||||
be blocked as soon as possible.
|
||||
.It Va BLACKLIST_BAD_USER
|
||||
The sending daemon has determined the username
|
||||
presented for authentication is invalid.
|
||||
The
|
||||
.Xr blacklistd 8
|
||||
daemon compares the username to a configured list of forbidden
|
||||
usernames and
|
||||
blocks the address immediately if a forbidden username matches.
|
||||
(The
|
||||
.Ar BLACKLIST_BAD_USER
|
||||
support is not currently available.)
|
||||
This is considered as two failure counts together.
|
||||
.It Va BLOCKLIST_ABUSIVE_BEHAVIOR
|
||||
The sending daemon has detected abusive behavior from the remote system.
|
||||
This is considered as a total immediate failure.
|
||||
The remote address will be blocked as soon as possible.
|
||||
.It Va BLOCKLIST_AUTH_OK
|
||||
A valid user successfully authenticated.
|
||||
Any entry for the remote address will be removed as soon as possible.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn blacklist_r
|
||||
function is more efficient because it keeps the blacklist state around.
|
||||
.Fn blocklist_r
|
||||
function is more efficient because it keeps the blocklist state around.
|
||||
.Pp
|
||||
The
|
||||
.Fn blacklist_sa
|
||||
.Fn blocklist_sa
|
||||
and
|
||||
.Fn blacklist_sa_r
|
||||
.Fn blocklist_sa_r
|
||||
functions can be used with unconnected sockets, where
|
||||
.Xr getpeername 2
|
||||
will not work, the server will pass the peer name in the message.
|
||||
@@ -127,7 +137,7 @@ will not work, the server will pass the peer name in the message.
|
||||
In all cases the file descriptor passed in the
|
||||
.Fa fd
|
||||
argument must be pointing to a valid socket so that
|
||||
.Xr blacklistd 8
|
||||
.Xr blocklistd 8
|
||||
can establish ownership of the local endpoint
|
||||
using
|
||||
.Xr getsockname 2 .
|
||||
@@ -141,7 +151,7 @@ function can be used to create the required internal
|
||||
state and specify a custom logging function.
|
||||
.Sh RETURN VALUES
|
||||
The function
|
||||
.Fn blacklist_open
|
||||
.Fn blocklist_open
|
||||
returns a cookie on success and
|
||||
.Dv NULL
|
||||
on failure setting
|
||||
@@ -149,10 +159,10 @@ on failure setting
|
||||
to an appropriate value.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn blacklist ,
|
||||
.Fn blacklist_sa ,
|
||||
.Fn blocklist ,
|
||||
.Fn blocklist_sa ,
|
||||
and
|
||||
.Fn blacklist_sa_r
|
||||
.Fn blocklist_sa_r
|
||||
return
|
||||
.Dv 0
|
||||
on success and
|
||||
@@ -161,7 +171,7 @@ on failure setting
|
||||
.Dv errno
|
||||
to an appropriate value.
|
||||
.Sh SEE ALSO
|
||||
.Xr blacklistd.conf 5 ,
|
||||
.Xr blacklistd 8
|
||||
.Xr blocklistd.conf 5 ,
|
||||
.Xr blocklistd 8
|
||||
.Sh AUTHORS
|
||||
.An Christos Zoulas
|
||||
@@ -1,2 +1,2 @@
|
||||
major=0
|
||||
minor=0
|
||||
minor=1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# $NetBSD: Makefile,v 1.1 2015/01/22 17:49:41 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $
|
||||
|
||||
SCRIPTS= blacklistd-helper
|
||||
SCRIPTS= blocklistd-helper
|
||||
SCRIPTSDIR= /libexec
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
#!/bin/sh
|
||||
#echo "run $@" 1>&2
|
||||
#set -x
|
||||
# $1 command
|
||||
# $2 rulename
|
||||
# $3 protocol
|
||||
# $4 address
|
||||
# $5 mask
|
||||
# $6 port
|
||||
# $7 id
|
||||
|
||||
pf=
|
||||
if [ -f "/etc/ipfw-blacklist.rc" ]; then
|
||||
pf="ipfw"
|
||||
. /etc/ipfw-blacklist.rc
|
||||
ipfw_offset=${ipfw_offset:-2000}
|
||||
fi
|
||||
|
||||
if [ -z "$pf" ]; then
|
||||
for f in npf pf ipf; do
|
||||
if [ -f "/etc/$f.conf" ]; then
|
||||
pf="$f"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -z "$pf" ]; then
|
||||
echo "$0: Unsupported packet filter" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -n "$3" ]; then
|
||||
proto="proto $3"
|
||||
fi
|
||||
|
||||
if [ -n "$6" ]; then
|
||||
port="port $6"
|
||||
fi
|
||||
|
||||
addr="$4"
|
||||
mask="$5"
|
||||
case "$4" in
|
||||
::ffff:*.*.*.*)
|
||||
if [ "$5" = 128 ]; then
|
||||
mask=32
|
||||
addr=${4#::ffff:}
|
||||
fi;;
|
||||
esac
|
||||
|
||||
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
|
||||
;;
|
||||
ipfw)
|
||||
# use $ipfw_offset+$port for rule number
|
||||
rule=$(($ipfw_offset + $6))
|
||||
tname="port$6"
|
||||
/sbin/ipfw table $tname create type addr 2>/dev/null
|
||||
/sbin/ipfw -q table $tname add "$addr/$mask"
|
||||
# if rule number $rule does not already exist, create it
|
||||
/sbin/ipfw show $rule >/dev/null 2>&1 || \
|
||||
/sbin/ipfw add $rule drop $3 from \
|
||||
table"("$tname")" to any dst-port $6 >/dev/null && \
|
||||
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 | \
|
||||
grep -q "<port$6>" || \
|
||||
echo "block in quick $proto from <port$6> to any $port" | \
|
||||
/sbin/pfctl -a "$2/$6" -f -
|
||||
# insert $ip/$mask into per-protocol/port anchored table
|
||||
/sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \
|
||||
/sbin/pfctl -qk "$addr" && 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
|
||||
;;
|
||||
ipfw)
|
||||
/sbin/ipfw table "port$6" delete "$addr/$mask" 2>/dev/null && \
|
||||
echo OK
|
||||
;;
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" rem-id "$7"
|
||||
;;
|
||||
pf)
|
||||
/sbin/pfctl -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
|
||||
echo OK
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
flush)
|
||||
case "$pf" in
|
||||
ipf)
|
||||
/sbin/ipf -Z -I -Fi -s > /dev/null && echo OK
|
||||
;;
|
||||
ipfw)
|
||||
/sbin/ipfw table "port$6" flush 2>/dev/null && echo OK
|
||||
;;
|
||||
npf)
|
||||
/sbin/npfctl rule "$2" flush
|
||||
;;
|
||||
pf)
|
||||
# dynamically determine which anchors exist
|
||||
for anchor in $(/sbin/pfctl -a "$2" -s Anchors); do
|
||||
/sbin/pfctl -a $anchor -t "port${anchor##*/}" -T flush
|
||||
/sbin/pfctl -a $anchor -F rules
|
||||
done
|
||||
echo OK
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "$0: Unknown command '$1'" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
Executable
+272
@@ -0,0 +1,272 @@
|
||||
#!/bin/sh
|
||||
#echo "run $@" 1>&2
|
||||
#set -x
|
||||
# $1 command
|
||||
# $2 rulename
|
||||
# $3 protocol
|
||||
# $4 address
|
||||
# $5 mask
|
||||
# $6 port
|
||||
# $7 id
|
||||
|
||||
pf=
|
||||
if [ -f "/etc/ipfw-blocklist.rc" ]; then
|
||||
pf="ipfw"
|
||||
. /etc/ipfw-blocklist.rc
|
||||
ipfw_offset=${ipfw_offset:-2000}
|
||||
fi
|
||||
|
||||
if [ -z "$pf" ]; then
|
||||
for f in npf pf ipfilter ipfw; do
|
||||
if [ -x /etc/rc.d/$f ]; then
|
||||
if /etc/rc.d/$f status >/dev/null 2>&1; then
|
||||
pf="$f"
|
||||
break
|
||||
fi
|
||||
elif [ -f "/etc/$f.conf" ]; then
|
||||
# xxx assume a config file means it can be enabled --
|
||||
# and the first one wins!
|
||||
pf="$f"
|
||||
break
|
||||
fi
|
||||
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
|
||||
|
||||
addr="$4"
|
||||
mask="$5"
|
||||
case "$4" in
|
||||
::ffff:*.*.*.*)
|
||||
if [ "$5" = 128 ]; then
|
||||
mask=32
|
||||
addr=${4#::ffff:}
|
||||
fi;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
add)
|
||||
case "$pf" in
|
||||
ipfilter)
|
||||
# N.B.: If you reload /etc/ipf.conf then you need to stop and
|
||||
# restart blocklistd (and make sure blocklistd_flags="-r").
|
||||
# This should normally already be implemented in
|
||||
# /etc/rc.d/ipfilter, but if then not add the following lines to
|
||||
# the end of the ipfilter_reload() function:
|
||||
#
|
||||
# if checkyesnox blocklistd; then
|
||||
# /etc/rc.d/blocklistd restart
|
||||
# fi
|
||||
#
|
||||
# XXX we assume the following rule is present in /etc/ipf.conf:
|
||||
# (should we check? -- it probably cannot be added dynamically)
|
||||
#
|
||||
# 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/used in rules -- 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
|
||||
# supposed 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 rule generated here must exactly match the
|
||||
# corresponding 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))
|
||||
tname="port$6"
|
||||
/sbin/ipfw table $tname create type addr 2>/dev/null
|
||||
/sbin/ipfw -q table $tname add "$addr/$mask"
|
||||
# if rule number $rule does not already exist, create it
|
||||
/sbin/ipfw show $rule >/dev/null 2>&1 || \
|
||||
/sbin/ipfw add $rule drop $3 from \
|
||||
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 | \
|
||||
grep -q "<port$6>" || \
|
||||
echo "block in quick $proto from <port$6> to any $port" | \
|
||||
/sbin/pfctl -a "$2/$6" -f -
|
||||
# insert $ip/$mask into per-protocol/port anchored table
|
||||
/sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \
|
||||
/sbin/pfctl -qk "$addr" && echo OK
|
||||
;;
|
||||
|
||||
esac
|
||||
;;
|
||||
rem)
|
||||
case "$pf" in
|
||||
ipfilter)
|
||||
# N.B.: The rule generated here must exactly match the
|
||||
# corresponding rule generated for the "add" command above!
|
||||
#
|
||||
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 -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
|
||||
echo OK
|
||||
;;
|
||||
|
||||
esac
|
||||
;;
|
||||
flush)
|
||||
case "$pf" in
|
||||
ipfilter)
|
||||
#
|
||||
# N.B. WARNING: This is obviously not reentrant!
|
||||
#
|
||||
# First we flush all the rules from the inactive set, then we
|
||||
# reload the ones that do not belong to the group "$2", and
|
||||
# finally we swap the active and inactive rule sets.
|
||||
#
|
||||
/sbin/ipf -I -F a
|
||||
#
|
||||
# "ipf -I -F a" also flushes active accounting rules!
|
||||
#
|
||||
# Note that accounting rule groups are unique to accounting
|
||||
# rules and have nothing to do with filter rules, though of
|
||||
# course theoretically one could use the same group name for
|
||||
# them too.
|
||||
#
|
||||
# In theory anyone using any such accounting rules should have a
|
||||
# wrapper /etc/rc.conf.d/blocklistd script (and corresponding
|
||||
# /etc/rc.conf.d/ipfilter script) that will record and
|
||||
# consolidate the values accumulated by such accounting rules
|
||||
# before they are flushed, since otherwise their counts will be
|
||||
# lost forever.
|
||||
#
|
||||
/usr/sbin/ipfstat -io | fgrep -v "group $2" | \
|
||||
/sbin/ipf -I -f - >/dev/null 2>&1
|
||||
#
|
||||
# This MUST be done last and separately as "-s" is executed
|
||||
# _while_ the command arguments are being processed!
|
||||
#
|
||||
/sbin/ipf -s && 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)
|
||||
# dynamically determine which anchors exist
|
||||
for anchor in $(/sbin/pfctl -a "$2" -s Anchors 2> /dev/null); do
|
||||
/sbin/pfctl -a "$anchor" -t "port${anchor##*/}" -T flush
|
||||
/sbin/pfctl -a "$anchor" -F rules
|
||||
done
|
||||
echo OK
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "$0: Unknown command '$1'" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,25 +1,39 @@
|
||||
#
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
lib_LTLIBRARIES = libblacklist.la
|
||||
include_HEADERS = ../include/blacklist.h
|
||||
lib_LTLIBRARIES = libblocklist.la
|
||||
include_HEADERS = $(srcdir)/../include/blocklist.h
|
||||
|
||||
bin_PROGRAMS = blacklistd blacklistctl srvtest cltest
|
||||
exampledir = $(datarootdir)/examples
|
||||
example_DATA = $(srcdir)/../etc/blocklistd.conf $(srcdir)/../etc/npf.conf $(srcdir)/../etc/ipf.conf
|
||||
|
||||
VPATH = ../bin:../lib:../test:../include
|
||||
sbin_PROGRAMS = blocklistd blocklistctl
|
||||
noinst_PROGRAMS = srvtest cltest
|
||||
libexec_SCRIPTS = $(srcdir)/../libexec/blocklistd-helper
|
||||
|
||||
AM_CPPFLAGS = -I../include -DDOT="."
|
||||
man5_MANS = $(srcdir)/../bin/blocklistd.conf.5
|
||||
man8_MANS = $(srcdir)/../bin/blocklistd.8 $(srcdir)/../bin/blocklistctl.8
|
||||
|
||||
VPATH = $(srcdir)/../port:$(srcdir)/../bin:$(srcdir)/../lib:$(srcdir)/../test:$(srcdir)/../include
|
||||
|
||||
AM_CPPFLAGS = -I$(srcdir)/../include -DDOT="."
|
||||
AM_CPPFLAGS += -D_PATH_BLCONF=\"$(sysconfdir)/blocklistd.conf\"
|
||||
AM_CPPFLAGS += -D_PATH_BLCONTROL=\"$(libexecdir)/blocklistd-helper\"
|
||||
AM_CPPFLAGS += -D_PATH_BLSOCK=\"$(runstatedir)/blocklistd.sock\"
|
||||
AM_CPPFLAGS += -D_PATH_BLSTATE=\"$(localstatedir)/db/blocklistd.db\"
|
||||
AM_CPPFLAGS += -std=c99 -D_POSIX_C_SOURCE=200809L -D__EXTENSIONS__
|
||||
AM_CPPFLAGS += -D__BSD_VISIBLE=1
|
||||
AM_CFLAGS = @WARNINGS@
|
||||
|
||||
libblacklist_la_SOURCES = bl.c blacklist.c
|
||||
libblacklist_la_LDFLAGS = -no-undefined -version-info 0:0:0
|
||||
libblacklist_la_LIBADD = $(LTLIBOBJS)
|
||||
libblocklist_la_SOURCES = bl.c blocklist.c
|
||||
libblocklist_la_LDFLAGS = -no-undefined -version-info 0:0:0
|
||||
libblocklist_la_LIBADD = $(LTLIBOBJS)
|
||||
|
||||
SRCS = internal.c support.c run.c conf.c state.c
|
||||
blacklistd_SOURCES = blacklistd.c ${SRCS}
|
||||
blacklistd_LDADD = libblacklist.la
|
||||
blacklistctl_SOURCES = blacklistctl.c ${SRCS}
|
||||
blacklistctl_LDADD = libblacklist.la
|
||||
blocklistd_SOURCES = blocklistd.c ${SRCS}
|
||||
blocklistd_LDADD = libblocklist.la
|
||||
blocklistctl_SOURCES = blocklistctl.c ${SRCS}
|
||||
blocklistctl_LDADD = libblocklist.la
|
||||
srvtest_SOURCES = srvtest.c ${SRCS}
|
||||
srvtest_LDADD = libblacklist.la
|
||||
srvtest_LDADD = libblocklist.la
|
||||
cltest_SOURCES = cltest.c ${SRCS}
|
||||
cltest_LDADD = libblacklist.la
|
||||
cltest_LDADD = libblocklist.la
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: _strtoi.h,v 1.1 2015/01/22 02:15:59 christos Exp $ */
|
||||
/* $NetBSD: _strtoi.h,v 1.1.1.1 2020/06/15 01:52:53 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT([blacklistd],[0.1],[christos@netbsd.com])
|
||||
AC_INIT([blocklistd],[0.1],[christos@netbsd.com])
|
||||
AM_INIT_AUTOMAKE([subdir-objects foreign])
|
||||
m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
|
||||
|
||||
@@ -7,9 +7,10 @@ AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
AC_SUBST(WARNINGS)
|
||||
AC_SUBST(LINK_NTOA)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC_STDC
|
||||
AC_PROG_CC
|
||||
AC_USE_SYSTEM_EXTENSIONS
|
||||
AM_PROG_CC_C_O
|
||||
AC_C_BIGENDIAN
|
||||
@@ -18,18 +19,19 @@ AC_PROG_LN_S
|
||||
LT_INIT([disable-static pic-only])
|
||||
gl_VISIBILITY
|
||||
dnl Checks for headers
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_MAJOR
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(stdint.h fcntl.h stdint.h inttypes.h unistd.h)
|
||||
AC_CHECK_HEADERS(sys/un.h sys/socket.h limits.h)
|
||||
AC_CHECK_HEADERS(arpa/inet.h getopt.h err.h)
|
||||
AC_CHECK_HEADERS(sys/types.h util.h sys/time.h time.h)
|
||||
AC_CHECK_HEADERS(netatalk/at.h net/if_dl.h db.h db_185.h)
|
||||
AC_CHECK_HEADERS(netatalk/at.h db.h db_185.h)
|
||||
AC_CHECK_HEADERS(sys/cdefs.h)
|
||||
AC_CHECK_LIB(rt, clock_gettime)
|
||||
AC_CHECK_LIB(db, __db185_open)
|
||||
AC_CHECK_LIB(util, pidfile)
|
||||
AC_CHECK_LIB(util, sockaddr_snprintf)
|
||||
AC_SEARCH_LIBS(__xnet_connect, socket)
|
||||
|
||||
AH_BOTTOM([
|
||||
#ifndef __NetBSD__
|
||||
@@ -82,7 +84,7 @@ dnl Checks for functions
|
||||
AC_CHECK_FUNCS(strerror)
|
||||
|
||||
dnl Provide implementation of some required functions if necessary
|
||||
AC_REPLACE_FUNCS(strtoi sockaddr_snprintf popenve clock_gettime strlcpy strlcat getprogname fparseln fgetln pidfile)
|
||||
AC_REPLACE_FUNCS(strtoi sockaddr_snprintf popenve clock_gettime strlcpy strlcat getprogname fparseln fgetln pidfile vsyslog_r)
|
||||
|
||||
dnl See if we are cross-compiling
|
||||
AM_CONDITIONAL(IS_CROSS_COMPILE, test "$cross_compiling" = yes)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fgetln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $NetBSD: fgetln.c,v 1.1.1.1 2020/06/15 01:52:54 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $NetBSD: fparseln.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
|
||||
@@ -27,9 +27,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: fparseln.c,v 1.1 2015/01/22 03:48:07 christos Exp $");
|
||||
__RCSID("$NetBSD: fparseln.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $ */
|
||||
/* $NetBSD: pidfile.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1999 The NetBSD Foundation, Inc.
|
||||
@@ -32,9 +32,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: pidfile.c,v 1.2 2016/04/05 12:28:57 christos Exp $");
|
||||
__RCSID("$NetBSD: pidfile.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $ */
|
||||
/* $NetBSD: popenve.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
@@ -36,12 +36,14 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95";
|
||||
#else
|
||||
__RCSID("$NetBSD: popenve.c,v 1.2 2015/01/22 03:10:50 christos Exp $");
|
||||
__RCSID("$NetBSD: popenve.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
@@ -15,6 +16,22 @@
|
||||
#define __dead __attribute__((__noreturn__))
|
||||
#endif
|
||||
|
||||
#ifndef __BEGIN_DECLS
|
||||
#define __BEGIN_DECLS
|
||||
#endif
|
||||
|
||||
#ifndef __END_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef __RCSID
|
||||
#define __RCSID(a)
|
||||
#endif
|
||||
@@ -27,6 +44,10 @@
|
||||
#define __arraycount(a) (sizeof(a) / sizeof(a[0]))
|
||||
#endif
|
||||
|
||||
#ifndef __STRING
|
||||
#define __STRING(x) #x
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCPY
|
||||
size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
@@ -78,9 +99,10 @@ int clock_gettime(int, struct timespec *);
|
||||
#define CLOCK_REALTIME 0
|
||||
#endif
|
||||
|
||||
#if !defined(__FreeBSD__)
|
||||
#define _PATH_BLCONF "conf"
|
||||
#define _PATH_BLCONTROL "control"
|
||||
#define _PATH_BLSOCK "blacklistd.sock"
|
||||
#define _PATH_BLSTATE "blacklistd.db"
|
||||
#ifndef HAVE_VSYSLOG_R
|
||||
#define SYSLOG_DATA_INIT { 0 }
|
||||
struct syslog_data {
|
||||
int dummy;
|
||||
};
|
||||
void vsyslog_r(int, struct syslog_data *, const char *, va_list);
|
||||
#endif
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: sockaddr_snprintf.c,v 1.11 2016/06/01 22:57:51 christos Exp $ */
|
||||
/* $NetBSD: sockaddr_snprintf.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2004 The NetBSD Foundation, Inc.
|
||||
@@ -32,9 +32,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.11 2016/06/01 22:57:51 christos Exp $");
|
||||
__RCSID("$NetBSD: sockaddr_snprintf.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $NetBSD: strlcat.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
@@ -22,9 +22,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcat.c,v 1.2 2015/01/22 03:48:07 christos Exp $");
|
||||
__RCSID("$NetBSD: strlcat.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $ */
|
||||
/* $NetBSD: strlcpy.c,v 1.2 2025/02/11 17:48:30 christos Exp $ */
|
||||
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
|
||||
|
||||
/*
|
||||
@@ -22,9 +22,12 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
__RCSID("$NetBSD: strlcpy.c,v 1.2 2015/01/22 03:48:07 christos Exp $");
|
||||
__RCSID("$NetBSD: strlcpy.c,v 1.2 2025/02/11 17:48:30 christos Exp $");
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _LIBC
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $ */
|
||||
/* $NetBSD: strtoi.c,v 1.2 2025/02/11 17:48:31 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
|
||||
@@ -33,8 +33,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: strtoi.c,v 1.3 2015/01/22 03:10:50 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: strtoi.c,v 1.2 2025/02/11 17:48:31 christos Exp $");
|
||||
|
||||
#if defined(_KERNEL)
|
||||
#include <sys/param.h>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <syslog.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
void
|
||||
vsyslog_r(int priority, struct syslog_data *sd __unused, const char *fmt, va_list ap)
|
||||
{
|
||||
vsyslog(priority, fmt, ap);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.3 2015/05/30 22:40:38 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.1.1.1 2020/06/15 01:52:54 christos Exp $
|
||||
|
||||
MKMAN=no
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $ */
|
||||
/* $NetBSD: cltest.c,v 1.2 2025/02/11 17:48:31 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: cltest.c,v 1.6 2015/01/22 05:44:28 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: cltest.c,v 1.2 2025/02/11 17:48:31 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $ */
|
||||
/* $NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2015 The NetBSD Foundation, Inc.
|
||||
@@ -32,8 +32,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_CDEFS_H
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $");
|
||||
#endif
|
||||
__RCSID("$NetBSD: srvtest.c,v 1.2 2025/02/11 17:43:16 christos Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -48,7 +50,7 @@ __RCSID("$NetBSD: srvtest.c,v 1.10 2015/05/30 22:40:38 christos Exp $");
|
||||
#include <poll.h>
|
||||
#include <err.h>
|
||||
|
||||
#include "blacklist.h"
|
||||
#include "blocklist.h"
|
||||
#ifdef BLDEBUG
|
||||
#include "bl.h"
|
||||
static void *b;
|
||||
@@ -71,9 +73,9 @@ process_tcp(int afd)
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
|
||||
#ifdef BLDEBUG
|
||||
blacklist_r(b, 1, afd, buffer);
|
||||
blocklist_r(b, 1, afd, buffer);
|
||||
#else
|
||||
blacklist(1, afd, buffer);
|
||||
blocklist(1, afd, buffer);
|
||||
#endif
|
||||
exit(0);
|
||||
}
|
||||
@@ -95,7 +97,7 @@ process_udp(int afd)
|
||||
err(1, "recvfrom");
|
||||
buffer[sizeof(buffer) - 1] = '\0';
|
||||
printf("%s: sending %d %s\n", getprogname(), afd, buffer);
|
||||
blacklist_sa(1, afd, (void *)&ss, slen, buffer);
|
||||
blocklist_sa(1, afd, (void *)&ss, slen, buffer);
|
||||
exit(0);
|
||||
}
|
||||
static int
|
||||
@@ -167,7 +169,11 @@ static __dead void
|
||||
usage(int c)
|
||||
{
|
||||
warnx("Unknown option `%c'", (char)c);
|
||||
fprintf(stderr, "Usage: %s [-u] [-p <num>]\n", getprogname());
|
||||
fprintf(stderr, "Usage: %s [-u] [-p <num>]"
|
||||
#ifdef BLDEBUG
|
||||
" [-s <sockpath>]"
|
||||
#endif
|
||||
"\n", getprogname());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@@ -182,14 +188,16 @@ main(int argc, char *argv[])
|
||||
struct pollfd pfd[NUMFD];
|
||||
int type = SOCK_STREAM, c;
|
||||
in_port_t port = 6161;
|
||||
#ifdef BLDEBUG
|
||||
char *sockpath = "blsock";
|
||||
const char *optstr = "up:s:";
|
||||
#else
|
||||
const char *optstr = "up:";
|
||||
#endif
|
||||
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
#ifdef BLDEBUG
|
||||
b = bl_create(false, "blsock", vsyslog);
|
||||
#endif
|
||||
|
||||
while ((c = getopt(argc, argv, "up:")) != -1)
|
||||
while ((c = getopt(argc, argv, optstr)) != -1)
|
||||
switch (c) {
|
||||
case 'u':
|
||||
type = SOCK_DGRAM;
|
||||
@@ -197,10 +205,20 @@ main(int argc, char *argv[])
|
||||
case 'p':
|
||||
port = (in_port_t)atoi(optarg);
|
||||
break;
|
||||
#ifdef BLDEBUG
|
||||
case 's':
|
||||
sockpath = (char *)optarg;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
usage(c);
|
||||
}
|
||||
|
||||
#ifdef BLDEBUG
|
||||
b = bl_create(false, sockpath, vsyslog_r);
|
||||
#endif
|
||||
|
||||
|
||||
pfd[0].fd = cr(AF_INET, type, port);
|
||||
pfd[0].events = POLLIN;
|
||||
#if NUMFD > 1
|
||||
|
||||
Reference in New Issue
Block a user