虚拟机必须用 NAT,如何把 Linux IP 固定住?重启不变、DHCP 不乱改、外部访问入口也稳定
副标题
在 NAT 网络模式不能改桥接 的前提下,正确实现 虚拟机 Linux 固定 IP、宿主机固定入口、端口映射稳定访问 的完整方案
适用场景:
- VMware / VirtualBox / KVM 等虚拟机中的 Linux
- 家庭网络环境
- Ubuntu / Debian / CentOS / Rocky / AlmaLinux
- 虚拟机 必须使用 NAT,不能桥接
- 希望 重启后 IP 不变
- 希望 不跟随 DHCP 自动变化
- 希望 访问入口长期稳定
导语
很多人一提"固定 IP",第一反应就是:
- 把虚拟机 Linux 改成静态 IP
- 然后希望它 永远不变
- 重启不变
- 不跟随路由 DHCP 修改
- 最好外部访问的地址也不变
但如果你的虚拟机 必须使用 NAT 模式,事情就不能按"桥接主机"的思路去做。
因为 NAT 模式下,虚拟机并不是你家庭局域网里的独立一台机器,而是:
- 虚拟机在一个虚拟 NAT 私网里
- 宿主机充当中间层
- 外界访问通常先到宿主机,再转发到虚拟机
所以,NAT 模式下真正要固定的,不是一个 IP,而是 三层入口关系。
摘要
本文讲清 4 个关键问题:
- NAT 模式下,到底该固定哪个 IP
- 如何让虚拟机 Linux 自己的 IP 重启后不变
- 如何让外部访问入口稳定,而不是每次都改地址
- 为什么"虚拟机固定 IP"并不等于"公网 IP 永远不变"
如果你现在的前提是:
虚拟机网络必须 NAT,不能桥接
那本文这套方案就是更正确的做法。
一、先说结论:NAT 模式下,想"稳定不变",必须固定 3 层
结论先给出
在 NAT 模式 下,要想达到"地址长期稳定、重启不变、外部访问尽量不改"的效果,正确做法不是只改 Linux 里的一个 IP,而是同时固定下面三层:
第 1 层:固定 虚拟机内部 IP
例如:
192.168.56.10
10.0.2.15
172.16.100.20
这取决于你的虚拟化 NAT 网段。
第 2 层:固定 宿主机在家庭局域网中的 IP
例如:
192.168.1.20
因为外部设备通常不是直接访问虚拟机,而是:
- 先访问宿主机
- 再由宿主机或虚拟化 NAT 规则转发到虚拟机
第 3 层:固定 外部访问入口
这一层不是"让公网 IP 一定固定",而是让外部访问方式稳定,例如:
- 家庭局域网内通过
宿主机IP:端口访问 - 外网通过
域名:端口访问 - 或者通过 DDNS / 反向代理 / 隧道保持入口稳定
二、NAT 模式下,为什么"虚拟机固定 IP"不等于"外部访问稳定"?
这是最常见的误区。
很多人把虚拟机 Linux 设置成静态 IP,比如:
192.168.56.10
然后以为后面就万事大吉了。
其实不是。
NAT 模式下的真实链路通常是这样的:
外部访问方
↓
家庭路由 / 公网入口
↓
宿主机 LAN IP(例如 192.168.1.20)
↓
NAT 端口映射
↓
虚拟机 Linux 私网 IP(例如 192.168.56.10:8080)
也就是说:
你固定了虚拟机 IP,只是固定了最末端那一跳
但如果下面这些东西变了,你的访问入口仍然会变:
- 宿主机局域网 IP 变了
- NAT 端口映射规则变了
- 路由器端口转发目标变了
- 家里的公网 IP 变了
所以,NAT 模式不是不能固定,而是要固定整条链路。
三、NAT 模式下,真正应该怎么设计?
正确架构
建议直接采用下面这个模型:
yaml
[虚拟机 Linux]
固定私网 IP:192.168.56.10
固定服务端口:22 / 8080 / 3306 ...
↑ 由虚拟化 NAT 转发
[宿主机]
固定局域网 IP:192.168.1.20
固定暴露端口:2222 -> 22
8080 -> 8080
13306 -> 3306
↑ 由家庭路由转发(可选)
[家庭路由]
固定把外部端口转发到宿主机 192.168.1.20
↑ 如果还要公网访问
[公网域名 / DDNS / 静态公网 IP]
把入口固定成域名或固定公网地址
四、你真正能"保证不变"的,分别是什么?
1. 能由你自己控制并长期不变的
这些通常是你自己能稳定控制的:
- 虚拟机 Linux 的 静态私网 IP
- 宿主机在家庭网络里的 固定内网 IP
- NAT 端口映射规则
- 路由器到宿主机的端口转发规则
- 域名访问入口
2. 不能只靠你本地配置就保证永远不变的
这些你本地一般无法单方面保证:
- 家里宽带的 公网 IP 永远不变
- 运营商分配策略永远不变
- 断电重拨后公网 IP 绝对不变化
所以要记住一句话
虚拟机 Linux 配静态 IP,只能固定虚拟机自己的私网地址。
公网出口 IP 是否固定,不由虚拟机决定。
五、NAT 模式下的最佳实践
最推荐的组合方案
如果你要求:
- 虚拟机必须 NAT
- Linux 地址固定
- 重启后不变
- 局域网内访问稳定
- 外网访问尽量稳定
那建议采用这套组合:
方案组合
1)虚拟机内部:Linux 配静态 IP
避免跟随 NAT DHCP 漂移。
2)宿主机:在家庭路由器中固定 LAN IP
例如把宿主机固定成:
192.168.1.20
3)虚拟化平台:配置 NAT 端口转发
例如:
宿主机 2222 -> 虚拟机 22宿主机 8080 -> 虚拟机 8080
4)如果需要公网访问:家庭路由器转发到宿主机
例如:
公网 2222 -> 宿主机 192.168.1.20:2222
5)如果公网 IP 不稳定:用 DDNS 或域名
这样虽然公网 IP 可能变,但 访问入口不变。
六、实操:先固定虚拟机 Linux 自己的 IP
这一步解决的是:
虚拟机 Linux 在 NAT 私网里自己的地址固定,不跟随 DHCP 自动变化。
1)Ubuntu / Debian:Netplan 固定静态 IP
先查看网卡名:
css
ip a
假设虚拟机网卡名为:
ens33
假设你的 NAT 网段是:
192.168.56.0/24
你准备把虚拟机 Linux 固定为:
192.168.56.10
网关设为 NAT 网关:
192.168.56.1
编辑文件:
arduino
sudo nano /etc/netplan/99-static-ip.yaml
写入:
yaml
network:
version: 2
renderer: networkd
ethernets:
ens33:
dhcp4: false
addresses:
- 192.168.56.10/24
routes:
- to: default
via: 192.168.56.1
nameservers:
addresses:
- 192.168.56.1
- 1.1.1.1
- 8.8.8.8
应用配置:
sudo netplan apply
验证:
css
ip a
ip route
2)CentOS / Rocky / AlmaLinux:nmcli 固定静态 IP
先看网卡名:
css
ip a
nmcli device status
假设网卡名为:
ens33
配置静态 IP:
rust
nmcli con add type ethernet con-name static-ens33 ifname ens33 ip4 192.168.56.10/24 gw4 192.168.56.1
nmcli con mod static-ens33 ipv4.dns "192.168.56.1 1.1.1.1 8.8.8.8"
nmcli con mod static-ens33 ipv4.method manual
nmcli con up static-ens33
验证:
css
ip a
ip route
nmcli con show
3)CentOS 7 传统 ifcfg 配置方式
编辑:
bash
sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33
写入:
ini
TYPE=Ethernet
BOOTPROTO=none
NAME=ens33
DEVICE=ens33
ONBOOT=yes
IPADDR=192.168.56.10
PREFIX=24
GATEWAY=192.168.56.1
DNS1=192.168.56.1
DNS2=1.1.1.1
DNS3=8.8.8.8
重启网络:
systemctl restart network
验证:
css
ip a
ip route
七、NAT 模式下,Linux 静态 IP 配置时必须注意的 4 件事
1. IP 必须属于 NAT 网段
不能随便写成家庭路由网段里的地址,例如:
- 宿主机 LAN 是
192.168.1.x - 虚拟机 NAT 网段却可能是
192.168.56.x或10.0.2.x
虚拟机的静态 IP 必须属于虚拟 NAT 网络,不是宿主机 LAN 网段
2. 网关要写 NAT 网关,不是家庭路由器地址
这是很多人最容易写错的地方。
例如:
- 家庭路由器是
192.168.1.1 - 但虚拟机 NAT 网关其实可能是
192.168.56.1
NAT 虚拟机的默认网关,通常应该指向 NAT 网关,而不是家庭路由器
3. 不要和 NAT DHCP 地址池冲突
如果 NAT 网络里还有 DHCP 服务器,而你手工静态指定的地址又刚好在 DHCP 池中,可能会造成冲突。
最好:
- 要么在 NAT 管理里做保留地址
- 要么在 Linux 里手工指定一个 不在 DHCP 自动分配范围内 的地址
4. 临时 ip addr add 不是持久化配置
下面这种命令只适合临时测试:
csharp
ip addr add 192.168.56.10/24 dev ens33
ip route add default via 192.168.56.1
它的特点是:
- 当前立即生效
- 但系统重启后通常会丢
你要的是"重启后也不变",所以必须写入持久化配置文件或连接配置
八、只固定虚拟机 IP 还不够,还要固定宿主机入口
这是 NAT 模式下必须补上的第二步。
为什么必须固定宿主机?
因为大多数外部访问其实打到的是 宿主机,不是虚拟机本身。
例如:
- 你局域网里的手机访问
192.168.1.20:8080 - 实际上是访问到宿主机
- 然后宿主机再通过 NAT 或端口映射转到虚拟机
192.168.56.10:8080
所以如果宿主机今天是:
192.168.1.20
明天变成:
192.168.1.35
那你的访问入口一样会失效。
九、如何固定宿主机在家庭网络中的 IP?
推荐做法:在路由器中给宿主机做地址保留
也就是:
- 找到宿主机网卡 MAC 地址
- 在家庭路由器 DHCP 静态绑定中把它固定到一个内网地址
例如固定成:
192.168.1.20
这样宿主机:
- 重启不变
- 不跟随路由 DHCP 漂移
- 家里其他设备访问入口稳定
十、NAT 模式下,外部设备怎么访问虚拟机?
这一步靠的是 端口映射,不是直接访问虚拟机 NAT 私网 IP。
访问方式示例
假设虚拟机 Linux 地址固定为:
192.168.56.10
虚拟机里跑了这些服务:
- SSH:
22 - Web:
8080 - MySQL:
3306
你可以在宿主机 / 虚拟化 NAT 中映射为:
宿主机 2222 -> 虚拟机 22宿主机 8080 -> 虚拟机 8080宿主机 13306 -> 虚拟机 3306
这样外部访问时:
局域网内访问
css
ssh -p 2222 user@192.168.1.20
http://192.168.1.20:8080
mysql -h 192.168.1.20 -P 13306
注意:
这里访问的是宿主机固定内网 IP,不是虚拟机 NAT 私网 IP
十一、如果还要让公网访问稳定,该怎么做?
这里必须讲清楚。
你能稳定的是"入口",不一定是"公网 IP 本身"
如果你家宽带公网 IP 会变化,最现实的做法不是死磕"公网 IP 永远不变",而是固定下面这些东西:
方案一:域名 + DDNS
让域名永远指向当前公网 IP。
公网 IP 变了,域名自动更新。
这样外部访问方式始终是:
makefile
your-domain.com:8080
而不是记公网 IP。
方案二:静态公网 IP
如果运营商支持,可以申请固定公网 IP。
这是公网层面最彻底的固定方式。
方案三:云服务器 / 反向代理 / 隧道
如果你不方便暴露家庭公网,可以:
- 云服务器做固定入口
- 家里宿主机主动连出去
- 外部统一访问云入口
- 再由云端转发
这样就不依赖你家公网 IP 是否变化。
十二、给出一套可以直接照抄的最终方案
场景前提
- 虚拟机必须 NAT
- 虚拟机里装的是 Linux
- 希望虚拟机地址固定
- 希望局域网内访问方式稳定
- 希望公网访问入口尽量稳定
最终推荐方案
第一步:固定虚拟机 Linux 静态 IP
例如:
192.168.56.10
第二步:固定宿主机内网 IP
例如在路由器里把宿主机固定为:
192.168.1.20
第三步:配置端口映射
例如:
yaml
宿主机 2222 -> 虚拟机 22
宿主机 8080 -> 虚拟机 8080
宿主机 13306 -> 虚拟机 3306
第四步:局域网统一通过宿主机访问
例如:
css
ssh -p 2222 user@192.168.1.20
http://192.168.1.20:8080
第五步:如果要公网访问,再在路由器上转发到宿主机
例如:
rust
公网 2222 -> 宿主机 192.168.1.20:2222
公网 8080 -> 宿主机 192.168.1.20:8080
第六步:如果公网 IP 会变,再加 DDNS 或域名
最终访问入口就能稳定成:
arduino
https://your-domain.com
或者:
css
ssh -p 2222 user@your-domain.com
十三、最容易踩的坑
坑 1:把 NAT 虚拟机配成家庭 LAN 网段地址
例如 NAT 虚拟机却写成:
192.168.1.88
如果 NAT 网段不是这个,就很可能直接出问题。
坑 2:默认网关写成家庭路由器
NAT 虚拟机默认网关通常应该是 NAT 网关,不是宿主机 LAN 网关,更不是随便写。
坑 3:只固定了虚拟机 IP,没固定宿主机 IP
这种情况下,局域网入口照样不稳定。
坑 4:只固定了内网,误以为公网 IP 也会固定
不会。
公网 IP 是否变化,取决于你的运营商链路。
坑 5:只改临时命令,没改持久化配置
测试时能通,重启就失效。
十四、最终总结
如果你的 虚拟机必须 NAT,那"固定 IP"的正确理解应该是:
不是只固定一个地址,而是固定整条访问链路
也就是:
1. 固定虚拟机 Linux 的 NAT 私网 IP
2. 固定宿主机在家庭网络里的 LAN IP
3. 固定 NAT 映射规则
4. 如需公网访问,再固定域名入口或申请静态公网 IP
一句话记住
NAT 模式下,虚拟机 Linux 能固定的是"自己的私网 IP";
外部稳定访问靠的是"宿主机固定入口 + 端口映射 + 域名/DDNS"。
适合掘金的封面摘要
虚拟机网络必须使用 NAT 时,很多人会误以为只要给 Linux 配静态 IP,就能做到地址永远不变、外部访问也稳定。实际上,NAT 模式下真正要固定的是整条访问链路:虚拟机私网 IP、宿主机内网 IP、端口映射规则,以及公网域名入口。本文从 Ubuntu、CentOS 静态 IP 配置,到 NAT 下的宿主机入口固定、端口转发、DDNS 方案,一次讲透。
关键词
NAT虚拟机固定IP Linux静态IP Ubuntu固定IP CentOS固定IP 宿主机端口映射 家庭路由固定IP DDNS 虚拟机NAT访问
结尾 CTA
如果你正在做的是:
- 家庭实验室
- Linux 开发环境
- Docker / MySQL / Redis / Nginx 服务
- NAS / 远程 SSH / 面板访问
- 虚拟机必须 NAT 的办公环境
那这套方案比"强行改桥接"更稳,也更符合实际限制。