Como obter todas as impressões digitais para o arquivo .ssh / allowed_keys (2)

39

Existe uma maneira simples de obter uma lista de todas as impressões digitais inseridas nas .ssh / allowed_keys || Arquivo .ssh / allowed_keys2?

ssh-keygen -l -f .ssh/authorized_keys 

retornará apenas a impressão digital da primeira linha / entrada / chave pública

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

mas existe uma maneira mais fácil ou comando ssh que não encontrei?

childno͡.de
fonte
Para fazer isso de maneira confiável, é necessário considerar o campo de opções no authorized_keysarquivo, no qual os ssh-keygenbaulks estão. Procurei uma maneira confiável de analisá-lo, mas o melhor que pude apresentar está coberto por esta resposta .
starfry

Respostas:

45

Aqui está outro truque usando o bash simples, sem arquivos temporários:

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

Você pode facilmente torná-lo uma função no seu .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 chame-o com:

$ fingerprints .ssh/authorized_keys
ℝaphink
fonte
11
@Raphink, obrigado. added code.childno.de/marcel/changeset/afdce0dd ;) Uma observação: ssh-keygen -l -f /dev/stdinparece não funcionar em um mac .. não obstante, não é relevante para servidores, mas gnaa apple ou é um "problema" do BSD /dev/stdin is not a public key file.?
Childno͡.de
11
Lendo a partir /dev/stdinnão é uma grande idéia, em geral, é melhor usar -, mas por alguma razão ssh-keygennão sabe sobre -...
ℝaphink
Não funciona no Mac?
Will
11
Isso não funciona se as chaves forem prefixadas com opções.
starfry
11
@ Aphink: eu iria local file="${1:-$HOME/.ssh/authorized_keys}"permitir que ele funcione sem argumentos e usar como padrão o ~/.ssh/authorized_keysarquivo usual e citar o < "$file"usado como entrada para o whileloop.
0xC0000022L
8

Aqui está uma maneira portátil de mostrar todas as principais impressões digitais de um determinado arquivo, testado no 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
}

Exemplo 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 $ 
Vai
fonte
lamento dizer isso, mas isso não é "mais simples", nem "menor", nem mesmo "mais inteligente" e não adota outra abordagem além da listada acima. apenas um script usando mais manipuladores de erro;)
childno͡.de
3
O que o torna mais seguro, certo? Você pode fazer edições, mas por que voto negativo? Não propus que fosse qualquer tipo de solução melhor que a sua ... Sinto que um arquivo temporário seguro é melhor e que é necessária mais segurança para fins de script. Além disso, a versão acima é segura para noclobber.
Will
Para um sistema FreeBSD (que não usa o bash por padrão), fiz as seguintes alterações: Supondo que o bash esteja instalado a partir das portas, altere a primeira linha para #!/usr/local/bin/bash. Eu, então, chamado a função adicionando esta como a última linha: fingerprint_keys $@. Salvei o script como fingerprints.bash, marcando-o como executável chmod u+x ./fingerprints.bash. Além disso, adicionei um comentário ao arquivo com o link para esta resposta, assim, próximo ao topo # solution from "Will" on SO http://serverfault.com/a/615892/126742. Chame assim ./fingerprints.bash ~/.ssh/authorized_keys.
precisa saber é o seguinte
11
@derekv: o método mais portátil é usar o seguinte hashbang:, #!/usr/bin/env bashporque o caminho para envé muito portátil e ele diz envpara executar o Bash que ele conhece.
0xC0000022L
7

Um one-liner baseado no truque / dev / stdin da resposta de ℝaphink e man xargs → EXEMPLOS :

egrep '^[^#]' ~/.ssh/authorized_keys | xargs -n1 -I% bash -c 'ssh-keygen -l -f /dev/stdin <<<"%"'
akavel
fonte
Isso funciona muito bem e, como é uma linha, pode ser facilmente usado para executar o comando via SSH. Obrigado!
Thibaut Barrère