Сертификаты ключей хоста ssh, найти срок действия удаленно?

У меня есть среда, где я использую сертификаты SSH для аутентификации ключей хоста SSH. Я говорю о том, какие сертификаты создаются при запуске ssh-keygen -s /path/to/ca -h ..., Эти сертификаты также создаются с интервалом действия с указанием срока их действия. Эти сертификаты уже используются достаточно долго, поэтому мне нужно начать следить за ними, чтобы понять, когда они начинают приближаться к истечению срока действия.

В любом случае я могу сделать удаленное соединение, не входя в систему, и каким-либо образом получить интервал действия, отображаемый alt. получить сертификат загружен? Бег ssh -vvv не отображаются для отображения информации мне нужно. Ни один не делает ssh-keyscan кажется, что сертификат осведомлен. Возможно, какая-то библиотека, на которую я не посмотрел достаточно внимательно?

В худшем случае я всегда могу написать плагин для мониторинга, который работает локально и анализирует вывод ssh-keygen -L -f, Тем не менее, удаленное сканирование действительно похоже на предпочтительный подход.

4 ответа

Решение

Это возможно, но ему не хватает поддержки инструмента. Я нашел библиотеку, которая достаточно хорошо говорит по протоколу SSH, чтобы я мог написать инструмент для извлечения сертификата хоста valid_before перед использованием полного входа в систему через ssh. Вот оно, на языке го. Я надеюсь, что это помогает.

package main

import "golang.org/x/crypto/ssh"
import "fmt"
import "os"
import "time"

func ignoreCertChain(auth ssh.PublicKey, address string) bool {
    return true // Pretend all certificates are trusted.
}

var sawACert bool

func examineCert(cert *ssh.Certificate) bool {
  expires := cert.ValidBefore
  var humanReadable string
  if expires >= ssh.CertTimeInfinity {
    humanReadable = "infinity"
  } else if expires < (1 << 63) {
    humanReadable = time.Unix(int64(expires), 0).Format(time.RFC3339)
  } else {
    humanReadable = "the distant future"
  }
  fmt.Println("Cert expires at time", expires, "(" + humanReadable + ")")
  sawACert = true
  return true  // Reject the cert, to force early connection close.
}

func main() {
  serverHostPort := os.Args[1]
  checker := &ssh.CertChecker{
    IsHostAuthority: ignoreCertChain,
    IsRevoked: examineCert,
  }
  config := &ssh.ClientConfig{
    User: "test-sshcertscan-not-a-real-login-attempt",
    Auth: []ssh.AuthMethod{
      ssh.Password(""),
    },
    HostKeyCallback: checker.CheckHostKey,
  }
  sawACert = false
  client, err := ssh.Dial("tcp", serverHostPort, config);
  if err != nil && !sawACert {
    panic(fmt.Sprint("Cannot connect to ", serverHostPort, ", error: ",
                     err.Error()))
  } else if client != nil {
    defer client.Close()
  }
}

(Быстрые инструкции по использованию: установите Go, сохраните код, указанный выше, в sshcertscan.go, запустите go build sshcertscan.go, а затем направьте его на ssh-сервер с портом examplehost с помощью ./sshcertscan examplehost:22.)

К сожалению, я не знаю ни одного инструмента с открытым исходным кодом. Похоже, что Nmap сможет каким-то образом получить его с помощью NSE- скриптов (но требует некоторой настройки - проверьте / usr / share / nmap / scripts).

SSH-сервер Tectia SSH включает в себя инструмент ssh-fetchkey, который будет извлекать сертификат, а затем вы можете использовать ssh-certview для просмотра подробностей.

Следующая команда получит сертификат и отобразит информацию о нем:

      ssh-keyscan -c <host> | ssh-keygen -L  -f -

пример вывода:

              Type: ssh-ed25519-cert-v01@openssh.com host certificate
        Public key: ED25519-CERT SHA256:XXX<redacted>
        Signing CA: ED25519 SHA256:XXX<redacted>
        Key ID: "my_server"
        Serial: 0
        Valid: from 2022-12-05T15:42:00 to 2023-12-04T15:43:35
        Principals: 
                my_server.example.com
                my_server
                www.example.com
        Critical Options: (none)
        Extensions: (none)

Боюсь, ответ "это невозможно". По крайней мере, я никак не нашел, используя либо клиента openssh, либо библиотеку paramiko SSH для python. Я бы предложил локальную проверку, как вы описали, в сочетании с более простой удаленной проверкой, которая проверяет, что ключ, используемый SSHD, является ключом, который вы только что проверили, срок действия сертификата.

Другие вопросы по тегам