
次のシナリオを想像してみましょう。
特定のホスト名のホスト キーを持っているのでABCDEF1234
、known_hosts
ファイルは次のようになります (ハッシュ化されていないバージョン)。
example.com ssh-rsa ABCDEF1234
今接続すると、ホスト名は10.11.12.13に解決され、次のようなメッセージが表示されます
Warning: Permanently added the ECDSA host key for IP address '10.11.12.13' to the list of known hosts.
そして、私のknown_hostsは次のようになります
example.com ssh-rsa ABCDEF1234
192.0.2.1 ssh-rsa ABCDEF1234
数か月後、example.com
管理者から RSA キーが削除され、 キーに変更されたと通知されました1234ABCDEF
。 を使用して問題のキーを削除しssh-keygen -R example.com
、初めて接続してキーを受け入れると、 はknown_host
次のようになります。
192.0.2.1 ssh-rsa ABCDEF1234
example.com ssh-rsa 1234ABCDEF
そして、接続するたびに、次のような警告メッセージが表示されます。
Warning: the ECDSA host key for 'example.com' differs from the key for the IP address '192.0.2.1'
Offending key for IP in /home/jenkins/.ssh/known_hosts:162
Matching host key in /home/jenkins/.ssh/known_hosts:182
ここで、その特定のホスト名に数十または数百の IP があると想像してください。これは、クリーンアップする行が非常に多いことを意味します。 1 つの解決策は、 を使用してsed
一致する行を削除することですが、 の目的はssh-keygen -R
を混乱させないようにすることではないでしょうsed
か。
sed -i '/ABCDEF1234/d' known_hosts
known_host
ホスト名や IP アドレスではなく、特定のキーに関連付けられているすべてのエントリをファイルから削除する別の解決策はありますか?
答え1
の目的は のssh-keygen -R
使用を避けることではなくsed
、例えば がsed
見つからないハッシュ化されたホストを削除することです。ssh-keygen(1):
-R hostname
hostname
ファイルに属するすべてのキーを削除しますknown_hosts
。このオプションは、ハッシュされたホストを削除する場合に便利です (-H
上記のオプションを参照)。
-H
ファイルをハッシュします
known_hosts
。これにより、指定されたファイル内のすべてのホスト名とアドレスがハッシュ表現に置き換えられます。元のコンテンツは、サフィックス付きのファイルに移動されます。これらのハッシュは通常、および.old
で使用できますが、ファイルの内容が公開された場合でも、識別情報は公開されません。このオプションは、既存のハッシュされたホスト名を変更しないため、ハッシュされた名前とハッシュされていない名前が混在するファイルで安全に使用できます。ssh
sshd
考慮事項
衝突を避ける
他の鍵を削除しないようにするには、Base64でエンコードされた完全な公開鍵を使用するのが最善です。たとえば、ヘッダ同じタイプのキーがすべて削除されることになります。
ベース64 | アスキー | 参照 |
---|---|---|
AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY AAAAIbmlzdHAyNTYAAABBB |
....ecdsa-sha2-nistp256 ....nistp256...A |
RFC 5656、3.1 |
AAAAC3NzaC1lZDI1NTE5AAAAIFKy |
....ssh-ed25519... R² |
RFC 8709、4 |
AAAAB3NzaC1yc2EAAAADAQABAAABAQ |
...ssh-rsa........... |
RFC 4253、6.6 |
sed
Base64に合わせて調整する
Base64 でエンコードされた公開鍵には文字 が含まれていますA-Za-z0-9+/=
。例/
で使用されている が含まれている可能性があるためsed
、 のような別の文字を使用する必要があります:
。
実例
例:
- は
AAAA+OLD/KEY=
、満杯古い公開鍵。 - は
AAAA+NEW/KEY=
、満杯新しい公開鍵。
同じキーを持つすべてのホストを削除します
完全な古いキーを使用して、それを含むすべての行を削除します。
sed -i ':AAAA+OLD/KEY=:d' ~/.ssh/known_hosts
古い鍵を新しい鍵に交換する
完全なキー (古いキーと新しいキー) を使用して、古いキーを含むすべての行を置き換えます。
sed -i 's:AAAA+OLD/KEY=:AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
キータイプも変更された場合は、それを含める必要があります。例:
sed -i 's:ssh-rsa AAAA+OLD/KEY=:ecdsa-sha2-nistp256 AAAA+NEW/KEY=:g' ~/.ssh/known_hosts
ホスト名またはIPのキーを削除します
これは、 を使用する唯一のユースケースですssh-keygen
。
ssh-keygen -R example.com
ssh-keygen -R 192.0.2.1
答え2
そもそも問題を回避することは良い解決策です。known_hosts に特定のホスト名のすべての IP のエントリが入力されていなければ、sed を操作する必要はありません。ssh_keygen -R hostname
キーのローテーションを実行するだけで十分です。
したがって、これに対する私の解決策は、ssh 構成でCheckHostIP
を設定することです。no