Как получить все отпечатки для файла .ssh / authorized_keys (2)

39

Есть ли простой способ получить список всех отпечатков пальцев, введенных в .ssh / authorized_keys || Файл .ssh / authorized_keys2?

ssh-keygen -l -f .ssh/authorized_keys 

вернет только отпечаток первой строки / записи / публичного ключа

взломать с помощью 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"
        )
    }
}'

но есть ли более простой способ или команда ssh, которую я не нашел?

childno͡.de
источник
Чтобы сделать это надежно, вы должны рассмотреть поле опций в authorized_keysфайле, в котором ssh-keygenскрывается ошибка. Я искал надежный способ разобрать его, но лучшее, что я мог придумать, покрыто этим ответом .
Starfry

Ответы:

45

Вот еще один хак с использованием простого bash без временных файлов:

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

Вы можете легко сделать это функцией в вашем .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}"
}

и назовите это с:

$ fingerprints .ssh/authorized_keys
ℝaphink
источник
1
хороший @Raphink, спасибо. добавлено code.childno.de/marcel/changeset/afdce0dd ;) Одно замечание: ssh-keygen -l -f /dev/stdinпохоже, не работает на Mac .. но, тем не менее, не относится к серверам, но gnaa apple или это проблема BSD /dev/stdin is not a public key file.?
childno͡.de
1
Чтение из /dev/stdinне очень хорошая идея в целом, лучше использовать -, но по какой-то причине ssh-keygenне знает о -...
ℝaphink
Не работает на Mac?
Будет ли
1
Это не работает, если ключи имеют префикс с параметрами.
Звездный день
1
@ Haphink: я бы хотел, local file="${1:-$HOME/.ssh/authorized_keys}"чтобы это работало без каких-либо аргументов, и по умолчанию использовал обычный ~/.ssh/authorized_keysфайл, и цитировал его < "$file"как входные данные для whileцикла.
0xC0000022L
8

Вот портативный способ показать все ключевые отпечатки пальцев для данного файла, протестированного на Mac и 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
}

Пример использования:

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 $ 
Будет
источник
извините, но это ни «проще», ни «меньше», ни даже «умнее» и не использует другой подход, чем перечисленный выше. просто скрипт, использующий больше обработчиков ошибок;)
childno͡.de
3
Что делает это безопаснее, верно? Вы можете вносить изменения, но зачем понижать голос? Я не предлагал, чтобы это было какое-то лучшее решение, чем ваше ... Я чувствую, что безопасный временный файл лучше, и что для сценариев требуется больше безопасности. Кроме того, вышеприведенная версия безопасна для noclobber.
Будет
Для системы FreeBSD (которая по умолчанию не использует bash) я внес следующие изменения: Предполагая, что bash установлен из портов, измените первую строку на #!/usr/local/bin/bash. Я тогда назвал функцию, добавив это в последней строке: fingerprint_keys $@. Я сохранил скрипт как fingerprints.bash, пометив его как исполняемый chmod u+x ./fingerprints.bash. Кроме того, я добавил комментарий к файлу со ссылкой на этот ответ, например, в самом верху # solution from "Will" on SO http://serverfault.com/a/615892/126742. Назовите это так ./fingerprints.bash ~/.ssh/authorized_keys.
Дерекв
1
@derekv: более переносимый метод заключается в использовании следующего hashbang:, #!/usr/bin/env bashпотому что путь для envнего очень переносимый, и он говорит envвыполнить Bash, о котором он знает.
0xC0000022L
7

Однострочник, основанный на уловке / dev / stdin из ответа ℝaphink и man xargs → ПРИМЕРЫ :

egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'
akavel
источник
Это прекрасно работает, и, учитывая его однострочность, может быть легко использовано для запуска команды через SSH. Благодарность!
Тибо Баррер