Как мне написать программу (скрипт) для удаления устаревших ключей хоста из ~ / .ssh / known_hosts? - PullRequest
0 голосов
/ 19 декабря 2009

Я использую кластер из примерно 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-адреса, как это было в более ранних версиях.

Так вот мой вопрос:

  • Учитывая имя хоста и IP-адрес, как я могу написать программу, чтобы узнать, какие строки моего ~/.ssh/known_hosts хранят ключ хоста SSH для этого хоста или IP-адреса?

Если я смогу восстановить эту информацию, я думаю, что смогу сделать все остальное сам.


Сноска: я бы предпочел кодировать в bash / ksh / sh или C или Lua; мой Perl и Python очень ржавые.


Разъяснения:

  • Я не хочу удалять весь файл и заново его заполнять; он содержит более ста проверенных ключей, которые я предпочитаю не подтверждать повторно.

  • Сохраняю ли я одну мастер-копию или несколько реплик, проблема очистки большой группы устаревших ключей хоста остается.

Ответ

Вот скрипт 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

Ответы [ 4 ]

3 голосов
/ 09 марта 2010
ssh-keygen -R hostname
ssh-keygen -R ipaddress

лично я вычищаю IP-адреса с помощью цикла и perl и удаляю конфликты вручную.

$!/usr/bin/perl
for (1..30){
     `ssh keygen -R 192.168.0.$_`; #note: backticks arent apostrophies
}
1 голос
/ 17 апреля 2011

коснитесь и отредактируйте «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", и он удалит ошибочную строку!

1 голос
/ 20 декабря 2009

Если я хочу узнать, в какой строке находится запись для хоста,

ssh-keygen -F hostname

Тот же трюк работает с IP-адресами.

0 голосов
/ 04 июля 2013

Я обычно делаю следующее в 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
[[ $? -ne 0 ]] && exit
# Isolate line number
L=`echo $L | cut -f 1 -d :`
sed -i "${L}d" $KH

Вы можете добавить ssh $1 exit в конце, чтобы автоматически воссоздать запись в файле, если ваш ssh настроен для этого.

Назовите это как checkssh <hostname>.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...