Damien Miller
2025-May-22 02:40 UTC
LogLevel INFO shows few details for Certificate invalid: not yet valid / expired
On Wed, 21 May 2025, Lars Nood?n via openssh-unix-dev wrote:> On 4/5/25 15:01, Lars Nood?n wrote: > > I notice that when using log level INFO it seems sshd(8) provides very > > little information about failed SSH certificate log in attempts: > > > > Apr? 5 14:44:41 server sshd-session[51695]: error: Certificate invalid: > > not yet valid > > > > Apr? 5 14:45:31 server sshd-session[88953]: error: Certificate invalid: > > expired > > > > Likewise for invalid principals: > > > > Apr? 5 14:46:56 server sshd-session[66692]: error: Certificate invalid: > > name is not a listed principal > > > > Is that on purpose or is there a recommended practice to note the > > account, principal, or certificate used in failed attempts? > > > > Having a valid principal + certificate but from an invalid source > > address provides more information in the log, but it is split into two > > lines: > > > > Apr? 5 14:57:47 server sshd-session[78381]: cert: Authentication tried > > for lars with valid certificate but not from a permitted source address > > (10.11.9.65). > > Apr? 5 14:57:47 server sshd-session[78381]: error: Refused by > > certificate options > > > > Thanks, > > Lars > > Apologies for the timing of the first message. > > As a follow up, it would save a lot of detective work with the logs if, > when specific certificate is part of the problem, to include the > certificate's id and serial number in the log message. I'm not sure of > what the best punctuation might be or if there is already an established > practice for annotating all that. But here is an illustration of how it > could be:Please give the attached patch a try. -d -------------- next part -------------- diff --git a/auth2-hostbased.c b/auth2-hostbased.c index e221417..0227d8e 100644 --- a/auth2-hostbased.c +++ b/auth2-hostbased.c @@ -212,8 +212,16 @@ hostbased_key_allowed(struct ssh *ssh, struct passwd *pw, if (sshkey_is_cert(key) && sshkey_cert_check_authority_now(key, 1, 0, 0, lookup, &reason)) { - error("%s", reason); - auth_debug_add("%s", reason); + if ((fp = sshkey_fingerprint(key->cert->signature_key, + options.fingerprint_hash, SSH_FP_DEFAULT)) == NULL) + fatal_f("sshkey_fingerprint fail"); + error("Refusing certificate ID \"%s\" serial=%llu signed by " + "%s CA %s: %s", key->cert->key_id, key->cert->serial, + sshkey_type(key->cert->signature_key), fp, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, + reason); + free(fp); return 0; } diff --git a/auth2-pubkey.c b/auth2-pubkey.c index d6bc309..3292f7c 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c @@ -583,8 +583,14 @@ user_cert_trusted_ca(struct passwd *pw, struct sshkey *key, if ((final_opts = sshauthopt_merge(principals_opts, cert_opts, &reason)) == NULL) { fail_reason: - error("%s", reason); - auth_debug_add("%s", reason); + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s: %s", key->cert->key_id, + key->cert->serial, + sshkey_type(key->cert->signature_key), ca_fp, + reason); + auth_debug_add("Refused Certificate ID \"%s\" " + "serial=%llu: %s", key->cert->key_id, + (unsigned long long)key->cert->serial, reason); goto out; } } diff --git a/auth2-pubkeyfile.c b/auth2-pubkeyfile.c index c3bd24b..09ce37e 100644 --- a/auth2-pubkeyfile.c +++ b/auth2-pubkeyfile.c @@ -343,15 +343,15 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, /* Parse and check options present in certificate */ if ((certopts = sshauthopt_from_cert(key)) == NULL) { reason = "Invalid certificate options"; - goto fail_reason; + goto cert_fail_reason; } if (auth_authorise_keyopts(pw, certopts, 0, remote_ip, remote_host, loc) != 0) { reason = "Refused by certificate options"; - goto fail_reason; + goto cert_fail_reason; } if ((finalopts = sshauthopt_merge(keyopts, certopts, &reason)) == NULL) - goto fail_reason; + goto cert_fail_reason; /* * If the user has specified a list of principals as @@ -361,12 +361,12 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, if (keyopts->cert_principals != NULL && !match_principals_option(keyopts->cert_principals, key->cert)) { reason = "Certificate does not contain an authorized principal"; - goto fail_reason; + goto cert_fail_reason; } if (sshkey_cert_check_authority_now(key, 0, 0, 0, keyopts->cert_principals == NULL ? pw->pw_name : NULL, &reason) != 0) - goto fail_reason; + goto cert_fail_reason; verbose("Accepted certificate ID \"%s\" (serial %llu) " "signed by CA %s %s found at %s", @@ -385,8 +385,17 @@ auth_check_authkey_line(struct passwd *pw, struct sshkey *key, ret = 0; goto out; + cert_fail_reason: + error("Refusing certificate ID \"%s\" serial=%llu " + "signed by %s CA %s via %s: %s", key->cert->key_id, + key->cert->serial, sshkey_type(key->cert->signature_key), + fp, loc, reason); + auth_debug_add("Refused Certificate ID \"%s\" serial=%llu: %s", + key->cert->key_id, (unsigned long long)key->cert->serial, reason); + goto out; + fail_reason: - error("%s", reason); + error("%s at %s", reason, loc); auth_debug_add("%s", reason); out: free(fp);
Lars Noodén
2025-May-22 06:42 UTC
LogLevel INFO shows few details for Certificate invalid: not yet valid / expired
On 5/22/25 05:40, Damien Miller wrote: [snip] > Please give the attached patch a try. Yes, thank you very much. The patch works when applied and the three cases where the certificate is expired, is not yet valid, or is not used by the right principal are covered: May 22 08:44:31 obsd sshd-session[1022]: error: Refusing certificate ID "edcba" serial=3 signed by ED25519 CA SHA256:4ZyxpgCaw3Y8wz91ajLWARibUGfwyuOrftt2wermMJE: Certificate invalid: expired May 22 08:46:43 obsd sshd-session[31281]: error: Refusing certificate ID "fedcb" serial=4 signed by ED25519 CA SHA256:4ZyxpgCaw3Y8wz91ajLWARibUGfwyuOrftt2wermMJE: Certificate invalid: not yet valid May 22 08:49:01 obsd sshd-session[34072]: error: Refusing certificate ID "gfedc" serial=5 signed by ED25519 CA SHA256:4ZyxpgCaw3Y8wz91ajLWARibUGfwyuOrftt2wermMJE: Certificate invalid: name is not a listed principal It was tested on: $ uname -srm OpenBSD 7.7 amd64 $ grep -A1 '^OpenBSD' /var/run/dmesg.boot | tail -n 2 OpenBSD 7.7-current (GENERIC) #660: Tue May 20 23:57:50 MDT 2025 deraadt at amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC It's very much appreciated. What's the preference for adding to a wish list the case of merging two log lines into one, bugzilla or bugs@? That'd be when the connection is refused due to certificate options like if there is valid certificate but not from a permitted source address. /Lars