0.前言
大多数人应该不会遇到我这样的问题,就是VMware虚拟机卸载过之后重装,死活装不上虚拟网络适配器,导致没法启用桥接模式,结果就是虚拟机可以正常上网也可以ping通主机,但主机死活ping不通虚拟机,xshell也一直连接不上。微信和虚拟机之间传文件还得靠网页版的微信传输助手,那叫一个难受。。。
本文介绍一下在NAT模式下主机连接虚拟机的方式,以Centos7为例。
1.NAT模式vs.桥接模式
桥接模式和NAT模式是在计算机网络中用于连接设备的两种不同方式。
桥接模式指的是将不同的网络连接起来形成一个单一的网络。这种连接方式通过将数据包从一个物理网络传递到另一个物理网络来实现,通常使用网络交换机或路由器作为中介设备。在桥接模式下,所有连接到同一网络的设备都可以直接相互通信,就好像它们连接在同一个物理网络上一样。
而NAT(Network Address Translation)模式则是将一个私有网络连接到公共网络(如Internet)的一种方式。在NAT模式下,通过使用路由器或防火墙等设备,将私有网络中的IP地址转换成公共网络中的IP地址,以便与外部网络进行通信。这种方式使得私有网络内的设备可以更安全地访问公共网络,并且只需要使用较少的IP地址。
因此,桥接模式和NAT模式的主要区别在于它们连接设备的不同方式。桥接模式将多个网络连接起来,使它们看起来像是一个单一的网络,而NAT模式则是将一个私有网络连接到公共网络,并将其IP地址转换为公共网络中的IP地址。
如果在虚拟机中使用的是“NAT”或“仅主机”网络配置,则可能无法通过ping命令从主机上ping通虚拟机。
原因是,当使用“NAT”或“仅主机”网络时,虚拟机位于宿主机的私有网络中,并且由虚拟化软件(如VMware或VirtualBox)充当代理来转发网络流量。因此,要从主机上ping通虚拟机,需要进行额外的配置。
对于VMware Workstation和VirtualBox等虚拟化软件,可以将虚拟机的网络适配器类型更改为“桥接”,这将使虚拟机直接连接到宿主机所在的物理网络中。然后,虚拟机将被视为独立设备,可以从主机上ping通虚拟机。
如果无法更改虚拟机的网络适配器类型,请考虑创建端口转发规则来将主机上的特定端口转发到虚拟机的某个端口上。例如,如果想从主机上ping通虚拟机,则可以在虚拟机中启用SSH服务,并将主机端口映射到虚拟机的SSH端口上。然后,可以使用ssh命令从主机上连接到虚拟机并执行ping测试。
2.NAT模式下主机连接虚拟机
在NAT模式下,虚拟机的网络默认被隔离在一个私有子网中,并无法直接从主机访问。要连接到该虚拟机,只能通过ssh协议连接,虚拟机中需要安装并启用ssh server,并需要进行端口转发或设置端口映射。
2.1启用ssh服务
以下是在CentOS系统上启用SSH服务的步骤:
- 打开虚拟机并登录到其中。根据使用的操作系统不同,可能需要以管理员权限运行命令。
- 检查OpenSSH服务器软件包是否已安装。默认情况下,CentOS应该已经安装了OpenSSH服务器。可以输入以下命令来检查其是否已安装:
rpm -qa | grep openssh-server
如果未安装,则可以使用以下命令安装:
sudo yum install openssh-server
- 启动SSH服务。在CentOS中,使用以下命令启动SSH服务器:
sudo systemctl start sshd
- 使用以下命令查看ssh服务是否启用,如果显示
active (running)
,表示ssh服务已经启用:
sudo systemctl status sshd
sshd.service - OpenSSH server daemon Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled) Active: active (running) since Thu 2023-03-30 23:01:11 EDT; 1min 46s ago Docs: man:sshd(8) man:sshd_config(5) Main PID: 1091 (sshd) Tasks: 1 CGroup: /system.slice/sshd.service └─1091 /usr/sbin/sshd -D
- 确保SSH服务已设置为在启动时自动启动:
sudo systemctl enable sshd
- 确保防火墙允许SSH流量通过。如果的虚拟机上启用了防火墙,则需要确保已允许SSH流量通过。例如,在CentOS 7中,可以使用以下命令打开SSH端口(默认为22):
sudo firewall-cmd --zone=public --add-port=22/tcp --permanent
然后重新加载防火墙规则:
sudo firewall-cmd --reload
- 现在已经成功启用了SSH服务。桥接模式下,从主机上,可以使用SSH客户端连接到虚拟机并执行ping测试等操作。可以使用以下命令连接到虚拟机:
ssh username@vm-ip-address
其中“username”是虚拟机中的用户名,“vm-ip-address”是虚拟机分配的IP地址。
2.2虚拟机的IP地址
可输入ip addr show
或ifconfig
以下命令来查看虚拟机分配的IP地址:
ifconfig
ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:ea:62:03 brd ff:ff:ff:ff:ff:ff inet 192.168.195.128/24 brd 192.168.195.255 scope global noprefixroute dynamic ens33 valid_lft 1455sec preferred_lft 1455sec inet6 fe80::80d1:5471:8afb:fff3/64 scope link noprefixroute valid_lft forever preferred_lft forever virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000 link/ether 52:54:00:2e:36:8b brd ff:ff:ff:ff:ff:ff inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0 valid_lft forever preferred_lft forever
在该虚拟机中,有两个网络接口:
- ens33 - 这是一个物理网络接口,它连接到您所连接的物理网络。inet 192.168.195.128/24 是该接口分配的IP地址,也是您可以在宿主机或其他计算机上ping通的IP地址。因此,在这种情况下,vm-ip-address就是192.168.195.128。
- virbr0 - 这是一个虚拟网络接口,它用于虚拟化软件(如KVM、libvirt等)创建的虚拟机之间通信。inet 192.168.122.1/24 是该接口分配的IP地址,但不会直接从宿主机或其他计算机上ping通,因为它们不在同一物理网络中。
2.3端口转发
在NAT模式下,虚拟机的网络默认被隔离在一个私有子网中,并无法直接从主机访问。要连接到该虚拟机,需要进行端口转发或设置端口映射:
- 端口转发
在虚拟机配置中启用端口转发功能,将虚拟机的SSH端口(默认是22)映射到主机的某个端口上(如2222)。这样,在主机上使用ssh客户端时,将目标IP地址设置为虚拟机所在的IP地址,端口号设置为映射的主机端口即可。例如:
ssh username@192.168.0.10 -p 2222
- 设置端口映射
如果使用的是VMware Workstation等虚拟化软件,可以在虚拟网络编辑器中创建并设置虚拟网络适配器。将虚拟机桥接到该适配器上,并设置虚拟网络适配器的IP地址为与主机相同的网段。这样,主机和虚拟机就处于同一局域网中,可以直接通过SSH连接到虚拟机。
我的虚拟机由于虚拟网络适配器的缺失,无法使用桥接模式。NAT模式下进行端口转发时,需要在虚拟机所在的宿主机上进行配置。具体操作步骤如下:
- 在虚拟机所在的宿主机上启动虚拟化软件(如VMware Workstation等),并打开该虚拟机的设置界面。
- 找到“网络适配器”选项,并选择“NAT设置”。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avEkekGB-1680272720991)(assets/image-20230331204250478.png)]
- 找到“端口转发”设置,添加一个规则,将虚拟机的SSH端口(默认为22)映射到宿主机的某个端口(如2222)上。完成设置后保存并关闭虚拟机设置窗口。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vldgwK8E-1680272720991)(assets/image-20230331204525459.png)]
完成以上设置后,就可以从宿主机连接到该虚拟机了,命令如下:
ssh username@127.0.0.1 -p 2222
其中,username为虚拟机中的用户名,IP地址为本地回环地址127.0.0.1,端口号为映射的宿主机端口2222。
如果之前一切顺利,到这一步就可以在NAT模式下,使用xshell成功连接到虚拟机了。
3.ssh隧道
SSH隧道是一种通过SSH连接在两个网络之间创建加密通道的方法,可以用来跨越不信任的公共网络进行数据传输。它通常被用来加密非安全协议(如Telnet、FTP、VNC等)的连接,并提供更高级别的安全性。
SSH隧道有三种类型:
- 本地端口转发(Local port forwarding)
本地端口转发可以将一台机器的某个端口绑定到另外一台机器的指定端口上。这种方式常用于将远程服务器上需要登录才能访问的服务通过SSH隧道映射到本机。命令格式如下:
ssh -L [local_port]:[remote_host]:[remote_port] [user]@[ssh_server]
其中,local_port是本地要监听的端口,remote_host是远程主机名或IP地址,remote_port是远程主机要映射的端口号。例如,将远程MySQL数据库通过SSH映射到本地3306端口:
ssh -L 3306:localhost:3306 user@remote_server
- 远程端口转发(Remote port forwarding)
远程端口转发可以将一台机器上某个端口绑定到另外一台机器上指定端口。这种方式常用于内网穿透和代理服务器。命令格式如下:
ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server]
其中,remote_port是远程主机要监听的端口,local_host是本地主机的IP地址或主机名,local_port是本地要映射的端口。例如,将本地Web服务器通过SSH隧道映射到远程服务器的8080端口:
ssh -R 8080:localhost:80 user@remote_server
- 动态端口转发(Dynamic port forwarding)
动态端口转发可以将一台机器上任意一个端口绑定到另外一台机器上,通常用于代理服务器和内网穿透。这种方式与HTTP代理非常相似,但比HTTP代理更安全,并且可以访问被防火墙屏蔽的网站。命令格式如下:
ssh -D [local_port] [user]@[ssh_server]
其中,local_port是本地要监听的端口号。例如:
ssh -D 1080 user@remote_server
这条命令会启动一个socks5代理服务器,可以在浏览器及其他应用中使用该代理来访问Web资源。
4.碎碎念
在找到这个解决办法之前,我一直靠着网页版的微信传输助手,来回切换于主机和虚拟机之间,硬生生搭出了一个fabric原型系统,那种来回传输文件调试代码的痛苦我再不想经历第二次(哭死)。那么,大致总结一下使用虚拟机过程中的一些血泪教训吧。
- 虚拟机选定一个版本之后尽量不要反复卸载和重装,微软自带的wsl2子系统也不要跟虚拟机混用(好像也没法混用),反例在这摆着呢。
- 虚拟机连接主机默认都是桥接模式,毕竟桥接模式更加一劳永逸,如果桥接模式连接不上,排查一下虚拟网络适配器是否正常工作。一般情况下,虚拟网络适配器都可以通过卸载虚拟机、删除注册表等方式重新安装。
- 像我一样实在安装不上的,可以试试NAT模式,这种模式不需要虚拟网络适配器。另外NAT模式下的虚拟机有独立的ip地址,相对桥接模式也更加安全。