.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コマンドはありますか?


これを確実に行うには、authorized_keysファイルのオプションフィールドを考慮する必要がありますssh-keygen。私はそれを解析するための信頼できる方法を探しましが、私が思いつくことができる最高のものはこの答えでカバーされています
スターフライ

回答:


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

1
素敵な@Raphink、ありがとう。追加code.childno.de/marcel/changeset/afdce0dd ;)ワンノート:ssh-keygen -l -f /dev/stdinサーバー用に関連するにもかかわらず... Mac上で動作しないではないようだが、gnaaのリンゴまたはそれはBSD「問題」になっています/dev/stdin is not a public key file.?!
childno͡.de

1
以下からの読み込み/dev/stdin、一般的には素晴らしいアイデアではありません、それはより有効に活用するのです-が、いくつかの理由ssh-keygenについて知らない-...
ℝaphink

Macでは動作しませんか?
ウィル

1
キーの前にオプションが付いている場合、これは機能しません。
スターフライ

1
@ℝaphink: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͡.de14年

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
derekv

1
@derekv:より移植性の高い方法は、次のhashbangを使用することです:#!/usr/bin/env bashのパスenvは非常に移植性が高くenv、知っているBashを実行するように指示するためです。
0xC0000022L

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.