![如何使用已知密钥通过 SSH 连接到未知主机名?](https://linux22.com/image/1365699/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%B7%B2%E7%9F%A5%E5%AF%86%E9%92%A5%E9%80%9A%E8%BF%87%20SSH%20%E8%BF%9E%E6%8E%A5%E5%88%B0%E6%9C%AA%E7%9F%A5%E4%B8%BB%E6%9C%BA%E5%90%8D%EF%BC%9F.png)
我有一台通过 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
这里有几个选项,从最简单到最复杂列出。不出所料,这些选项依次为好、更好、最好。
使用 crontab 以一定间隔更新远程系统上具有您的主机名的文件。
创建/编辑 Crontab:crontab -e
添加 Crontab 条目:要创建一个仅在周末工作日每小时更新文件的作业,请使用此示例:00 09-18**1-5 SSH[电子邮件保护]“回显 $(主机名 -A) > ubuntuhost.name”
使用 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
每当连接发生变化时,使用 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