Added a configuration option named AuthFailHook. This option holds the path of a program to run in the event that sshd exits without successfully authenticating a network client. The program receives the client's ip address in its environment. This is meant as a means of blacklisting nodes that attempt to break into our system by trying long lists of common passwords, one by one. Delegating this task to an external program provides for maximum flexibility. --- servconf.c | 6 ++++++ servconf.h | 1 + sshd.c | 19 +++++++++++++++++++ sshd_config | 3 +++ sshd_config.5 | 11 +++++++++++ 5 files changed, 40 insertions(+) diff --git a/servconf.c b/servconf.c index 70f5f73f..d455e465 100644 --- a/servconf.c +++ b/servconf.c @@ -543,6 +543,7 @@ typedef enum { sStreamLocalBindMask, sStreamLocalBindUnlink, sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, sSecurityKeyProvider, + sAuthFailHook, sDeprecated, sIgnore, sUnsupported } ServerOpCodes; @@ -695,6 +696,7 @@ static struct { { "rdomain", sRDomain, SSHCFG_ALL }, { "casignaturealgorithms", sCASignatureAlgorithms, SSHCFG_ALL }, { "securitykeyprovider", sSecurityKeyProvider, SSHCFG_GLOBAL }, + { "authfailhook", sAuthFailHook, SSHCFG_ALL }, { NULL, sBadOption, 0 } }; @@ -2338,6 +2340,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, *charptr = xstrdup(arg); break; + case sAuthFailHook: + charptr = &options->auth_fail_hook; + goto parse_filename; + case sDeprecated: case sIgnore: case sUnsupported: diff --git a/servconf.h b/servconf.h index 4202a2d0..2946d169 100644 --- a/servconf.h +++ b/servconf.h @@ -218,6 +218,7 @@ typedef struct { int expose_userauth_info; u_int64_t timing_secret; char *sk_provider; + char *auth_fail_hook; } ServerOptions; /* Information about the incoming connection as used by Match */ diff --git a/sshd.c b/sshd.c index 60b2aaf7..446d7ce9 100644 --- a/sshd.c +++ b/sshd.c @@ -2385,12 +2385,30 @@ do_ssh2_kex(struct ssh *ssh) debug("KEX done"); } +/* Run an external program if client authentication was unsuccessful */ +static void +run_auth_fail_hook(const char * h, const char * ip) +{ + if ((use_privsep && !mm_is_monitor()) || !strcmp(ip, "UNKNOWN")) + return; + + debug3("%s: Running %s for ip %s", __func__, h, ip); + + if (setenv("SSH_NOAUTH_ADDRESS", ip, 1) != 0 || system(h) != 0) + error("%s: Failed to run authentification failure hook", + __func__); +} + /* server specific fatal cleanup */ void cleanup_exit(int i) { if (the_active_state != NULL && the_authctxt != NULL) { do_cleanup(the_active_state, the_authctxt); + if (options.auth_fail_hook != NULL && + !the_authctxt->authenticated) + run_auth_fail_hook(options.auth_fail_hook, + ssh_remote_ipaddr(the_active_state)); if (use_privsep && privsep_is_preauth && pmonitor != NULL && pmonitor->m_pid > 1) { debug("Killing privsep child %d", pmonitor->m_pid); @@ -2405,5 +2423,6 @@ cleanup_exit(int i) if (the_active_state != NULL && (!use_privsep || mm_is_monitor())) audit_event(the_active_state, SSH_CONNECTION_ABANDON); #endif + _exit(i); } diff --git a/sshd_config b/sshd_config index 19b7c91a..108c07cd 100644 --- a/sshd_config +++ b/sshd_config @@ -105,6 +105,9 @@ AuthorizedKeysFile .ssh/authorized_keys # no default banner path #Banner none +# Program to run if client not authenticated +#AuthFailHook /bin/true + # override default of no subsystems Subsystem sftp /usr/libexec/sftp-server diff --git a/sshd_config.5 b/sshd_config.5 index 70ccea44..94e48084 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -231,6 +231,17 @@ is enabled), .Qq password and .Qq publickey . +.It Cm AuthFailHook +Specifies a program to be run if sshd exits whithout sucessfully +authenticating a client. The program is run via the +.Xr system 3 +function. It is only executed if the login attempt arrived via a +network connection. The address of the originating node will be passed +to it in the +.Ev SSH_NOAUTH_ADDRESS +environment variable. This is meant to provide a means of blacklisting +hosts that attempt to break into the system by trying long lists of +common passwords. .It Cm AuthorizedKeysCommand Specifies a program to be used to look up the user's public keys. The program must be owned by root, not writable by group or others and -- 2.24.1 _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev