代码之家  ›  专栏  ›  技术社区  ›  Norman Ramsey

如何编写程序(脚本)从~/.ssh/known_主机中删除过时的主机密钥?

  •  0
  • Norman Ramsey  · 技术社区  · 16 年前

    我使用了一个由大约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

    如果我能恢复这些信息,我想我可以自己做剩下的事情。


    脚注:我更喜欢用bash/ksh/sh或C或Lua编写代码;我的Perl和Python已经非常过时了。


    澄清:

    • 我不想删除整个文件并重新填充它;它包含100多个经过验证的密钥,我不想重新验证。

    答复

    下面是我使用 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 回复  |  直到 16 年前
        1
  •  4
  •   Matthieu    7 年前
    ssh-keygen -R hostname
    ssh-keygen -R ipaddress
    

    就我个人而言,我使用循环和perl清除IP地址,并手动消除冲突。

    $!/usr/bin/perl
    for (1..30){
         `ssh keygen -R 192.168.0.$_`; #note: backticks arent apostrophies
    }
    
        2
  •  1
  •   Norman Ramsey    16 年前

    ssh-keygen -F hostname
    

        3
  •  1
  •   thedarkness    15 年前

    触摸并编辑“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.sh3”,它将删除违规行!

        4
  •  0
  •   Matthieu    7 年前

    我通常在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> .

        5
  •  0
  •   Martin Bramwell    6 年前

    编写脚本时,您可能希望尝试以下操作:

    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)