如何使用已知密钥通过 SSH 连接到未知主机名?

如何使用已知密钥通过 SSH 连接到未知主机名?

我有一台通过 VPN 连接到公司网络的机器。当我连接到 VPN 时,它总是给我一个不同的主机名和 IP 地址。主机名始终是 remote-[IP 地址的最后八位字节]。每当我想通过 SSH 进入我的机器时,我首先必须运行“hostname -A”来查看主机名是什么。问题是,当我需要访问计算机时,我并不总是知道我的主机名是什么。(如果我去计算机的物理位置查找主机名,它就不需要 SSH 了。)

我可以使用 SSH 并尝试子网中的每个主机名/ip,直到找到与正确密钥文件匹配的主机名/ip 吗?


我正在使用 Windows 笔记本电脑(也通过 VPN 连接)和 cygwin 通过 ssh 连接到 Ubuntu 12.04 机器。我不确定为什么连接到 VPN 时会得到不同的主机名,但这是企业网络,所以他们可以做任何他们想做的事情。

答案1

这不是端口扫描

这里我们将仅使用基本的 ssh 实用程序ssh-keyscan进行ssh-keygen网络连接/密钥转换。

如果您知道服务器指纹

并且想要搜索它,那么你可以这样做:

for x in {1..254}; do ssh-keyscan 10.0.0.$x > /tmp/ssh-scan.log 2> /dev/null; cat /tmp/ssh-scan.log; ssh-keygen -lf /tmp/ssh-scan.log | grep -v 'not a public key file' ; done

它将打印所有找到的主机的指纹。上面的行将遍历 10.0.0.1 - 10.0.0.254,尝试从每个主机获取公钥,最后将公钥转换为指纹并显示。大多数常见错误消息都会重定向到从 找到的黑洞/dev

或者搜索公钥

然后同样的事情,没有指纹转换器,显示所有主机的公钥之间10.0.0.0 和 10.0.0.255:

for x in {1..254}; do ssh-keyscan 10.0.0.$x 2> /dev/null; done

最终答案,ssh seek'n'connect 脚本

最初发布者用户229010作为评论,我只是把它清理干净了:-)

for i in {1..255}; do 
    echo trying remote-$i
    ping -w 1 -c 1 remote-$i > /dev/null
    if [ $? -eq 0 ]; then
        # this is a live ip
        echo remote-$i is up
        if ssh-keyscan remote-ca$i | grep $expected_key -m1 -c > /dev/null; then
            # this is my machine
            ssh remote-$i
            exit 0
        fi
    fi
done

答案2

这里有几个选项,从最简单到最复杂列出。不出所料,这些选项依次为好、更好、最好。

  1. 使用 crontab 以一定间隔更新远程系统上具有您的主机名的文件。
    创建/编辑 Crontab: crontab -e
    添加 Crontab 条目:要创建一个仅在周末工作日每小时更新文件的作业,请使用此示例:

    00 09-18**1-5 SSH[电子邮件保护]“回显 $(主机名 -A) > ubuntuhost.name”

  2. 使用 crontab 每隔一段时间通过电子邮件将您的主机名发送给自己。
    安装Mailutils: sudo apt-get update && sudo apt-get install mailutils注意:如果 mailutils 安装支持,请选择“互联网连接”,这应该是第一个选项。
    创建/编辑 Crontab: crontab -e
    添加 Crontab 条目:要创建一个作业,在周末工作日每小时向您发送一封带有主机名主题行的电子邮件,请使用此示例:

    00 09-18 * * 1-5 邮件 -s “Ubuntu $(主机名 -A)”[电子邮件保护]< /dev/null

  3. 每当连接发生变化时,使用 NetworkManager Dispatcher 通过电子邮件发送当前主机名。
    将此脚本放入 /etc/NetworkManager/dispatcher.d,并将其命名为“50emailhostname”

/bin/sh -e #!/bin/sh -e
#确保我可以执行 (chmod 775)

echo "接口:$1,操作:$2" >> /tmp/interface.log #debug

如果 [ “$1” = “eth0” ] && [ “$2” = “up” ]
然后
  mail -s“Ubuntu $(主机名-A)”[电子邮件保护]> /tmp/interface.log#调试
别的
  echo "false" >> /tmp/interface.log#debug

出口

笔记:

  • 您可能需要将脚本中的“eth0”更改为“vpn0”或其他内容,具体取决于您的客户端
  • 您可能需要将“up”更改为“vpn-up”
  • 使用调试语句来获取所需的行为!
  • tail -f /tmp/interfaces.log在单独的窗口中查看它正在做什么
  • 根据需要使用 service network-manager restart 重新启动网络服务
  • 完成后注释掉调试语句
  • 你可以使用类似以下命令获取 IP 地址而不是主机名
    $(ifconfig | awk -F':' '/inet addr/&&!/127.0.0.1/{split($2,_," ");print _[1]}')

答案3

让远程机器在某处报告其 IP 会更有意义。例如,通过运行 crontab 连接到本地机器,通过 ssh 将主机名写入文件。如果您在问题中更新更多详细信息(什么操作系统?您的本地机器是否可通过网络访问?),我可以告诉您如何执行此操作。

无论如何,要尝试子网中的所有 IP,假设您已经arp安装,您可以执行以下操作:

for ip in `arp | grep -v Add | awk '{print $1}'`; do ssh $ip; done

答案4

如果你想暴力破解你的 ubuntu 机器使用的 IP,OpenSSH 有一个名为 ssh-keyscan 的工具可以扫描网络以查找 ssh 主机密钥:

for ((a=0;a<255;a++)); do echo 198.51.100.$a; done | ssh-keyscan -f -H > ssh_id_list

你只需要知道哪一个是你的服务器。你可以直接从你的服务器获取它,或者你可以利用你的客户端在第一次连接时将它们存储在 ~/.ssh/known_hosts 中的事实:

ssh-keygen -F last_ip_you_used_to_connect -l

然后只需使用它来 grep ssh-keyscan 。


另一种可能性是使用 mDNS:这是一种分布式 DNS 解决方案,在 VPN 允许多播流量的情况下运行良好。Ubuntu 桌面上默认安装了该解决方案(如果hostname -A显示yourhostname.local,则表示正常)。如果碰巧 iTunes(或任何其他安装 Bonjour 的 Apple 软件)安装在 Windows 中,那么您只需连接到它yourhostname.local,它就会立即工作。否则,如果您有另一台 Ubuntu 机器,并且已知 IP 地址并安装了 mDNS 响应器,只需连接到它并要求它解析或 pingyourhostname.local

相关内容