add a "Match invalid-user" predicate to sshd_config Match options.
authordjm <djm@openbsd.org>
Sun, 15 Sep 2024 01:18:26 +0000 (01:18 +0000)
committerdjm <djm@openbsd.org>
Sun, 15 Sep 2024 01:18:26 +0000 (01:18 +0000)
This allows writing Match conditions that trigger for invalid username.
E.g.

PerSourcePenalties refuseconnection:90s
Match invalid-user
  RefuseConnection yes

Will effectively penalise bots try to guess passwords for bogus accounts,
at the cost of implicitly revealing which accounts are invalid.

feedback markus@

usr.bin/ssh/auth.c
usr.bin/ssh/servconf.c
usr.bin/ssh/servconf.h
usr.bin/ssh/sshd_config.5

index 3fec9d7..399d75d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: auth.c,v 1.161 2024/05/17 00:30:23 djm Exp $ */
+/* $OpenBSD: auth.c,v 1.162 2024/09/15 01:18:26 djm Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  *
@@ -421,6 +421,7 @@ getpwnamallow(struct ssh *ssh, const char *user)
 
        ci = server_get_connection_info(ssh, 1, options.use_dns);
        ci->user = user;
+       ci->user_invalid = getpwnam(user) == NULL;
        parse_server_match_config(&options, &includes, ci);
        log_change_level(options.log_level);
        log_verbose_reset();
index a8bd2dd..c056f63 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.c,v 1.416 2024/09/15 01:11:26 djm Exp $ */
+/* $OpenBSD: servconf.c,v 1.417 2024/09/15 01:18:26 djm Exp $ */
 /*
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  *                    All rights reserved
@@ -978,9 +978,10 @@ match_cfg_line(const char *full_line, int *acp, char ***avp,
        if (ci == NULL)
                debug3("checking syntax for 'Match %s'", full_line);
        else {
-               debug3("checking match for '%s' user %s host %s addr %s "
+               debug3("checking match for '%s' user %s%s host %s addr %s "
                    "laddr %s lport %d", full_line,
                    ci->user ? ci->user : "(null)",
+                   ci->user_invalid ? " (invalid)" : "",
                    ci->host ? ci->host : "(null)",
                    ci->address ? ci->address : "(null)",
                    ci->laddress ? ci->laddress : "(null)", ci->lport);
@@ -1007,6 +1008,16 @@ match_cfg_line(const char *full_line, int *acp, char ***avp,
                                argv_consume(acp); /* consume remaining args */
                        return 1;
                }
+               /* Criterion "invalid-user" also has no argument */
+               if (strcasecmp(attrib, "invalid-user") == 0) {
+                       if (ci == NULL)
+                               continue;
+                       if (ci->user_invalid == 0)
+                               result = 0;
+                       else
+                               debug("matched invalid-user at line %d", line);
+                       continue;
+               }
                /* All other criteria require an argument */
                if ((arg = argv_next(acp, avp)) == NULL ||
                    *arg == '\0' || *arg == '#') {
@@ -2704,6 +2715,8 @@ int parse_server_match_testspec(struct connection_info *ci, char *spec)
                                    " specification %s\n", p+6, p);
                                return -1;
                        }
+               } else if (strcmp(p, "invalid-user") == 0) {
+                       ci->user_invalid = 1;
                } else {
                        fprintf(stderr, "Invalid test mode specification %s\n",
                            p);
index d7066ec..33ada42 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: servconf.h,v 1.167 2024/09/15 01:11:26 djm Exp $ */
+/* $OpenBSD: servconf.h,v 1.168 2024/09/15 01:18:26 djm Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -253,6 +253,7 @@ typedef struct {
 /* Information about the incoming connection as used by Match */
 struct connection_info {
        const char *user;
+       int user_invalid;
        const char *host;       /* possibly resolved hostname */
        const char *address;    /* remote address */
        const char *laddress;   /* local address */
index 7d29085..3078dfe 100644 (file)
@@ -33,7 +33,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.\" $OpenBSD: sshd_config.5,v 1.372 2024/09/15 01:11:26 djm Exp $
+.\" $OpenBSD: sshd_config.5,v 1.373 2024/09/15 01:18:26 djm Exp $
 .Dd $Mdocdate: September 15 2024 $
 .Dt SSHD_CONFIG 5
 .Os
@@ -1238,9 +1238,11 @@ applied.
 .Pp
 The arguments to
 .Cm Match
-are one or more criteria-pattern pairs or the single token
-.Cm All
-which matches all criteria.
+are one or more criteria-pattern pairs or one of the single token criteria:
+.Cm All ,
+which matches all criteria, or
+.Cm Invalid-User ,
+which matches when the requested user-name does not match any known account.
 The available criteria are
 .Cm User ,
 .Cm Group ,