Cómo obtener todas las huellas digitales para el archivo .ssh / Authorized_keys (2)

39

¿Hay una manera simple de obtener una lista de todas las huellas digitales ingresadas en .ssh / Authorized_keys || .ssh / Author_keys2 archivo?

ssh-keygen -l -f .ssh/authorized_keys 

solo devolverá la huella digital de la primera línea / entrada / clave pública

piratear con awk:

awk 'BEGIN { 
    while (getline < ".ssh/authorized_keys") {
        if ($1!~"ssh-(r|d)sa") {continue}
        print "Fingerprint for "$3
        system("echo " "\""$0"\"> /tmp/authorizedPublicKey.scan; \
            ssh-keygen -l -f /tmp/authorizedPublicKey.scan; \
            rm /tmp/authorizedPublicKey.scan"
        )
    }
}'

pero hay una manera más fácil o comando ssh que no encontré?

childno͡.de
fuente
Para hacer esto de manera confiable, debe tener en cuenta el campo de opciones en el authorized_keysarchivo, en el que se ssh-keygenconcentra. Busqué una forma confiable de analizarlo, pero lo mejor que pude encontrar está cubierto por esta respuesta .
starfry

Respuestas:

45

Aquí hay otro truco usando bash simple sin archivos temporales:

while read l; do
  [[ -n $l && ${l###} = $l ]] && ssh-keygen -l -f /dev/stdin <<<$l;
done < .ssh/authorized_keys

Puede convertirlo fácilmente en una función en su .bashrc:

function fingerprints() {
  local file="${1:-$HOME/.ssh/authorized_keys}"
  while read l; do
    [[ -n $l && ${l###} = $l ]] && ssh-keygen -l -f /dev/stdin <<<$l
  done < "${file}"
}

y llámalo con:

$ fingerprints .ssh/authorized_keys
Phaphink
fuente
1
agradable @Raphink, gracias. code.childno.de/marcel/changeset/afdce0dd agregado ;) Una nota: ssh-keygen -l -f /dev/stdinparece que no funciona en un mac .. sin embargo, no es relevante para servidores pero gnaa apple o es un "problema" de BSD /dev/stdin is not a public key file.?
childno͡.de
1
La lectura desde /dev/stdinno es una gran idea, en general, es mejor usar -, pero por alguna razón ssh-keygenno sabe nada -...
ℝaphink
¿No funciona en Mac?
Será el
1
Esto no funciona si las teclas tienen el prefijo de opciones.
Starfry
1
@ ℝaphink: me gustaría local file="${1:-$HOME/.ssh/authorized_keys}"permitir que funcione sin ningún argumento y predeterminado al ~/.ssh/authorized_keysarchivo habitual y citar el < "$file"utilizado como entrada al whilebucle.
0xC0000022L
8

Aquí hay una forma portátil de mostrar todas las huellas digitales clave para un archivo determinado, probado en Mac y Linux:

#!/bin/bash

fingerprint_keys()
{
    if (( $# != 1 )); then
        echo "Usage: ${FUNCNAME} <authorized keys file>" >&2
        return 1
    fi

    local file="$1"
    if [ ! -r "$file" ]; then
        echo "${FUNCNAME}: File '${file}' does not exist or isn't readable." >&2
        return 1
    fi

    # Must be declared /before/ assignment, because of bash weirdness, in
    # order to get exit code in $?.
    local TMPFILE

    TEMPFILE=$(mktemp -q -t "$0.XXXXXXXXXX")
    if (( $? != 0 )); then
        echo "${FUNCNAME}: Can't create temporary file." >&2
        return 1
    fi

    while read line; do
        # Make sure lone isn't a comment or blank.
        if [[ -n "$line" ]] && [ "${line###}" == "$line" ]; then
            # Insert key into temporary file (ignoring noclobber).
            echo "$line" >| "$TEMPFILE"

            # Fingerprint time.
            ssh-keygen -l -f "$TEMPFILE"

            # OVerwrite the file ASAP (ignoring noclobber) to not leave keys
            # sitting in temp files.
            >| "$TEMPFILE"
        fi
    done < "$file"

    rm -f "$TEMPFILE"
    if (( $? != 0 )); then
        echo "${FUNCNAME}: Failed to remove temporary file." >&2
        return 1
    fi
}

Ejemplo de uso:

bash $ fingerprint_keys ~/.ssh/authorized_keys
2048 xx:xx:xx:xx:xx:xx:xx:xx:bb:xx:xx:xx:xx:xx:xx:xx  x@x.local (RSA)
bash $ 
Será
fuente
lamento decir eso, pero eso no es "más simple", ni "más pequeño", ni siquiera "más inteligente" y no adopta otro enfoque que el mencionado anteriormente. solo un script que usa más controladores de errores;)
childno͡.de
3
Lo que lo hace más seguro, ¿verdad? Puedes hacer ediciones, pero ¿por qué votar en contra? No propuse que fuera una solución mejor que la suya ... Siento que un archivo temporal seguro es mejor, y que se necesita más seguridad para los scripts. Además, la versión anterior es segura para noclobber.
Será el
Para un sistema FreeBSD (que no usa bash por defecto), hice los siguientes cambios: Suponiendo que bash esté instalado desde los puertos, cambie la primera línea a #!/usr/local/bin/bash. Entonces llamé a la función mediante la adición de esto como la última línea: fingerprint_keys $@. Guardé el script como fingerprints.bash, marcándolo ejecutable con chmod u+x ./fingerprints.bash. Además, agregué un comentario al archivo con el enlace a esta respuesta, así, cerca de la parte superior # solution from "Will" on SO http://serverfault.com/a/615892/126742. Llámalo así ./fingerprints.bash ~/.ssh/authorized_keys.
derekv
1
@derekv: el método más portátil es usar el siguiente hashbang: #!/usr/bin/env bashporque la ruta para enves muy portátil y le indica envque ejecute el Bash que conoce.
0xC0000022L
7

Una línea basada en el truco / dev / stdin de la respuesta de ℝaphink y man xargs → EJEMPLOS :

egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'
akavel
fuente
Esto funciona muy bien, y dado que es de una sola línea, se puede usar fácilmente para ejecutar el comando a través de SSH. ¡Gracias!
Thibaut Barrère