Come ottenere tutte le impronte digitali per il file .ssh / authorized_keys (2)


39

Esiste un modo semplice per ottenere un elenco di tutte le impronte digitali inserite in .ssh / authorized_keys || .ssh / authorized_keys2 file?

ssh-keygen -l -f .ssh/authorized_keys 

restituirà solo l'impronta digitale della prima riga / entry / publickey

hack 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"
        )
    }
}'

ma c'è un modo più semplice o un comando ssh che non ho trovato?


Per fare ciò in modo affidabile, è necessario considerare il campo delle opzioni nel authorized_keysfile in cui si ssh-keygentrovano. Ho cercato un modo affidabile per analizzarlo, ma il meglio che ho potuto trovare è coperto da questa risposta .
Starfry,

Risposte:


45

Ecco un altro hack che utilizza semplice bash senza file temporanei:

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

Puoi facilmente renderlo una funzione nel tuo .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}"
}

e chiamalo con:

$ fingerprints .ssh/authorized_keys

1
bello @Raphink, grazie. aggiunto code.childno.de/marcel/changeset/afdce0dd ;) Una nota: ssh-keygen -l -f /dev/stdinsembra non funzionare su un mac .. tuttavia non è rilevante per i server ma gnaa apple o è un "problema" di BSD ottenere /dev/stdin is not a public key file.?!
childno͡.de

1
Leggere da /dev/stdinnon è una grande idea in generale, è meglio usarlo -, ma per qualche ragione ssh-keygennon sa di -...
inkaphink

Non funziona su Mac?
Sarà il

1
Questo non funziona se i tasti hanno il prefisso con le opzioni.
Starfry,

1
@ ℝaphink: farei local file="${1:-$HOME/.ssh/authorized_keys}"in modo che funzioni senza argomenti e, di default, utilizzi il solito ~/.ssh/authorized_keysfile e citerei l' < "$file"usato come input per il whileloop.
0xC0000022L

8

Ecco un modo portatile per mostrare tutte le impronte digitali chiave per un determinato file, testato su Mac e 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
}

Esempio di utilizzo:

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 $ 

mi dispiace dirlo, ma non è né "più semplice", né "più piccolo", nemmeno "più intelligente" e non ha un approccio diverso da quello sopra elencato. solo uno script che utilizza più gestori di errori;)
childno͡.de

3
Il che lo rende più sicuro, giusto? Puoi apportare modifiche, ma perché ridimensionare? Non ho proposto che si trattasse di una soluzione migliore della tua ... Sento che un tempfile sicuro è migliore e che è necessaria maggiore sicurezza a scopi di scripting. Inoltre, la versione precedente è sicura per i non fumatori.
Sarà il

Per un sistema FreeBSD (che non usa bash di default), ho apportato le seguenti modifiche: Supponendo che bash sia installato dalle porte, cambia la prima riga in #!/usr/local/bin/bash. Poi ho chiamato la funzione aggiungendo questo come l'ultima riga: fingerprint_keys $@. Ho salvato lo script come fingerprints.bash, contrassegnandolo come eseguibile chmod u+x ./fingerprints.bash. Inoltre, ho aggiunto un commento al file con il link a questa risposta, in questo modo, vicino alla cima # solution from "Will" on SO http://serverfault.com/a/615892/126742. Chiamalo così ./fingerprints.bash ~/.ssh/authorized_keys.
Derekv,

1
@derekv: il metodo più portatile è usare il seguente hashbang:, #!/usr/bin/env bashperché il percorso per envè molto portatile e dice envdi eseguire il Bash di cui è a conoscenza.
0xC0000022L

7

Un one-liner basato sul trucco / dev / stdin dalla risposta di ℝaphink e man xargs → ESEMPI :

egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'

Funziona alla grande, e dato che è un one-liner, può essere facilmente utilizzato per eseguire il comando tramite SSH. Grazie!
Thibaut Barrère,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.