这篇文章用来记录一下自己折腾PVE NAT的过程。
提前叠甲,我不是专业运维,我也不是什么计算机系学生,我也不是什么计算机系教授,我是个学一半数学的。所以如果出现了不专业不优雅不合适的错误或者说可优化空间请友善提出。
我必须记录下来的原因就和很多二婚人士一样,我从来没有想过要再从头配置一台PVE,就像他们在第一次结婚的时候大概率没有想到要结第二次。当然,就像很多二婚人士变得更有远见一样,为了防止我和PVE第三次结婚时手足无措,所以提前先能记录多少记多少。
为什么要NAT
我知道其实很多简单的需求确实是用不上组NAT。但是在我自己的使用环境中NAT可以解决很多痛点。
-
在我的家庭环境中,由于我的家人同时也要上网,并且我用的是某米的路由器,所以我希望可以尽量少的更改路由器端的设置,给我的家人创造良好的上网环境。你当然可以说换路由器、让家人即使忍着断网也要接受内网DNS、路由器设备数量过多、旁路由失效等问题,这不在我的讨论范围之内我也不想对此做出回应。
-
不方便固定IP或者固定IP效果不佳 。我是属于后者,我即使在路由器固定了IP偶尔也会失效,导致我的frp穿透出错,重新配置极其麻烦,这个时候一个稳定的IP环境无疑可以减少很多麻烦。
-
虚拟机较多导致路由器后台可以看到一大堆桥接的网卡,这对于家庭环境以及家庭路由器还是比较重要的,最少不用在几十个虚拟网卡里找自己要找的设备了。
-
PVE内DNS
-
单IP出口
要做什么
我自己的总体思路就是,用一个网桥作为内网的“交换机”。
-
新建一个网桥用来连接所有要NAT的虚拟机,之所以新建是因为我原来的网卡给确实有桥接需求的虚拟机留着,并且原来的网卡也许可能和PVE本身的网络挂钩,我怕删了导致PVE上不了网,毕竟都用PVE了直接新建一个Bridge也是很方便。理论上也可以不用新建?总之我这方面确实没有测试也不算精通。
-
给这张网卡配置dhcp服务用来分配IP。
-
配置NAT来进行网络通信
PVE下虚拟机设置
更改桥接网卡
把虚拟机的网络设备里的桥接改成建好的网卡。
在新建完网卡或这设置好dhcp服务器这几个时间段更改最好,因为可以比较直观的看见变化。放在这里不是说现在就改!得先看后面建好网桥再来改,不然都找不到是哪张。放在这里主要是为了留个印象以及方便跳转。
PVE 宿主机设置
新建Bridge
这里可以先填上网卡的地址,一般为建立的网段的首个地址,省的后面操作了。注意不要填写网关,也不要连接到任何物理网卡,桥接端口就让他空着。唯一需要填的就是这个IPV4/CIDR。
不填写网关是因为Bridge里的网关指PVE宿主机本身访问外网的路径,vmbr0已经有了原来存在的网关,让PVE宿主机能上网,如果vmbr1填了可能会出现双默认网关冲突,导致宿主机断网。当然,我自己没有试过填写。
开启网卡转发
在光标位置上一行开启转发 理论上来说,在 /etc/network/interfaces 中通过这一行命令,用以在网卡启动后开启转发。为啥用理论上呢,是因为这次我自己弄的时候忘了用什么方法直接打开了,所以没写这里面。当然无论哪种方法,本质上都是让
cat /proc/sys/net/ipv4/ip_forward 的内容输出为1,只要是1就代表你已经开启转发了。
我找到我在哪里设置了,
我其实采用的方法是网上教程比较常见的 /etc/sysctl.conf 永久开启,但是呢,由于PVE9基于debain13,所以这些配置都倾向于这种原子化的配置方式,/etc/sysctl.conf文件默认已经不存在了,虽然你可以直接新建一个也不影响使用。但是既然都用新版PVE了当然也要与时俱进,找一个有大妈心的萝莉,我不干这种事😋。要开启转发,直接在sysctl.d目录下新建配置文件就可以。我同时开启了v6的转发以备不时之需。
开启DHCP服务
安装isc-dhcp-server
运行
sudo apt install isc-dhcp-server -y 来安装dhcp服务器。在安装过程中可能会出现systemd的错误,这没关系,因为我们对dhcp的配置还没完成,导致systemd的service无法开启。
配置DHCP服务器
指定监听网卡
首先进入 /etc/default/isc-dhcp-server。
在INTERFACESv4这栏填写我们添加的用以连接虚拟机的网卡。INTERFACES的内容决定里你的dhcp在哪里发挥作用。
配置地址池 在 /etc/dhcp/dhcpd.conf
这边比较重要的是
# 1. 全局选项
# 设置客户端的域名后缀
option domain-name "pve.local";
# 设置客户端使用的 DNS 服务器地址(阿里云和电信 DNS)
option domain-name-servers 223.5.5.5, 114.114.114.114;
# 默认租期(秒),600秒即10分钟
default-lease-time 600;
# 最大租期(秒),如果客户端请求更长租期,最多给7200秒(2小时)
max-lease-time 7200;
# 2. 运行模式
# 禁用 DNS 动态更新(大多数局域网环境不需要)
ddns-update-style none;
# 声明此服务器是该网络中的“权威”服务器
# 这样当客户端请求一个错误的 IP 时,服务器会主动发送 DHCPNAK 让客户端重新申请
authoritative;
# 3. 子网定义 (针对你的 vmbr1 网段自行修改,我的是: 10.0.0.1)
subnet 10.0.0.0 netmask 255.255.255.0 { # 定义可分配的 IP 地址范围
range 10.0.0.100 10.0.0.200;
# 定义客户端获取到的网关地址(通常就是你 PVE 自身的 vmbr1 IP)
option routers 10.0.0.1;
# 子网掩码和广播地址
option subnet-mask 255.255.255.0;
option broadcast-address 10.0.0.255;
}
事已至此,虚拟机理论上在这步可以获取到我们设置的网段下的IP了。
ps:万一我记错了也不一定,反正就是在这几步。🫡
配置iptable规则
这步其实有传统的iptables的方法,这个网络上有很多,可以直接搜索得到,常用的有在上面配置转发的interfaces文件里面同样的位置写类似于
post-up iptables -t nat -A POSTROUTING -s '10.0.0.0/24' -o {出口网卡} -j MASQUERADE
post-down iptables -t nat -D POSTROUTING -s '10.0.0.0/24' -o {出口网卡} -j MASQUERADE
这种写法,但是呢我为了挑战自己和自己的精神疾病等等各种原因,想要直接使用nftables来写这个规则。二者的区别网上已经有很多介绍了,我在这不多赘述。这块我自己也不是特别懂,权当参考吧。
在/etc/nftables.conf 文件下
我并没有删除默认的表,而是新加了一个nat_table表。其中counter这个关键字是我后面排查问题的时候加入的。我现在正式使用的版本是
ip saddr 10.0.0.0/24 oifname “vmbr0” masquerade
这个版本指定了输出的网卡,但是你要是像上面那张图一样没指定网卡在我简单测试下来也是可行的。counter也仅仅只是为了我查问题的时候让我能看到有没有包经过这条规则。
当然,开启网络转发和配置iptables的这些操作,都比较适合使用post-up写在interfaces文件里。这样在删除,变更网卡的时候会更加灵活,不容易出错,要怎么写直接问问ai就行,我没改纯是已经改好懒得再改了😝
在完成这些步骤后,我们的虚拟机应该拿到了自己的ip以及可以正常上网了。