我使用了大约30台机器的集群,这些机器最近都使用新的OpenSSH主机密钥进行了重新配置。当我尝试登录一个时,我收到此错误消息(为简洁起见删除了许多行):
@ 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地址。
所以这是我的问题:
~/.ssh/known_hosts
哪些行存储该主机或IP地址的SSH主机密钥? < / LI>
如果我可以恢复这些信息,我想我可以自己完成剩下的工作。
脚注:我更喜欢用bash / ksh / sh或C或Lua编码;我的Perl和Python非常生疏。
澄清:
我不想删除整个文件并重新填充它;它包含一百多个经验证的密钥,我不想重新验证。
无论是维护单个主副本还是多个副本,都会留下擦除大量过时主机密钥的问题。
这是我用ssh-keygen -F
编写的Lua脚本:
#!/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
答案 0 :(得分:2)
好的
ssh-keygen -R hostname
ssh-keygen -R ipaddress
我个人用loop和perl擦除IP地址,然后手动删除冲突。
$!/usr/bin/perl
for (1..30){
`ssh keygen -R 192.168.0.$_`; #note: backticks arent apostrophies
}
欢呼声, 风暴
答案 1 :(得分:1)
如果我想知道主持人的条目在哪一行,
ssh-keygen -F hostname
同样的技巧适用于IP地址。
答案 2 :(得分:1)
触摸并修改“clearkey.sh”或任何名字让你开心。
#! /bin/bash
# $1 is the first argument supplied after calling the script
sed -i "$1d" ~/.ssh/known_hosts
echo "Deleted line $1 from known_hosts file"
应该可以执行“clearkey.sh 3”并删除违规行!
答案 3 :(得分:0)
我通常在bash脚本checkssh
中执行以下操作以自动删除该行:
#!/bin/bash
# Path to "known_hosts" file
KH=~/.ssh/known_hosts
# Find the host in the file, showing line number
L=`grep -i -n $1 $KH`
# If line is not found, exit
if [ $? -ne 0 ] ; then exit ; fi
# Isolate line number
L=`echo $L | cut -f 1 -d :`
sed -i "${L}d" $KH
如果您的ssh配置为这样,您可以在末尾添加ssh $1 exit
以自动在文件中重新创建条目。
将其称为checkssh <hostname>
。
答案 4 :(得分:0)
编写脚本时,您可能想尝试以下方法:
declare CHANGED_HOST_NAME="host.yourpublic.work";
declare CHANGED_HOST_IP=$(dig +short ${CHANGED_HOST_NAME});
# Remove old IP address if found
[ -z ${CHANGED_HOST_IP} ] || ssh-keygen -R ${CHANGED_HOST_IP};
# Remove old host key
ssh-keygen -R ${CHANGED_HOST_NAME};
# Add new host key
ssh-keyscan ${CHANGED_HOST_NAME} >> $HOME/.ssh/known_hosts;
非常感谢@Storm Knight(@ 289844)