Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 16 Mar 2018 23:34:44 +0000 (UTC)
From:      Kurt Lidl <lidl@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r331079 - in stable/11/contrib/blacklist: bin libexec
Message-ID:  <201803162334.w2GNYiPu018645@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: lidl
Date: Fri Mar 16 23:34:44 2018
New Revision: 331079
URL: https://svnweb.freebsd.org/changeset/base/331079

Log:
  MFC r328861: improve blacklist-helper shell script

Modified:
  stable/11/contrib/blacklist/bin/blacklistd.8
  stable/11/contrib/blacklist/bin/blacklistd.c
  stable/11/contrib/blacklist/libexec/blacklistd-helper
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/contrib/blacklist/bin/blacklistd.8
==============================================================================
--- stable/11/contrib/blacklist/bin/blacklistd.8	Fri Mar 16 22:25:33 2018	(r331078)
+++ stable/11/contrib/blacklist/bin/blacklistd.8	Fri Mar 16 23:34:44 2018	(r331079)
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 7, 2016
+.Dd Dec 6, 2017
 .Dt BLACKLISTD 8
 .Os
 .Sh NAME
@@ -35,7 +35,7 @@
 .Nd block and release ports on demand to avoid DoS abuse
 .Sh SYNOPSIS
 .Nm
-.Op Fl dfrv
+.Op Fl Bdfrv
 .Op Fl C Ar controlprog
 .Op Fl c Ar configfile
 .Op Fl D Ar dbfile
@@ -154,6 +154,8 @@ The Berkeley DB file where
 .Nm
 stores its state, usually
 .Pa /var/run/blacklistd.db .
+.It Fl B
+Disable processing of bad-usernames.
 .It Fl d
 Normally,
 .Nm

Modified: stable/11/contrib/blacklist/bin/blacklistd.c
==============================================================================
--- stable/11/contrib/blacklist/bin/blacklistd.c	Fri Mar 16 22:25:33 2018	(r331078)
+++ stable/11/contrib/blacklist/bin/blacklistd.c	Fri Mar 16 23:34:44 2018	(r331079)
@@ -76,6 +76,7 @@ static DB *state;
 static const char *dbfile = _PATH_BLSTATE;
 static sig_atomic_t readconf;
 static sig_atomic_t done;
+static int Bflag;
 static int vflag;
 
 static void
@@ -164,12 +165,85 @@ getremoteaddress(bl_info_t *bi, struct sockaddr_storag
 	return 0;
 }
 
+static const char *badnames_email[] = {
+	"info",
+	"root",
+	"admin",
+	"support",
+	"webmaster",
+	"sales",
+	"postmaster",
+	"marketing",
+	"administrator",
+	"default",
+	"noreply",
+	"ftpuser",
+	"backup",
+	"webadmin",
+	"security",
+	NULL
+};
+
+static const char *badnames_ssh[] = {
+	"admin",
+	"support",
+	"pi",
+	"info",
+	"root",
+	"guest",
+	"webmaster",
+	"ubnt",
+	"abuse",
+	"default",
+	"apache",
+	"nginx",
+	"cisco",
+	"administrator",
+	"ftpuser",
+	"supervisor",
+	"mysql",
+	"postgres",
+	"oracle",
+	"security",
+	"nagios",
+	"webadmin",
+	"usuario",
+	"uucp",
+	"PlcmSpIp",
+	" 0101",
+	NULL
+};
+
+static int
+lookup_username(int proto, int port, const char *username)
+{
+	int i;
+	const char **names;
+
+	if (proto != IPPROTO_TCP)
+		return 0;
+
+	if (port == 22)
+		names = badnames_ssh;
+	else if (port == 25 || port == 587)
+		names = badnames_email;
+	else
+		return 0;
+
+	for (i = 0; names[i] != NULL; i++) {
+		if (strcmp(username, names[i]) == 0)
+			return 1;
+	}
+	return 0;
+}
+
 static void
 process(bl_t bl)
 {
 	struct sockaddr_storage rss;
 	socklen_t rsl;
 	char rbuf[BUFSIZ];
+	int runadd, rundelete;
 	bl_info_t *bi;
 	struct conf c;
 	struct dbinfo dbi;
@@ -213,59 +287,74 @@ process(bl_t bl)
 		    fmttime(b2, sizeof(b2), ts.tv_sec));
 	}
 
+	runadd = rundelete = 0;
+
 	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.
+		 * set the number of fails to be the configured limit.
 		 */
 		if (c.c_nfail != -1)
-			dbi.count = c.c_nfail - 1;
-		/*FALLTHROUGH*/
-	case BL_ADD:
-		dbi.count++;
-		dbi.last = ts.tv_sec;
-		if (dbi.id[0]) {
-			/*
-			 * We should not be getting this since the rule
-			 * should have blocked the address. A possible
-			 * explanation is that someone removed that rule,
-			 * and another would be that we got another attempt
-			 * before we added the rule. In anycase, we remove
-			 * and re-add the rule because we don't want to add
-			 * it twice, because then we'd lose track of it.
-			 */
-			(*lfun)(LOG_DEBUG, "rule exists %s", dbi.id);
-			(void)run_change("rem", &c, dbi.id, 0);
-			dbi.id[0] = '\0';
-		}
-		if (c.c_nfail != -1 && dbi.count >= c.c_nfail) {
-			int res = run_change("add", &c, dbi.id, sizeof(dbi.id));
-			if (res == -1)
-				goto out;
-			sockaddr_snprintf(rbuf, sizeof(rbuf), "%a",
-			    (void *)&rss);
-			(*lfun)(LOG_INFO,
-			    "blocked %s/%d:%d for %d seconds",
-			    rbuf, c.c_lmask, c.c_port, c.c_duration);
-				
-		}
+			dbi.count = c.c_nfail;
+		rundelete = 1;
+		runadd = 1;
 		break;
 	case BL_DELETE:
 		if (dbi.last == 0)
 			goto out;
 		dbi.count = 0;
 		dbi.last = 0;
+		rundelete = 1;
 		break;
 	case BL_BADUSER:
-		/* ignore for now */
+		(*lfun)(LOG_DEBUG, "BL_BADUSER: username %s", bi->bi_msg);
+		dbi.count--;
+		if (Bflag == 0 && lookup_username(c.c_proto, c.c_port, bi->bi_msg) == 1) {
+			dbi.count = c.c_nfail - 1;
+			(*lfun)(LOG_DEBUG, "BL_BADUSER: found %s on list (port: %d)", bi->bi_msg, c.c_port);
+		}
+		/* FALLTHROUGH */
+	case BL_ADD:
+		dbi.count++;
+		dbi.last = ts.tv_sec;
+		if (c.c_nfail != -1 && dbi.count >= c.c_nfail) {
+			rundelete = 1;
+			runadd = 1;
+		}
 		break;
 	default:
 		(*lfun)(LOG_ERR, "unknown message %d", bi->bi_type); 
 	}
+
+	if (rundelete && c.c_duration != -1) {
+		/*
+		 * We should not be getting this since the rule
+		 * should have blocked the address. A possible
+		 * explanation is that someone removed that rule,
+		 * and another would be that we got another attempt
+		 * before we added the rule. In anycase, we remove
+		 * and re-add the rule because we don't want to add
+		 * it twice, because then we'd lose track of it.
+		 */
+		if (dbi.id[0]) {
+			(*lfun)(LOG_INFO, "rule exists %s", dbi.id);
+			(void)run_change("rem", &c, dbi.id, 0);
+			dbi.id[0] = '\0';
+		}
+	}
+	if (runadd) {
+		int res = run_change("add", &c, dbi.id, sizeof(dbi.id));
+		if (res == -1)
+			goto out;
+		sockaddr_snprintf(rbuf, sizeof(rbuf), "%a",
+		    (void *)&rss);
+		(*lfun)(LOG_INFO,
+		    "blocked %s/%d:%d for %d seconds",
+		    rbuf, c.c_lmask, c.c_port, c.c_duration);
+	}
+
+	/* persist the data */
 	state_put(state, &c, &dbi);
 
 out:
@@ -404,13 +493,16 @@ rules_restore(void)
 	struct conf c;
 	struct dbinfo dbi;
 	unsigned int f;
+	static int addremove;
 
 	for (f = 1; state_iterate(state, &c, &dbi, f) == 1; f = 0) {
 		if (dbi.id[0] == '\0')
 			continue;
 		(void)run_change("rem", &c, dbi.id, 0);
 		(void)run_change("add", &c, dbi.id, sizeof(dbi.id));
+		addremove++;
 	}
+	(*lfun)(LOG_INFO, "removed and re-added %d addresses", addremove);
 }
 
 int
@@ -429,8 +521,11 @@ main(int argc, char *argv[])
 	restore = 0;
 	tout = 0;
 	flags = O_RDWR|O_EXCL|O_CLOEXEC;
-	while ((c = getopt(argc, argv, "C:c:D:dfP:rR:s:t:v")) != -1) {
+	while ((c = getopt(argc, argv, "BC:c:D:dfP:rR:s:t:v")) != -1) {
 		switch (c) {
+		case 'B':
+			Bflag++;
+			break;
 		case 'C':
 			controlprog = optarg;
 			break;

Modified: stable/11/contrib/blacklist/libexec/blacklistd-helper
==============================================================================
--- stable/11/contrib/blacklist/libexec/blacklistd-helper	Fri Mar 16 22:25:33 2018	(r331078)
+++ stable/11/contrib/blacklist/libexec/blacklistd-helper	Fri Mar 16 23:34:44 2018	(r331079)
@@ -80,8 +80,8 @@ add)
 		    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 -a "$2/$6" -t "port$6" -T add "$addr/$mask" && \
-		    echo OK
+		/sbin/pfctl -qa "$2/$6" -t "port$6" -T add "$addr/$mask" && \
+		    /sbin/pfctl -q -k $addr && echo OK
 		;;
 	esac
 	;;
@@ -101,7 +101,7 @@ rem)
 		/sbin/npfctl rule "$2" rem-id "$7"
 		;;
 	pf)
-		/sbin/pfctl -a "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
+		/sbin/pfctl -qa "$2/$6" -t "port$6" -T delete "$addr/$mask" && \
 		    echo OK
 		;;
 	esac
@@ -118,7 +118,13 @@ flush)
 		/sbin/npfctl rule "$2" flush
 		;;
 	pf)
-		/sbin/pfctl -a "$2/$6" -t "port$6" -T flush && echo OK
+		# dynamically determine which anchors exist
+		anchors=$(/sbin/pfctl -a $2 -s Anchors)
+		for anchor in $anchors; do
+			/sbin/pfctl -a $anchor -t "port${anchor##*/}" -T flush
+			/sbin/pfctl -a $anchor -F rules
+		done
+		echo OK
 		;;
 	esac
 	;;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201803162334.w2GNYiPu018645>