年轻人的第一台 nas

发布于 2025-03-03 02:13 3598 字 18 min read

暂无系列文章
All in one, all in boom

缘起

关于为什么要买 nas 这件事,我个人认为只有以下几种原因:

  • 存储不够
  • 重视数据隐私和安全
  • 单纯拿来折腾

很不幸,我全中了。再加上我计划之前攒的一套主机没有点亮,迫使我需要找一个一体化的 nas 解决方案,插上硬盘就可以用的那种。而且我还需要利用到我闲置的 3.5 英寸硬盘,说起这个硬盘,我原本是打算给我的 PS3 由 120g 扩容到 500g 的,但是当时我以为 PS3 用的是 3.5 英寸的硬盘,结果买到手才发现 PS3 用的是 2.5英寸的硬盘,我买的那个根本放不下去,于是就闲置了。这下得利用起来了。

虽然说我有一台骁龙 8gen3 16+512 的一加 Ace3 Pro,而且我还有大大小小的 U 盘和移动硬盘,再加上我还有两个 5tb 的 e5 ,理论上来说我不应该买一个 nas 吧?

但是我的数据太多了以至于分散在各处,而且万一 e5 续订不成功怎么办?以至于我无法统一我现有的所有设备。在这些因素的驱使下我买了一个单盘位的 nas

初探

这是关于我买的这一套 nas 的配置:

  • CPU: Intel(R) Celeron(R) Processor 1037U @ 1.80GHz
  • MEM: 4G DDR3 1333MHz
  • HARDDISK: Seagate Barracuda 7200.14(AF) ST500DM002-1BD142
  • HARDDISK: FASTDISK 32G SSD
  • POWER: 12V 5A DC

总价不带硬盘是 110R.

后来我有看到卖家上了一个双盘位 1037U 的 nas 才贵 10R,我有点后悔买早了,不过早买早享受嘛。

让后就是插好电源,网线,hdmi 线,开机进 PE 查看下情况。

(No Picture)

接下来就是装系统了,我这里试了好几个系统:

  • DSM: 一开始用 RR 编译引导失败,然后用网上的二合一整合包能启动但是卡 booting the kernel 且群晖助手没有扫到 ip 地址,作罢。
  • OMV 7: 装完之后没有 IP 地址,用 Debian 手动安装后在创建存储空间时突然卡死重启后就找不到 IP 了,作罢
  • FnOS: 很顺利啊装完之后就可以直接用了,不过还是遇到了一点小麻烦。

遇到的问题

关于 fnos 自带虚拟机的问题

  • 创建虚拟机时无法识别网卡 需要在设置>网络选项里开启 ovs

  • 打开 ovs 重启后没有 IP 解决方法: 参考该帖子下面的回复,这个问题我在实体机遇到了,但是虚拟机没有。

  • ui 体验对手机不友好 这个目前无解。我一般情况下是下了个手机客户端来解决大部分情况的,少部分需要登 ssh 解决,极少数情况需要登 webui.

而且 fnos 官方虚拟机前端是 novnc, 也不支持调整 vnc 端口,就没有用。

但是我又想体验虚拟机,因为 fnos 是基于 debian 12 深度魔改,理论上我们就可以使用 qemu 来实现虚拟机的要求,虽然可以使用 systemd 来开机自启动,但是我装了三个虚拟机有时候要启动别的所以就没有这样做:

#!/bin/bash

# Enable debug output
set -eu

# Configuration
VM_MEMORY=2048
VM_CPUS=1
ISO_PATH="/vol1/1000/1/debian-12.9.0-amd64-netinst.iso"
DISK_PATH="/vol1/1000/1/vms/debian.qcow2"
VNC_DISPLAY=
VM_NAME="qemu-vm-$(date +%s)"
LOG_FILE="/var/log/qemu-vm.log"

# Logging function
log() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[${timestamp}] $1" | tee -a "${LOG_FILE}"
}

# Check VM status
check_vm_status() {
    if pgrep -f "qemu-system-x86_64.*${DISK_PATH}" >/dev/null; then
        return 0  # VM is running
    else
        return 1  # VM is not running
    fi
}

convert() {
    TEMP_DISK=/tmp/$(openssl rand -base64 8).qcow2
    if ! check_resources; then
        log "系统资源不足,压缩可能会影响系统性能"
        read -p "是否仍然继续?(y/N) " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log "用户取消压缩"
            return 1
        fi
    fi
    log "开始压缩磁盘 ${DISK_PATH},压缩后文件临时存放到 ${TEMP_DISK}"
    sudo qemu-img convert -p -c -O qcow2 ${DISK_PATH} ${TEMP_DISK}
    if [ ! -f ${TEMP_DISK} ]; then
        log "转换失败!"
        rm -rf ${TEMP_DISK}
        return 1
    fi
    if cp ${TEMP_DISK} ${DISK_PATH} ; then
        log "覆盖成功"
        rm -rf ${TEMP_DISK}
        log "已删除临时文件"
    else
        log "覆盖失败!"
        rm -rf ${TEMP_DISK}
        return 1
    fi
}

# Get VM information
get_vm_info() {
    local pid=$(pgrep -f "qemu-system-x86_64.*${DISK_PATH}")
    if [ -n "$pid" ]; then
        echo "VM Status: Running"
        echo "VM PID: $pid"
        echo "VM Runtime: $(ps -o etime= -p $pid)"
        echo "Memory Usage: $(ps -o rss= -p $pid | awk '{printf "%.2f GB\n", $1/1024/1024}')"
        echo "CPU Usage: $(ps -p $pid -o %cpu=)%"
        echo "VNC Display: :${VNC_DISPLAY}"
    else
        echo "VM Status: Stopped"
    fi
}

# Check system resources
check_resources() {
    local total_mem=$(free -g | awk '/^Mem:/{print $2}')
    local free_mem=$(free -g | awk '/^Mem:/{print $4}')
    local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')

    if [ ${free_mem} -lt 2 ]; then
        log "警告: 系统内存不足 (可用: ${free_mem}GB)"
        return 1
    #fi

    if [ $(echo "${cpu_usage} > 90" | bc -l) -eq 1 ]; then
        log "警告: CPU 负载过高 (使用率: ${cpu_usage}%)"
        return 1
    fi

    return 0
}

# Function to start VM
start() {
    if check_vm_status; then
        log "虚拟机已经在运行中"
        get_vm_info
        return 1
    fi

    if ! check_resources; then
        log "系统资源不足,启动可能会影响系统性能"
        read -p "是否仍然继续?(y/N) " -n 1 -r
        echo
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            log "用户取消启动"
            return 1
        fi
    fi

    log "正在刷新系统资源"
    sync
    sh -c "echo 3 > /proc/sys/vm/drop_caches"
    sync
    log "系统资源刷新完成"

    if [ ! -f "${DISK_PATH}" ]; then
        log "错误: 磁盘镜像不存在: ${DISK_PATH}"
        return 1
    fi

    log "正在启动虚拟机..."
    sudo qemu-system-x86_64 \
        -name "${VM_NAME}" \
        -m ${VM_MEMORY} \
        -smp ${VM_CPUS} \
        -netdev user,id=net0 \
        -device virtio-net-pci,netdev=net0 \
        -device virtio-scsi-pci,id=scsi0 \
        -drive file=${DISK_PATH},format=qcow2,if=virtio,id=hd0 \
        -vga qxl \
        -bios /usr/share/qemu/OVMF.fd \
        -vnc :${VNC_DISPLAY} \
        -accel kvm \
        -daemonize -M q35 -cpu max

    sleep 1
    if check_vm_status; then
        log "虚拟机启动成功"
        get_vm_info
    else
        log "虚拟机启动失败"
        return 1
    fi
}

# Function to stop VM
stop() {
    if ! check_vm_status; then
        log "虚拟机未在运行"
        return 1
    fi

    local pid=$(pgrep -f "qemu-system-x86_64.*${DISK_PATH}")
    log "正在停止虚拟机 (PID: ${pid})..."

    # Try to stop vm
    kill -TERM $pid

    # Waiting vm stop
    for i in {1..30}; do
        if ! check_vm_status; then
            log "虚拟机已成功停止"
            return 0
        fi
        echo -n "."
        sleep 1
    done

    # Force close if still running
    log "虚拟机未能正常停止,正在强制关闭..."
    kill -9 $pid 2>/dev/null || true

    if ! check_vm_status; then
        log "虚拟机已被强制停止"
    else
        log "错误: 无法停止虚拟机"
        return 1
    fi
}

# Get vm status
status() {
    log "正在获取虚拟机状态..."
    get_vm_info
}

# Main function
main() {
    # Check if running as root
    if [ "$(id -u)" -ne 0 ]; then
        log "错误: 请使用root权限运行此脚本"
        exit 2
    fi

    # Create log directory if it doesn't exist
    mkdir -p "$(dirname ${LOG_FILE})"

    # Check for arguments
    if [ $# -eq 0 ]; then
        echo "用法: $0 [-s|-e|-v|-h|-i]"
        exit 1
    fi

    # Process arguments
    case "$1" in
        -s)
            start
            ;;
        -e)
            stop
            ;;
        -i)
            status
            ;;
        -v)
            echo "Version: 1.1.0"
            ;;
        -c)
            convert
            ;;
        -h)
            echo "用法: $0 [-s|-e|-v|-h|-i|-c]"
            echo "  -s      启动虚拟机"
            echo "  -e      停止虚拟机"
            echo "  -i      显示虚拟机状态信息"
            echo "  -v      显示版本信息"
            echo "  -h      显示此帮助信息"
            echo "  -c      动态调整虚拟机磁盘大小"
            ;;
        *)
            log "错误: 未知选项 '$1'"
            echo "使用 '$0 -h' 查看帮助信息"
            exit 1
            ;;
    esac
}

# Run main function with all arguments
main "$@"

然后就可以通过 vnc 连接了。

散热

虽然 1037U 只有双核双线程,但是单核心暴打 J1900 和 N3150,多核心基本持平,但是代价就是:

    1. tdp 高达 17w
  • 2.机器自带一个小风扇,开机后比被动散热的 J1900 吵。

这两个我暂时没有解决方法。目前在 bios 里找不到风扇选项

远程访问

如果家里有公网IP可以考虑一下,如果不是公网IP可以考虑frp穿透出去或者注册一个飞牛账号然后使用 fn connwct 进行远程访问。

我试了几个方法:

  • frp 穿透: 目前只穿透了一个 ssh 端口,通过 systemd 进行开机自启动:
[Unit]
Description=Frp Client Service
Wants=network.target
After=systemd-user-sessions.service

[Service]
Type=simple
ExecStart=/etc/frpc/frpc -c /etc/frpc/frpc.ini
KillMode=process

[Install]
WantedBy=multi-user.target

然后在 ssh 里(需要在设置里打开)执行:

$ sudo systemctl daemon-reload
$ sudo systemctl enable frpc.service
$ sudo systemctl start frpc.service

然后就可以通过提供的 ip 和端口进行远程访问了:

$ ssh -p <port> <username>@<address>

frpc 可以穿透多个端口,前提是这些端口都指定一个隧道,多个隧道不同端口我还在研究

  • fn connect 通过手机号注册飞牛账号后就可以在设置里启用了,目前我试过只能访问 webui,ssh 和 vnc 是无法访问的。
  • v6 公网 虽然机器获取的 v6 地址是 2409 开头的,但是流量完全无法访问,可能跟这个有关?我也不太清楚。

无法网盘自动备份

由于是单盘位无法组 raid,所以硬盘坏了就是真的 g 了。

而 fnos 也没有退出类似 dsm 的 cloudsync 那样的。

只能等官方更新咯。

内存虚标

具体表现为 fnos app 和 htop 剩余内存不一样。

我也不知道是不是故意这样设计的,总之我看着觉得比较膈应。

目前还是先把 zram 打开:

$ echo "zram" > /etc/modules-load.d/zram.conf
$ echo 'KERNEL=="zram0", ATTR{comp_algorithm}="zstd", ATTR{disksize}="3G" RUN="/sbin/mkswap /dev/zram0", TAG+="systemd"' > /etc/udev/rules.d/99-zram.rules
$ echo -e "\n/dev/zram0 none swap defaults,pri=200 0 0" >> /etc/fstab

以上命令会将最大3G内存用以内存 zram,如果需要使用更多的内存用以 zram,可以自行修改。 尽量留1G的物理内存剩余空间,避免出现不必要的麻烦。

开启 zram 后,可以将部分内存压缩使用,令小内存能发挥更大的力量。

但这种力量也是有限的。如果占用过高还是发动钞能力,给nas加内存吧。

核显摸鱼

主要表现为播放视频是核显不工作,但是 app 里能看到核显显存占用,/dev/dri 也不为空,我觉得应该需要 ffmpeg 指定 intel 解码器才能工作?

尝试 ffmpeg 指令:

$ ffmpeg -hwaccel qsv -c:v hevc_qsv -i input_file.mkv -c:v h264_qsv -c:a aac output_file.mp4

但是报错:

Device creation failed: -542398533.
[hevc @ 0x55fdc6f62280] No device available for decoder: device type qsv needed for codec hevc.
Stream mapping:
  Stream #0:0 -> #0:0 (hevc (native) -> h264 (libx264))
  Stream #0:1 -> #0:1 (flac (native) -> aac (native))
Device setup failed for decoder on input stream #0:0 : Generic error in an external library

查看视频信息:

user@fnnas:~$ ffprobe /vol1/1000/1/\[UHA-WINGS\&VCB-Studio\]\ Eromanga\ Sensei\ \[01\]\[Ma10p_1080p\]\[x265_flac\].mkv
ffprobe version 5.1.4-0+deb12u1 Copyright (c) 2007-2023 the FFmpeg developers
  built with gcc 12 (Debian 12.2.0-14)
  configuration: --prefix=/usr --extra-version=0+deb12u1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librist --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --disable-sndio --enable-libjxl --enable-pocketsphinx --enable-librsvg --enable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-libplacebo --enable-librav1e --enable-shared
  libavutil      57. 28.100 / 57. 28.100
  libavcodec     59. 37.100 / 59. 37.100
  libavformat    59. 27.100 / 59. 27.100
  libavdevice    59.  7.100 / 59.  7.100
  libavfilter     8. 44.100 /  8. 44.100
  libswscale      6.  7.100 /  6.  7.100
  libswresample   4.  7.100 /  4.  7.100
  libpostproc    56.  6.100 / 56.  6.100
Input #0, matroska,webm, from '/vol1/1000/1/[UHA-WINGS&VCB-Studio] Eromanga Sensei [01][Ma10p_1080p][x265_flac].mkv':
  Metadata:
    encoder         : libebml v1.3.4 + libmatroska v1.4.5
    creation_time   : 2017-07-08T03:34:59.000000Z
  Duration: 00:23:42.09, start: 0.000000, bitrate: 3945 kb/s
  Chapters:
    Chapter #0:0: start 0.000000, end 190.982000
      Metadata:
        title           : Chapter 01
    Chapter #0:1: start 190.982000, end 578.036000
      Metadata:
        title           : Chapter 02
    Chapter #0:2: start 578.036000, end 1305.179000
      Metadata:
        title           : Chapter 03
    Chapter #0:3: start 1305.179000, end 1395.227000
      Metadata:
        title           : Chapter 04
    Chapter #0:4: start 1395.227000, end 1409.992000
      Metadata:
        title           : Chapter 05
    Chapter #0:5: start 1409.992000, end 1422.090000
      Metadata:
        title           : Chapter 06
  Stream #0:0(jpn): Video: hevc (Main 10), yuv420p10le(tv, bt709/unknown/unknown), 1920x1080, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 1k tbn (default)
    Metadata:
      BPS             : 2631829
      BPS-eng         : 2631829
      DURATION        : 00:23:42.088000000
      DURATION-eng    : 00:23:42.088000000
      NUMBER_OF_FRAMES: 34096
      NUMBER_OF_FRAMES-eng: 34096
      NUMBER_OF_BYTES : 467836589
      NUMBER_OF_BYTES-eng: 467836589
      _STATISTICS_WRITING_APP: mkvmerge v13.0.0 ('The Juggler') 64bit
      _STATISTICS_WRITING_APP-eng: mkvmerge v13.0.0 ('The Juggler') 64bit
      _STATISTICS_WRITING_DATE_UTC: 2017-07-08 03:34:59
      _STATISTICS_WRITING_DATE_UTC-eng: 2017-07-08 03:34:59
      _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
  Stream #0:1(jpn): Audio: flac, 48000 Hz, stereo, s32 (24 bit) (default)
    Metadata:
      BPS             : 1311765
      BPS-eng         : 1311765
      DURATION        : 00:23:42.090000000
      DURATION-eng    : 00:23:42.090000000
      NUMBER_OF_FRAMES: 16666
      NUMBER_OF_FRAMES-eng: 16666
      NUMBER_OF_BYTES : 233181058
      NUMBER_OF_BYTES-eng: 233181058
      _STATISTICS_WRITING_APP: mkvmerge v13.0.0 ('The Juggler') 64bit
      _STATISTICS_WRITING_APP-eng: mkvmerge v13.0.0 ('The Juggler') 64bit
      _STATISTICS_WRITING_DATE_UTC: 2017-07-08 03:34:59
      _STATISTICS_WRITING_DATE_UTC-eng: 2017-07-08 03:34:59
      _STATISTICS_TAGS: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES
      _STATISTICS_TAGS-eng: BPS DURATION NUMBER_OF_FRAMES NUMBER_OF_BYTES

查看信息后发现核显不支持 h265解码,他妈的。

DLNA

挂载的本地存储还是工作的,主要说一下 webdav 方面。

因为我懒得下载在上传到盘里,虽然 app 里有一个自动下载的功能但是 nas 的主要用途又不是影视盘,于是找了个挂载上去,通过 dlna 在电视上观看。

但是不知道为什么加载非常慢,而且播放几秒后就强制退出了,我也不知道为什么。

但是在 PS3 上就可以看了,虽然隔几分钟就卡一下,但是总比一播放就闪退要好的多,但是很可惜 PS3 不支持 hevc 视频。

手机上也是可以看的,但是没有办法选择字幕。

后来又挂了一个小雅,但是官方应用商店的小雅是不能用的,只能手动安装,用 GitHub 上的安装脚本安装就可以了。但是有一点需要注意网络模式一定要改成 host 否则无法联网。

折腾了这么久,终于上享受到满屏电影墙的快感了,虽然我本地也没有资源,虽然加载慢,虽然电视播放不了,虽然我不一定能有时间看。

感觉年纪轻轻染上刮削也不是什么好事(笑)

用途

  • docker 挂小雅和青龙面板 现在这台 nas 上面在跑的服务:
  • ftp,smb
  • 装了三个虚拟机,一个 alpine 用来挂 telegram 和 QQ,一个 Windows8 build 8400 骨头版 32 位用来玩 Galgame,一个 WindowsXP 32 位用来玩玩老游戏,例如双星物语,可以勉强 30 帧游玩,虽然有时候会掉到 15 帧以下。 可能会跑的一些服务:
  • qb 下载(有 v6 公网但是防火墙关不了有什么用呢?)
  • 搭一个本地音乐服务器在线听歌也说不定,因为我用的落雪音乐的音乐源经常失效加载不出来。

感觉 fnos 体验还是挺不错的,这台机器目前放在了卧室旁边的储物柜底下,和路由器共用一个插线板,有线网络直连路由器,有点吵(但是 PS3 一打开基本上就可以忽略不计了),但是基本上是可以忍受的(如果是那种对噪音很敏感的建议买一个 J1900 然后挂几个固态组集群(),。后期可能会考虑加购个 UPS,突然断电很伤 HDD(虽然我没有遇到过,而且我这里几乎没有突然停电的历史)。

至于还有其他什么的到时候再说吧。可能到时候升级下硬盘和内存也说不定?毕竟 4g 内存挂虚拟机还是有点捉襟见肘的。

喜欢的话,留下你的评论吧~