From owner-svn-src-stable-11@freebsd.org Fri Mar 16 23:34:45 2018 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5B34AF56C86; Fri, 16 Mar 2018 23:34:45 +0000 (UTC) (envelope-from lidl@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 0B6237A50F; Fri, 16 Mar 2018 23:34:45 +0000 (UTC) (envelope-from lidl@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id ED0FA250E; Fri, 16 Mar 2018 23:34:44 +0000 (UTC) (envelope-from lidl@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w2GNYiZi018648; Fri, 16 Mar 2018 23:34:44 GMT (envelope-from lidl@FreeBSD.org) Received: (from lidl@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w2GNYiPu018645; Fri, 16 Mar 2018 23:34:44 GMT (envelope-from lidl@FreeBSD.org) Message-Id: <201803162334.w2GNYiPu018645@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: lidl set sender to lidl@FreeBSD.org using -f From: Kurt Lidl Date: Fri, 16 Mar 2018 23:34:44 +0000 (UTC) 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 X-SVN-Group: stable-11 X-SVN-Commit-Author: lidl X-SVN-Commit-Paths: in stable/11/contrib/blacklist: bin libexec X-SVN-Commit-Revision: 331079 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 16 Mar 2018 23:34:45 -0000 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 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 ;;