OPNsense 默认设置非常保守,在千兆以上高带宽网络中往往无法跑满。有国外网友在 Proxmox 上部署 OPNsense 时遇到网络吞吐不达标的问题,经过摸索最终解决。以下是原文翻译与整理。
最近我决定逐步淘汰 Ubiquiti EdgeRouter Infinity,转而尝试 OPNsense。我购置了 E5-2650L v3、64GB 内存和 X520-DA2I 万兆网卡,搭建好 Proxmox 后安装 OPNsense,问题随之而来。我的互联网带宽有 6Gbps,原以为这样的硬件处理 10G 连接毫无压力,但在虚拟机中实测吞吐只有 2-3Gbps,仅达到带宽的一半左右。

即使使用 iperf 在 OPNsense VM 与本地网络机器之间测试,速度依然不达标。为什么只能用到 10G 连接的大约 25%?我花了几天时间翻阅文章和论坛,逐步试错,最终解决了吞吐问题。整理如下,供将来参考。

排除硬件问题
Proxmox 本身完全能处理 10Gbps 的网络负载,X520-DA2I 网卡在过往任何系统中也从未出过问题。为了排除硬件因素,我创建了一个 Debian 11 VM 并连接到相同的虚拟接口,iperf 测试轻松跑到 9.6Gbps。可见硬件不是瓶颈。
FreeBSD 虚拟网络问题
在调研中我沮丧地发现,FreeBSD 在虚拟网卡上一直有性能问题的历史,不仅在 Proxmox 上,VMware 同样如此。部分资料指出 VirtIO 在 FreeBSD 11/12 存在严重驱动缺陷,建议使用 E1000;也有说法认为我使用的 FreeBSD 13 已修复 VirtIO 驱动。我逐一测试了 Proxmox 中所有虚拟网卡类型:VirtIO、E1000、Realtek RTL8139 和 VMware vmxnet3。在没有额外调优的情况下,VirtIO 表现最好(约 2.5Gbps),其他类型甚至达不到 1Gbps。最终我选定 VirtIO,并进行其他调整。
测试中还对比了 Host CPU 与 KVM64 两种模式,KVM64 实际表现略好,所以我保留默认。另外添加了 AES 标志(可提升 VPN 性能)和 NUMA 标志,虽然 NUMA 可能没有明显收益。
硬件卸载问题
普遍共识是不要在防火墙设备上启用硬件 TSO 或 LRO。我逐一尝试每个选项,偶尔能获得少量性能提升(硬件 LRO 提升显著),但某些设置反而大幅拖慢速度。开启硬件 VLAN 过滤后网速极低,甚至无法可靠访问 Web 管理界面。更诡异的是,硬件卸载有时能大幅提升 LAN 端性能,却让 WAN 端性能急剧下降。

鉴于这些奇怪结果,我决定关闭所有硬件卸载。最终,在不启用任何硬件卸载的情况下实现了目标性能。
低效的默认可调参数
在论坛上看到有人遇到类似问题后,我意外发现了备受推崇的 FreeBSD 网络性能调优指南。忽略其中与 ZFS 和 DDoS 缓解相关的内容,重点关注网络提升部分。
调整后,网络性能确实大幅提升,防火墙可以跑到 4-5Gbps。

但仍未达到我的 6Gbps 带宽上限,还需进一步优化。我又查阅了 GitHub 上的讨论、OPNsense 论坛关于接收端缩放的帖子、pfSense 性能调优指南以及 Reddit 上的旧帖,逐步补充参数。
我一次只改一个参数并重启,没有严格记录每个效果,因为读完说明后大多认同“增加这项有好处”。如果你想要更精确地筛选有效参数,可自行逐项测试。下面给出最终帮我解决吞吐问题的配置组合。
正确配置方法
以下配置在我防火墙上实现了超过 6Gbps 的吞吐。
Proxmox 虚拟机硬件设置 – 机器类型
关于机器类型选 q35 还是 i440fx 争议很大,我沿用默认的 i440fx,没有出现明显性能波动。
Proxmox 虚拟机硬件设置 – CPU


- CPU 类型保持“KVM64”(默认),提供了最佳性能。
- 总核心数与物理宿主机匹配,让路由器能使用全部 CPU。
- 勾选“启用 NUMA”(可能不会提高性能)。
- 启用“AES CPU 标志”(可以提升 VPN 性能)。
Proxmox 虚拟机硬件设置 – 网络适配器

- 禁用防火墙选项,Proxmox 本身不做防火墙处理,全由 OPNsense 负责。
- 使用 VirtIO 网络设备类型,实测效果最佳。
- 将 Multiqueue 设置为 8(最大值),为网卡提供额外并行处理能力。
OPNsense 设置
在“接口” -> “设置”中,禁用所有硬件卸载选项。

OPNsense 可调参数
参照 FreeBSD 网络性能调优指南,在“系统 - 设置 - 可调参数”中添加以下调整:
hw.ibrs_disable=1
缓解 Spectre V2 漏洞的 CPU 参数,禁用可大幅提升性能。net.isr.maxthreads=-1
解除 netisr 可用 CPU 数量的限制,设为 -1 可使用全部 24 个线程。net.isr.bindthreads=1
将每个 ISR 线程绑定到固定核心,因为我们为每个核心启动一个线程。net.isr.dispatch=deferred
根据 GitHub 讨论,需要设为deferred或hybrid才能使其他 net.isr 参数生效。net.inet.rss.enabled=1
启用接收方缩放(RSS),改善多核网络的并行处理。net.inet.rss.bits=6
该值应为 CPU 核心数除以 4,我的虚拟机有 24 核,故取 24/4=6。请根据实际核心数调整。kern.ipc.maxsockbuf=614400000
来自调优指南,推荐用于 100Gbps 网卡。默认值仅对应 2Gbps 网络。若不用这么高,10Gbps 可设为 16777216。net.inet.tcp.recvbuf_max=4194304net.inet.tcp.recvspace=65536net.inet.tcp.sendbuf_inc=65536net.inet.tcp.sendbuf_max=4194304net.inet.tcp.sendspace=65536
这些 TCP 缓冲区设置均来自调优指南,全部大于或等于 OPNsense 默认值,有助于提升性能。net.inet.tcp.soreceive_stream=1
启用优化的内核套接字接口,显著降低高速 TCP 流对 CPU 的影响。net.pf.source_nodes_hashsize=1048576
增加 PF 防火墙哈希表大小,防止连接数过多时性能下降。net.inet.tcp.mssdflt=1240net.inet.tcp.abc_l_var=52
提高 IP 分片处理效率,这些值相对安全。net.inet.tcp.minmss=536
配置 IPv4 TCP 段的最小负载大小,提升效率。kern.random.fortuna.minpoolsize=128
并非网络相关,用于改善 RNG 熵池,对 VPN 等加密场景有益。net.isr.defaultqlimit=2048
来自 Reddit 讨论,这一批参数最终将吞吐推上峰值。
结论
通过上述调整,Proxmox 上 KVM 虚拟机中的 OPNsense 终于达到预期性能。这些思路同样适用于 pfSense 等基于 FreeBSD 的防火墙,甚至家中的 FreeNAS 等 FreeBSD 系统。不过在我的测试中,OPNsense 的性能受默认限制特别明显,可能与兼容性策略有关。
本文并非全面指南,只为将来参考而写,希望遇到类似问题的读者能从中找到答案并取得良好效果。
觉得内容不错?我要