So erhalten Sie alle Fingerabdrücke für die Datei .ssh / authorized_keys (2)

39

Gibt es eine einfache Möglichkeit, eine Liste aller Fingerabdrücke zu erhalten, die unter .ssh / authorized_keys || eingegeben wurden? .ssh / authorized_keys2 Datei?

ssh-keygen -l -f .ssh/authorized_keys 

Gibt nur den Fingerabdruck der ersten Zeile / Eintrag / Veröffentlichung zurück

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

aber gibt es einen einfacheren weg oder einen ssh befehl, den ich nicht gefunden habe?

childno͡.de
quelle
Um dies zuverlässig zu tun, müssen Sie das Optionsfeld in der authorized_keysDatei berücksichtigen , an dem sich die ssh-keygenSperren befinden. Ich habe nach einem zuverlässigen Weg gesucht , es zu analysieren, aber das Beste, was ich mir einfallen lassen konnte, wird durch diese Antwort abgedeckt .
Starfry

Antworten:

45

Hier ist ein weiterer Hack mit Bash ohne temporäre Dateien:

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

Sie können es leicht zu einer Funktion machen in Ihrem .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}"
}

und nenne es mit:

$ fingerprints .ssh/authorized_keys
ℝaphink
quelle
1
nice @Raphink, danke. code.childno.de/marcel/changeset/afdce0dd hinzugefügt ;) Ein Hinweis: ssh-keygen -l -f /dev/stdinscheint auf einem Mac nicht zu funktionieren .. trotzdem nicht relevant für Server aber gnaa apple oder handelt es sich um ein BSD "Problem" bekommen /dev/stdin is not a public key file.?!
childno͡.de
1
Lesen von /dev/stdinist im Allgemeinen keine gute Idee, es ist besser zu verwenden -, aber aus irgendeinem Grund ssh-keygenweiß nicht über -...
--aphink
Funktioniert nicht auf Mac?
Wird
1
Dies funktioniert nicht, wenn den Schlüsseln Optionen vorangestellt sind.
Starfry
1
@ ℝaphink: Ich würde dafür sorgen local file="${1:-$HOME/.ssh/authorized_keys}", dass es ohne Argumente und standardmäßig mit der üblichen ~/.ssh/authorized_keysDatei funktioniert und zitiere die < "$file"als Eingabe für die whileSchleife verwendeten.
0xC0000022L
8

Hier ist eine portable Möglichkeit, alle wichtigen Fingerabdrücke für eine bestimmte Datei anzuzeigen, die auf Mac und Linux getestet wurde:

#!/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
}

Beispiel Verwendung:

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 $ 
Wille
quelle
Es tut mir leid, das zu sagen, aber das ist weder "einfacher" noch "kleiner", nicht einmal "schlauer" und verfolgt keinen anderen Ansatz als den oben aufgeführten. nur ein Skript mit mehr Fehlerbehandlungsroutinen;)
childno͡.de
3
Was macht es sicherer, oder? Sie können gerne Änderungen vornehmen, aber warum nicht? Ich habe nicht vorgeschlagen, dass dies eine bessere Lösung ist als Ihre. Ich bin der Meinung, dass ein sicheres tempfile besser ist und dass mehr Sicherheit für Skriptzwecke erforderlich ist. Die obige Version ist auch nicht schlagbruchsicher.
Wird
Für ein FreeBSD-System (das standardmäßig kein bash verwendet) habe ich folgende Änderungen vorgenommen: Angenommen, bash wird von Ports installiert, ändern Sie die erste Zeile in #!/usr/local/bin/bash. Ich rief dann die Funktion durch das Hinzufügen dieser als letzte Zeile: fingerprint_keys $@. Ich habe das Skript als gespeichert fingerprints.bashund es als ausführbar markiert chmod u+x ./fingerprints.bash. Außerdem habe ich der Datei einen Kommentar mit dem Link zu dieser Antwort hinzugefügt, ähnlich wie oben # solution from "Will" on SO http://serverfault.com/a/615892/126742. Nenne es so ./fingerprints.bash ~/.ssh/authorized_keys.
Derekv
1
@derekv: Die portablere Methode ist die Verwendung des folgenden Hashbangs:, #!/usr/bin/env bashda der Pfad für envsehr portabel ist und angibt , envden Bash auszuführen, über den er Bescheid weiß.
0xC0000022L
7

Ein Einzeiler basierend auf dem / dev / stdin- Trick aus ℝaphinks Antwort und man xargs → BEISPIELE :

egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'
akavel
quelle
Dies funktioniert hervorragend und kann, vorausgesetzt es handelt sich um einen Einzeiler, problemlos verwendet werden, um den Befehl über SSH auszuführen. Vielen Dank!
Thibaut Barrère