web-dev-qa-db-ja.com

www.github.comをknown_hostsファイルに追加する安全で正しい方法は何ですか?

Ssh経由でgithubリポジトリにアクセスしたい。初めてリポジトリにアクセスすると、github sshサーバーをknown_hostsファイルに追加するかどうかを尋ねられます。これは正常に機能します。このリクエストでは、そのサーバーのRSAキーフィンガープリントも表示され、github here によって提供されるものと同じであることを手動で確認できます。

これらは、OpenSSH 6.8以降(base64形式)で表示されるSHA256ハッシュです。

SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8 (RSA)
SHA256:br9IjFspm1vxR3iA35FWE+4VTyz1hYVLIE2t1/CeyWQ (DSA)

問題は、私のgitリポジトリに最初にアクセスする前に、公開鍵をknown_hostsファイルに追加することで、その要求を防止したいということです。これは、ssh-keyscan -t rsa www.github.comコマンドを使用して実行できます。このコマンドは、known_hostsファイルで必要な形式の公開鍵を取得します。しかし、これは安全ではなく、中間者攻撃に対して脆弱であると人々は繰り返し言及します。彼らが言及していないのは、それを正しく行う方法です。

では、githubページで提供されているRSAフィンガープリントを使用して、sshサーバーの公開ホストキーを安全に取得するにはどうすればよいですか?予想されるrsaフィンガープリントを追加できるssh-keyscanコマンドのオプションを多かれ少なかれ探しています。ホストのフィンガープリントが指定されたものと一致しない場合、コマンドは失敗します。

お時間をいただきありがとうございます!

12
Knitschi

私は...するだろう ない その場合はssh-keyscanを使用してください。
むしろ、私はそれを使用しGitHubによって提供されたものとそのフィンガープリントを比較して結果を再確認します。

次に SSH GitHub test を実行して、次のことを確認します。

Hi username! You've successfully authenticated, but GitHub does not
provide Shell access.

したがって、手動プロセスでは ここで推奨

ssh-keyscan github.com >> githubKey

フィンガープリントを生成します。

ssh-keygen -lf githubKey

GitHubが提供するものと比較してください

最後に、githubKeyコンテンツを~/.ssh/known_hostsファイルにコピーします。


wercker/step-add-to-known_hosts を使用して、そのプロセス(指紋ステップチェックを含む)を自動化できます。これは- wercker step ですが、独自の独立したスクリプトとして推定できます。

- add-to-known_hosts:
    hostname: github.com
    fingerprint: 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
    type: rsa

しかし、それは help.github.com/articles/github-s-ssh-key-fingerprints に対するチェックに欠けます。以下を参照してください。


ここで説明 のように、nmapを使用してもあまり役に立ちません。

nmapを使用してSSHホストキーのフィンガープリントを取得し、それをssh-keyscanのフィンガープリントと比較します。どちらの場合も、フィンガープリントはと同じです 場所。
これは、これらの他の自動化ソリューションと同様にMITMに対して脆弱です。

SSH公開鍵を確認するための安全で有効な唯一の方法は、信頼できる帯域外チャネルを使用することです。 (または、ある種の鍵署名インフラストラクチャーをセットアップします。)

ここでは、 help.github.com/articles/github-s-ssh-key-fingerprints は「信頼できる帯域外チャネル」のままです。

9
VonC

VonC の回答に基づいて、以下のスクリプトはキーを確認して自動的に追加できます。次のように使用します。

$ ./add-key.sh github.com nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8

指紋の検証と保存に成功したかどうかがわかります。
使用情報については、./add-key.sh --helpを使用してください

スクリプト:

#!/usr/bin/env bash

# Settings
knownhosts=$HOME/.ssh/known_hosts

if [ "x$1" == "x-h" ] || [ "x$1" == "x--help" ] || [ ${#1} == 0 ]; then
    echo "Usage: $0 <Host> <fingerprint> [<port>]"
    echo "Example: $0 github.com nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8"
    echo "The default port is 22."
    echo "The script will download the ssh keys from <Host>, check if any match"
    echo "the <fingerprint>, and add that one to $knownhosts."
    exit 1
fi

# Argument handling
Host=$1
fingerprint=$2
port=$(if [ -n "$3" ]; then echo "$3"; else echo 22; fi)

# Download the actual key (you cannot convert a fingerprint to the original key)
keys=$(ssh-keyscan -p $port $Host 2> /dev/null);
if [ ${#keys} -lt 20 ]; then echo Error downloading keys; exit 2; fi

# Find which line contains the key matching this fingerprint
line=$(ssh-keygen -lf <(echo "$keys") | grep -n "$fingerprint" | cut -b 1-1)

if [ ${#line} -gt 0 ]; then  # If there was a matching fingerprint
    # Take that line
    key=$(head -$line <(echo "$keys") | tail -1)
    # Check if the key part (column 3) of that line is already in $knownhosts
    if [ -n "$(grep "$(echo "$key" | awk '{print $3}')" $knownhosts)" ]; then
        echo "Key already in $knownhosts."
        exit 3
    else
        # Add it to known hosts
        echo "$key" >> $knownhosts
        # And tell the user what kind of key they just added
        keytype=$(echo "$key" | awk '{print $2}')
        echo Fingerprint verified and $keytype key added to $knownhosts
    fi
else  # If there was no matching fingerprint
    echo MITM? These are the received fingerprints:
    ssh-keygen -lf <(echo "$keys")
    echo Generated from these received keys:
    echo "$keys"
    exit 1
fi
4
Luc