Zhangzhe's Blog

The projection of my life.

0%

用树莓派 5 搭建 NAS 的 worklog

0. 背景知识

  1. NAS 是什么?
    • NAS 的全称是 Network Attached Storage,网络附加存储,说白了就是一个低性能高容量的私有云服务器
  2. NAS 能干什么用?
    • NAS 可以作为家庭影院数据中心,NAS + 局域网文件传输协议 + 智能电视 + 家庭影院软件可以实现非常好的家庭观影体验
    • NAS 可以作为私有云服务器,承担例如图床/视频床等功能,也可以建网站
  3. 怎么做一个 NAS
    • 通常情况下,直接买一个成品 NAS 是一个省心的选择,外观看通常是一个可以插硬盘的盒子,本质是一个 PC
    • 我更喜欢自己手搓

1. 手搓 NAS 方案

  1. NAS 手搓需要搞定 NAS 本体和网络两大块
    1. NAS 本体负责下载数据,保存数据和局域网内数据共享
    2. 网络部分负责让 NAS 本体成为一个公网可访问的设备
  2. NAS 本体用树莓派 5 实现是一个不错的选择
  3. 网络部分用光猫桥接 + DDNS + 端口转发方案

2. NAS 本体

硬件

  1. NAS 本体是一个 4GB 版本树莓派 5
  2. 一个 32GBSD 卡作为系统盘
  3. 一块 1TBUSB 3.0 的移动机械硬盘(后续根据需求扩容)

软件

  1. 操作系统:Ubuntu 24.04 Desktop arm64下载地址
    1. Ubuntu 的好处:社区活跃,遇到问题容易解决
    2. 坏处:预安装软件很多,比较大
  2. 其他软件:根据需求安装,例如:
    1. Samba 局域网共享软件
    2. RDP 远程桌面软件
    3. Transmission 磁力链接下载器

3. 网络

NAS 本体比起来,网络才是手搓 NAS 最难的部分,主要包含如下几个部分

公网 IP

  1. 选择的宽带运营商是电信,电信的入户光纤是动态公网 IPv4 地址(这一点还是比较良心的)
  2. 光猫默认开启了路由模式,因此路由器的输入已经变成了局域网,为了简化网络拓扑,需要给电信客服打电话要求将光猫改成桥接模式,即光猫只承担光电转换功能,输出端口 IP 和输入端口 IP 一致
  3. 光猫开启桥接模式之后,路由器输入端口变成了公网 IP,通过 PPPoE 拨号上网,同时实测发现,光猫桥接模式下,下载速度更快

DDNS

  1. 虽然路由器的输入已经变成公网 IP,但是动态的,几乎每天都在发生变化
  2. 因此需要用到 DDNS 服务,让动态 IP 绑定到静态的域名上,域名之前已购买,只需要在顶级域名之前加上一个 A 记录的子域名
  3. 由于家里用的路由器是小米 be6500 pro 型号,这个路由器本身并不支持腾讯云(dnspod)的 DDNS 服务,所以有两条路可以选:
    1. 刷机到 Openwrt 路由器固件,这个开源固件功能十分强大,但坏处是路由器无法再绑定到米家 APP 实现远程控制的一些官方功能
    2. 另外一种方法是通过某种方法开启路由器的 ssh 权限,登录到路由器内部,在内部开启 dnspod DDNS
  4. 这里选择了第二种方法,ssh 开启教程在 这里
  5. 开启 ssh 后,就可以登录到路由器 terminal,然而路由器使用的是小米自己魔改的 XiaoQiang Linux 操作系统,包管理工具以及软件源什么的完全搞不懂,也很难查到相关资料,所以常用的 DDNS 服务软件例如 ddns-go 什么的也无法正常安装和配置
  6. 在仔细了解了 DDNS 服务的基本原理之后,决定用 SHELL 手写一个 DDNS 服务
    1. DDNS 的原理(仅在 dnspod 服务商上测试过):客户端(路由器)定期检查输入端口 IP,当发现和 dnspod 服务商记录的这个域名绑定的 IP 不一致时,就给 dnspod 发一条修改绑定关系的请求,dnspod 更改后,新的 “域名——IP” 绑定关系就建立了
    2. 这里涉及到几个关键:
      1. API Token:上面这个修改过程显然不是任何人都可以改的,你只能修改自己名下的域名绑定的 IP,所以需要一个密钥来和 dnspod 服务器交互,这个密钥在 https://console.dnspod.cn/account/token/token 创建
      2. 查找域名和记录对应的 ID:由于 dnspodDDNS API 要求域名和对应的记录是以 ID 的方式描述的,所以需要查到域名 ID 和记录 ID
        1. 域名 ID
          1. curl -s "https://dnsapi.cn/Domain.List" -d "login_token=<your_token>&format=json" 得到输出查询结果
          2. 然后在查询结果中找到名下多个域名中想要查询域名的 ID
        2. 记录 ID
          1. curl -s "https://dnsapi.cn/Record.List" -d "login_token=<your_token>&format=json&domain_id=<your_domain_id>&sub_domain=<your_sub_domain>" 得到查询结果
          2. 在查询到的此域名下多条记录中,找到关注的记录 ID
      3. 查询当前 IPcurl -s http://ipinfo.io/ip
      4. 更新 DNS 记录:curl -s -X POST "https://dnsapi.cn/Record.Modify" -d "login_token=${API_TOKEN}" -d "format=json" -d "domain_id=${DOMAIN_ID}" -d "record_id=${RECORD_ID}" -d "sub_domain=${SUB_DOMAIN}" -d "record_line=${RECORD_LINE}" -d "record_type=${RECORD_TYPE}" -d "value=${CURRENT_IP}"
    3. 然后将此 DDNS_update.sh 文件注册到 crontab 中,每 5 分钟更新一次
  7. 确实可以正常更新 DNS,不过忙完之后才发现可以在树莓派上实现,不用自己写 SHELL

端口转发

  • 外网只能访问到路由器,如果想要通过 ssh 实现外网直连树莓派,那么需要在路由器上配置端口转发
  • 由于目前只有 SSHRDP 两个远程访问需求,所以只开了 223389TCP 端口转发(开的越少内网设备越安全)

4. 使用体验和后续计划

使用体验

  1. 用外网可以直连树莓派,可以用 SSH 远程给树莓派下发一些下载任务,也可以用 RDP 处理一些需要 GUI 的需求
  2. 设置了移动硬盘开机自动挂载,索尼电视安装 KODI 通过 Samba 协议看 4K 电影体验很震撼

后续计划

  1. 开放 http 协议端口,在树莓派上用 Nginx 等引擎让树莓派作为个人博客的图床和视频床
  2. 扩展硬盘架,树莓派外接 16 pin PCIE 转多口 SATA 扩展板 ,连接机械硬盘架