私は、最近すべて新しい OpenSSH ホスト キーで再構成された約 30 台のマシンのクラスターを使用しています。ログインしようとすると、次のエラー メッセージが表示されます (簡潔にするために多くの行が削除されています)。
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
The fingerprint for the RSA key sent by the remote host is
52:bb:71:83:7e:d0:e2:66:92:0e:10:78:cf:a6:41:49.
Add correct host key in /home/nr/.ssh/known_hosts to get rid of this message.
Offending key in /home/nr/.ssh/known_hosts:50
問題のある行を手動で削除することもできますが、その場合、別の行を手動で削除する必要があるため、IP アドレスについて別の苦情が寄せられます。この作業を 29 回繰り返す必要はありません。それを行うプログラムを書きたいと思います。残念ながら、.ssh ファイルの行には、以前のバージョンのようにホスト名と IP アドレスがクリア テキストで含まれなくなりました。
だからここに私の質問があります:
- ホスト名と IP アドレスが与えられた場合、ストアのどの行に
~/.ssh/known_hosts
そのホストまたは IP アドレスの SSH ホスト キーがあるかを調べるプログラムを作成するにはどうすればよいでしょうか?
この情報を復元できれば、あとは自分でできると思います。
脚注: 私は bash/ksh/sh または C または Lua でコーディングすることを好みます。私の Perl と Python は非常にさびています。
説明:
ファイル全体を削除して再作成したくありません。再検証したくない100以上の検証済みキーが含まれています.
維持するマスター コピーが 1 つであろうと複数のレプリカであろうと、古くなったホスト キーの大規模なグループを削除するという問題は残ります。
答え
これが私が使用して書いたLuaスクリプトですssh-keygen -F
:
#!/usr/bin/env lua
require 'osutil'
require 'ioutil'
local known = os.getenv 'HOME' .. '/.ssh/known_hosts'
local function lines(name)
local lines = { }
for l in io.lines(name) do
table.insert(lines, l)
end
return lines
end
local function remove_line(host)
local f = io.popen('ssh-keygen -F ' .. os.quote(host))
for l in f:lines() do
local line = l:match '^# Host %S+ found: line (%d+) type %u+$'
if line then
local thelines = lines(known)
table.remove(thelines, assert(tonumber(line)))
table.insert(thelines, '')
io.set_contents(known, table.concat(thelines, '\n'))
return
end
end
io.stderr:write('Host ', host, ' not found in ', known, '\n')
end
for _, host in ipairs(arg) do
local ip = os.capture('ipaddress ' .. host)
remove_line(host)
remove_line(ip)
end