用主机名代替 IP 地址连接 Hyper-V Ubuntu 虚拟机

用主机名代替 IP 地址连接 Hyper-V Ubuntu 虚拟机

每台 Hyper-V 虚拟机实例的 IP 地址都会随着宿主机的重启而变化。如果经常用 SSH 连接运行 Linux 的虚拟机,每次连接都需要输入密码或者配置免密连接,相当麻烦。

尽管可以在 Hyper-V 管理器创建新的内部虚拟交换机,将 Linux 虚拟机的虚拟网卡连接到这台虚拟交换机,并为之设置固定 IP,但是,这样就影响了这台 Linux 虚拟机与其他虚拟机之间的沟通。

一个偶然的机会,我发现了 Linux 内置的 Avahi 服务,它自动为运行 Linux 的电脑设置一个主机名,我们可以用主机名代替 IP 地址来连接 Linux 电脑。我使用的 Ubuntu 20.04 LTS 已经内置了 Avahi,开箱即用,毫不复杂。

什么是 Avahi?

Avahi 本来的意思是毛狐猴,它们只生活在非洲马达加斯加岛的热带雨林。Avahi 软件的 LOGO,就是一只毛狐猴的卡通画。
东部毛狐猴,图源:维基百科

Avahi 作为一个软件,它可以自动为运行 Linux 的电脑设置一个主机名,用主机名代替 IP 地址。IP 地址会经常变,但是 Avahi 生成的主机名不会变,我们可以用主机名代替 IP 地址来连接 Linux 电脑。考虑到 Hyper-V 总是改动虚拟机实例的 IP 地址,Avahi 和 Hyper-V 简直是天造地设的一对!

Avahi 的原理是什么?

Avahi 的原理是多播 DNS(multicast DNS),又称为 DNS 服务发现(DNS service discovery,DNS-SD),基于 TCP/IP 协议。Avahi 生成的「主机名」其实是「内网域名」,即只能在局域网内部使用域名。

举个例子。我有一台 Linux 电脑,主机名是 Ubuntu2004LTS。Avahi 会在局域网内部通过 mDNS 让每台电脑都能把内网域名 Ubuntu2004LTS.local 解析到这台 Linux 电脑。我在局域网内部任何一台电脑的终端输入 ssh kukmoon@Ubuntu2004LTS.local,就能通过 SSH 连接到这台 Linux 电脑。

Avahi 生成的主机名与 Windows 的「计算机名」类似,开箱即用,毫不复杂,无需另外配置。但是二者原理完全不同。上文已经介绍 Avahi 的原理是基于 TCP/IP 协议的多播 DNS,而 Windows 电脑的「计算机名」是基于 NetBIOS 协议,如果不是 Windows 在此处持续给 NetBIOS 协议续命,后者早就退出了历史舞台。

如何使用 Avahi?

用法:只需要在 SSH、Ping 之类的命令中把 Linux 虚拟机的 IP 更换成 主机名.local 的组合就可以了。
把 IP 更换成  的组合

例如我的 Linux 虚拟机,主机名是 Ubuntu-VM(这个主机名是在安装 Ubuntu)时输入的,本身只是起着一个辨识作用,而 Avahi 硬是把它转换成了一个可以在局域网内使用的主机名 Ubuntu-VM.local。假如我需要用局域网内其他电脑通过 SSH 连接这台 Linux 虚拟机,只需直接输入 ssh kukmoon@ubuntu-vm 即可。是的 Avahi 甚至贴心地做了大小写不敏感的设计(新建和存储时,大小写敏感;输入和检索时,大小写不敏感)。简直了,好贴心,他真的,我哭死。
Avahi 甚至贴心地做了大小写不敏感的设计

如何让 Avahi 仅使用 IPv4?

不过我发现如果开启了 IPv6,那么通过 SSH 连接 Linux 虚拟机的速度很慢。注意:Avahi建立在 DNS 多播基础之上,所以说此处实质是 DNS 解析的速度很慢。所以我做了一些设置,让 Avahi 仅仅使用 IPv4。

Step 1. 修改 /etc/nsswitch.conf 文件(乍一看还以为是任天堂 Switch),找到以 hosts 开头的一行,把这一行整个改为:

1
hosts: mymachines mdns4_minimal [NOTFOUND=return] resolve [!UNAVAIL=return] files myhostname dns

其中,mdns4_minimal 只解析 IPv4 地址而且速度最快,[NOTFOUND=return] 表示找不到主机名对应的 IPv4 地址就返回。

Step 2. 在防火墙中启用 Avahi 的端口(5353),以及 SSH 的端口(22)。

1
2
sudo ufw allow 5353
sudo ufw allow 22

Step 3. 配置 SSH 服务。否则,即使你用 SSH 连上了 Linux 虚拟机的 22 端口,Avahi 本身仍然像一座防火墙一样拦着你。

1
sudo cp /usr/share/doc/avahi/ssh.service /etc/avahi/services/

如果 /usr/share/doc/avahi/ssh.service 文件不存在,可以直接上 GitHub 仓库 里去找。

Step 4. 让 Avahi 仅使用 IPv4,忽略 IPv6。首先,打开 /etc/avahi/avahi-daemon.conf;其次,把 use-ipv6=yes 改成 use-ipv6=no;第三,把 #publish-aaaa-on-ipv4=yes 改成 publish-aaaa-on-ipv4=no(yes 改 no,别忘了去掉前面的 # 号)。

Step 5. 重启 Avahi-daemon 服务。

1
2
sudo systemctl stop avahi-daemon.service
sudo systemctl start avahi-daemon.service

搞定

无法通过 Avahi 生成的主机名连接 Linux 电脑怎么办?

一般来说,需要把本机的 DNS 设为「自动」,或者局域网内部的 DNS 服务器(家庭一般是路由器的 IP 地址,工作场所一般是默认网关 (Default Gateway) 的 IP 地址)。

局域网内部的 DNS 服务器


Avahi 的官方资料挺全的,不会就查。

图片版权

题图:Avahi 软件的 LOGO,来自维基百科。

头图:Image by Micha Sager from Pixabay


求扫码打赏
“我这么可爱,请给我钱 o(*^ω^*)o”

用主机名代替 IP 地址连接 Hyper-V Ubuntu 虚拟机
https://blog.kukmoon.com/671ff28715e0/
作者
Kukmoon谷月
发布于
2024年6月16日
许可协议