10. N305 AIO 主机

这是今天的主角,一台配备 5+2 盘位的 N305 AIO 主机。
过去的一段时间里,我使用 T68M 外挂移动硬盘作为家里的 NAS 存储使用,但 ARM 只能满足路由器需求,磁盘 IO 性能一塌糊涂。
于是在去年的 10 月 24 号,我预定了 TANK 电玩定制 NAS 主机,结果这个机子持续跳票,直到现在仍旧处于预售状态,好在店家没有跑路,在上个月有惊无险地完成了退款~真担心会变成另一个 Mou。
纠结一段时间后,放弃了品牌机,也放弃了自己组建,最终选定 南塘黑群晖菌 的定制 NAS,这里记录下过去这段时间折腾的东西。

- CPU:i3-N305
- 内存:16G DDR5 4800MHz
- 主板:定制主板
- PCIe 3.0 x 4 M.2 x 1,安装 ASM1166 M.2 转 SATA
- PCIe 3.0 x 1 M.2 x 1,安装 Intel 760p 512GB NVME
- SATA 3.0 x 2
- Intel I226-V 2.5G x 2
- USB 2.0 x 2
- USB 3.1 x 2
- 机箱:铝合金外框
- 散热:CPU 被动散热 + 1 个 PWM 硬盘散热风扇
- 电源:航嘉 HKA150120A0-7C 直流电源
起初我是想要一台纯粹的 NAS,选定的是 N100 处理器与 8G 内存,但从网上的评测结果看,N100 只能支撑轻度使用场景。
另外我也不放心在物理机上直接部署 NAS 系统,对于不熟悉的系统,在断断续续的折腾下,很有可能一波带走全部数据,还是使用熟悉的 Proxmox VE 相对安全。
物理机系统还是熟悉的 PVE,版本使用最新的 8.3.4,这里对系统一些调整。
flowchart LR
A[光猫]
subgraph AIO主机
subgraph iStoreOS
eth0[eth0 DHCP]
eth1[eth1 192.168.123.1/24]
eth1 --> |SNAT|eth0
end
V1[KVM 虚拟机]
V2[LXC 容器]
br_wan[br_wan<br>外网网口<br>192.168.1.2/24]
br_lan[br_lan<br>内网网口<br>192.168.123.153/24]
end
C[无线路由器]
D[其余设备]
br_wan --> |有线连接|A
C --> |有线连接|br_lan
eth0 --> |桥接|br_wan
br_lan --> |桥接|eth1
V1 --> |桥接|br_lan
V2 --> |桥接|br_lan
D -.-> |无线连接|C
这里创建了两个网桥对应外网和内网:
- br_wan 连接光猫,让桥接网卡也可以获取到公网 IPv6 地址,同时配置了一个光猫内网网段的 IPv4 地址,以备不时之需
- br_lan 连接有线中继模式的无线路由器,这样桥接网卡与家中的无线设备都可以接入内网,全部流量都会经过 iStoreOS 处理,br_lan 同样配置一个 iStoreOS 内网网段地址,方便从内网连接 PVE
之前写过一篇笔记:Linux笔记 / Proxmox VE / 5. KVM虚拟机 / 5.2 Intel核显SR-IOV,N305 携带的核显也支持通过 SR-IOV 的方式复用显卡,但由于系统和驱动的更新,现在 Guest 机器必须安装对应驱动才能使用 SR-IOV 拆分出的显卡。
普通 Linux 系统直接编译安装 i915-sriov-dkms 即可,飞牛 NAS 系统需要 皮蛋熊 大佬编译的驱动覆盖才能正常使用显卡硬解:https://blog.kkk.rs/archives/36。
我安装的 fnOS 虚拟机在最近两次的系统更新中,i915 驱动都会失效,更新后需再执行一次强制安装和重启:
wget https://blog.kkk.rs/upload/intel-i915-v2.deb
dpkg -i --force-all intel-i915-v2.deb
reboot
2025-10-25
i915-sriov-dkms 的 2025.07.22 版本正好同时被 PVE 8 的 6.8 版本内核,以及 fnOS(6.12.18 版本内核)应用中心的提供的驱动支持,因此通过 SR-IOV 使用核显的步骤简化如下:
- 宿主机:安装 2025.07.22 版本驱动,配置内核参数与 VF 数量,注意只能使用 i915 驱动,xe 驱动尚不支持显卡拆分
- 虚拟机:分配 VF 并安装驱动
- 普通 Linux 系统:安装 2025.07.22 版本驱动,配置内核参数,更新 grub 与 initramfs,重启系统
- fnOS:应用中心安装 i915-sriov-dkms 驱动,重启系统

iStoreOS 还是熟悉的配方,安装 PassWall、开启 IPv6 SNAT、配置 DNS 解析等,本次又解锁了一些新玩法。
由于 hosts 文件不支持泛域名解析,以往只能将所有域名记录添加到文件中,但我习惯把 iStoreOS 也作为内部应用网关,因此可以配置 网络 -> DHCP/DNS -> 常规 的地址选项,添加一个泛域名解析,将所有匹配 *.internal.wbuntu.com 域名解析到 192.168.123.1,后续只需要在 iStoreOS 上配置 Caddy 的转发规则即可访问对应服务。

之前为了兼顾安全和 IPv6,以及在外面访问家里的服务,只能使用 frp、gost、tailscale 等工具,通过内网穿透、NAT 打洞的办法连接到 iStoreOS。
而现在对于光猫来说,只有 iStoreOS 会获取公网 IPv6 地址~因此可以放心打开光猫的公网 IPv6 的入向访问了,然后在 iStoreOS 上配置防火墙的转发规则。
给 iStoreOS 配置 DDNS 后,在具备 IPv6 网络的环境下,可以通过域名和端口直连家庭内部网络,这里我选择编写了一个脚本,使用 Cloudflare 的 DNS 更新接口定时同步域名的 IPv6 记录:
#!/bin/bash
# 配置信息
ZONE_ID="<ZONE_ID>"
RECORD_ID="<REGION_ID>"
EMAIL="<EMAIL>"
API_KEY="<API_KEY>"
DOMAIN="<DOMAIN>"
LOG_FILE="/tmp/cf-ddns.log"
LAST_IP_FILE="/tmp/cf-ddns-ipv6-address"
# 获取外网 IPv6 地址
CURRENT_IPV6=$(curl -s 6.ipw.cn)
if [ $? -ne 0 ] || [ -z "$CURRENT_IPV6" ]; then
echo "$(date): 错误: 无法获取IPv6地址" >> $LOG_FILE
exit 1
fi
# 检查缓存的 IP 地址
if [ -f "$LAST_IP_FILE" ]; then
LAST_IPV6=$(cat "$LAST_IP_FILE")
# 如果 IP 地址没有变化,直接退出
if [ "$CURRENT_IPV6" = "$LAST_IPV6" ]; then
# 可以选择不记录日志,避免日志文件过大
# echo "$(date): IPv6 地址未变化,跳过更新" >> $LOG_FILE
exit 0
fi
fi
echo "$(date): 检测到 IPv6 地址变化: $CURRENT_IPV6" >> $LOG_FILE
# 构建请求 JSON
REQUEST_DATA=$(cat <<EOF
{
"comment": "DDNS Record - Updated $(date)",
"content": "$CURRENT_IPV6",
"name": "$DOMAIN",
"proxied": false,
"ttl": 60,
"type": "AAAA"
}
EOF
)
# 发送请求并保存响应
RESPONSE=$(curl -s https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID \
-X PUT \
-H 'Content-Type: application/json' \
-H "X-Auth-Email: $EMAIL" \
-H "X-Auth-Key: $API_KEY" \
-d "$REQUEST_DATA")
# 检查响应中的 success 字段
SUCCESS=$(echo "$RESPONSE" | grep -o '"success":true')
if [ -n "$SUCCESS" ]; then
echo "$(date): DNS 记录更新成功" >> $LOG_FILE
# 将当前 IP 地址保存到缓存文件
echo "$CURRENT_IPV6" > "$LAST_IP_FILE"
# 记录更多详细信息(可选)
CONTENT=$(echo "$RESPONSE" | grep -o '"content":"[^"]*"' | cut -d':' -f2- | tr -d '"')
MODIFIED=$(echo "$RESPONSE" | grep -o '"modified_on":"[^"]*"' | cut -d':' -f2- | tr -d '"')
echo "$(date): 记录内容: $CONTENT" >> $LOG_FILE
echo "$(date): 更新时间: $MODIFIED" >> $LOG_FILE
else
echo "$(date): DNS 记录更新失败" >> $LOG_FILE
echo "$(date): 错误信息: $RESPONSE" >> $LOG_FILE
# 可选:发送失败通知
# 例如:发送邮件通知
exit 1
fi
脚本只能对已有的记录执行更新,我们需要在创建 DNS 解析记录后,打开 F12 再对记录执行一次更新,获取 ZONE_ID、RECORD_ID,API_KEY 可以使用 Global API Key,或新建一个具备 编辑区域 DNS 权限的 API 令牌。
有了 DDNS 后,我们也可以使用 VPN 连接家里的 iStoreOS~目前各大运营商的蜂窝网络都启用了 IPv6,安卓手机上只需要安装 wireguard 应用,通过 VPN 连接到 iStoreOS 后,就可以解锁内网访问和透明代理,不需要再纠结使用哪一种代理协议和代理软件。
首先编辑 网络 -> 防火墙 -> 通信规则,添加一条规则开放 wireguard 服务使用的 UDP 端口,注意源区域选择 wan 与 wan6,目标区域选择 设备(输入):

然后使用 opkg 命令安装 wireguard-tools,它会一起安装 wireguard 内核模块:
opkg update
opkg install wireguard-tools
iStoreOS 虽然内置 luci-app-wireguard,但是操作起来比较困难,没有 Docker 容器的部署简单,下面使用 linuxserver 提供的 wireguard 容器镜像部署服务端:docker-wireguard,它会在隔离的容器网络中创建 wireguard 网卡,对外仅暴露一个 UDP 端口。
我当前使用的启动脚本如下;
#!/bin/bash
docker run -d \
--name=wireguard \
--cap-add=NET_ADMIN \
--cap-add=SYS_MODULE `#optional` \
-e PUID=1000 \
-e PGID=1000 \
-e TZ=Asia/Shanghai \
-e SERVERURL=<IPv6域名> `#optional` \
-e SERVERPORT=<外网端口> `#optional` \
-e PEERS=<设备数量> `#optional` \
-e PEERDNS=auto `#optional` \
-e INTERNAL_SUBNET=<内网地址段> `#optional` \
-e ALLOWEDIPS=0.0.0.0/0 `#optional` \
-e PERSISTENTKEEPALIVE_PEERS=all `#optional` \
-e LOG_CONFS=true `#optional` \
-p <外网端口>:51820/udp \
-v $PWD/config:/config \
-v /lib/modules:/lib/modules `#optional` \
--sysctl="net.ipv4.conf.all.src_valid_mark=1" \
--restart unless-stopped \
lscr.io/linuxserver/wireguard:latest
容器运行正常后,使用 docker logs wireguard 检查日志,可以看到配置文件的二维码,使用 app 扫码同步配置文件即可。

飞牛系统并没有太多需要设置的地方,开箱即用~我把操作系统安装在虚拟磁盘中,这样在使用初期就比较容易创建快照和恢复系统,宿主机的主板 SATA 控制器、M.2 转 SATA 控制器、SR-IOV 拆分显卡及 USB 设备都直通给了虚拟机,方便添加外部存储。
飞牛唯一需要折腾的可能只有 影视 应用的 GPU 加速,对于物理机部署的系统,自带的驱动可以正常启用核显加速,但 SR-IOV 拆分出的显卡需要安装驱动,否则只能 CPU 解码,即使四个核心跑满也无法流畅转码。