Changeset View
Changeset View
Standalone View
Standalone View
contrib/blacklist/README
- This file was added.
# $NetBSD: README,v 1.7 2015/01/26 00:34:50 christos Exp $ | |||||
This package contains library that can be used by network daemons to | |||||
communicate with a packet filter via a daemon to enforce opening and | |||||
closing ports dynamically based on policy. | |||||
The interface to the packet filter is in libexec/blacklistd-helper | |||||
(this is currently designed for npf) and the configuration file | |||||
(inspired from inetd.conf) is in etc/blacklistd.conf. | |||||
On NetBSD you can find an example npf.conf and blacklistd.conf in | |||||
/usr/share/examples/blacklistd; 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. | |||||
There is also a startup file in etc/rc.d/blacklistd | |||||
Patches to various daemons to add blacklisting capabilitiers are in the | |||||
"diff" directory: | |||||
- OpenSSH: diff/ssh.diff [tcp socket example] | |||||
- Bind: diff/named.diff [both tcp and udp] | |||||
- ftpd: diff/ftpd.diff [tcp] | |||||
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 | |||||
is handled by the library. In the simplest form the only thing the | |||||
daemon needs to do is to call: | |||||
blacklist(action, acceptedfd, message); | |||||
Where: | |||||
action = 0 -> successful login clear blacklist 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 | |||||
if the program has access to the listening | |||||
socket is done by virtue that the port | |||||
number is retrieved from the kernel. | |||||
message -> an optional string that is used in debugging logs. | |||||
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: | |||||
blacklist_sa(action, acceptedfd, sockaddr, sockaddr_len, message); | |||||
The configuration file contains entries of the form: | |||||
# Blacklist 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 | |||||
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 | |||||
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, | |||||
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 | |||||
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, | |||||
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: | |||||
ext_if=bge0 | |||||
int_if=sk0 | |||||
group "external" on $ext_if { | |||||
... | |||||
ruleset "blacklistd-ext" | |||||
ruleset "blacklistd" | |||||
... | |||||
} | |||||
group "internal" on $int_if { | |||||
... | |||||
ruleset "blacklistd-int" | |||||
... | |||||
} | |||||
Enjoy, | |||||
christos |