仓库源文站点原文


title: 个人网络 + NAS 折腾日记-1 date: 2023-11-07 08:27:24 updated: 2023-11-07 08:27:24 categories:


起因

最近有人问起我,关于我家里的 NAS 以及家庭网络搭建的情况,正好也闲来无事,打算写写目前的家庭网络部署情况

前置条件

首先,谈到家庭网络搭建,那必然需要先简单介绍一下生活基本情况:

graph BT
A1[他人设备1] -.Wi-Fi.-> B[路由器]
A2[他人设备2] -.Wi-Fi.-> B[路由器]
A3[他人设备3] -.Wi-Fi.-> B[路由器]
A4[他人设备4] -.Wi-Fi.-> B[路由器]
B[路由器] --DHCP--> C[光猫]
C[光猫] --PPOE--> D((公网))

同时,在爸妈家也有一套网络:

因此,主要也是将个人网络部署在租房内

另外,部署的过程也要符合个人的审美原则:

  1. 必须是体验极佳,要用户无感以及快速入手,能够使用系统自带的应用程序就不用第三方的程序
  2. 能多花一点钱就能减少折腾的,绝对不折腾

部署的目标也得罗列一下:

部署

家庭网络

网络方面的架构则比较简单,因为对这块的特殊需求比较少,当然也因为能够改造的方面比较少,所以也就采用简单的方案

graph BT
subgraph 我家
pad[pad] -.Wi-Fi.-> mi[小米路由器]
phone[phone] -.Wi-Fi.-> mi[小米路由器]
pc[laptop] -.Wi-Fi.-> mi[小米路由器]
nas[NAS] --> mi[小米路由器]
mi[小米路由器] --AP--> r2s[r2s]
end
r2s[r2s] --DHCP--> B[路由器]
A2[他人设备2] -.Wi-Fi.-> B[路由器]
A3[他人设备3] -.Wi-Fi.-> B[路由器]
A4[他人设备4] -.Wi-Fi.-> B[路由器]
B[路由器] --DHCP--> C[光猫]
C[光猫] --PPOE--> D((公网))

NAS 搭建

接下来是 NAS 的部分

考虑到避免折腾以及后续真香的成本,我决定直接入手白群晖。选择的是四盘位的 DS423+ 这款。主要考虑到的也是使用的目的。

DS423+

存储设置端

硬盘安装可以参考群晖给出的文档

SHR 比之余 RAID5 的好处,主要还是在于扩容的时候,只需要购买两张更大的硬盘就可以实现扩容,无需把所有硬盘都替换掉。至于性能和寿命?作为一个偏轻度的 NAS 使用者而言,似乎是一个无关痛痒的东西

将套件中心的存储空间和 Download Station 的缓存空间都设置到 SSD 盘,这样可以减少很多机械硬盘本身带来的噪音

网络配置

网络配置才是比较麻烦的操作

内网访问不必多说,主要是通过 HTTP 协议来管理,由于群晖提供的套件比较丰富,实际上你可以仅使用 HTTP 来管理文件、系统,当然,考虑到舒适的使用,还是需要用上 SMB 服务

测试了一下,房东的光猫的防火墙禁止了入网流量,导致无法直接在外网通过 IPv6 来访问到自己的 NAS。既然在没有考虑到要换新的房子的前提下,那就只能委曲求全,通过一些其他方案来访问内网

方案一:QuickConnect

quick connect 可以说是非常完美的解决方案,它考虑内网直连、公网 IP 直连、UPNP 连接、打洞、转发等方案,一个地址走天下的方案,能够在任何场景下得到最好的访问途径,可以说 QuickConnect 是体验最好的方案……吗?来看看速度对比

为了对比速度,我测试了一个大文件在多种场景下的速度情况,测试文件是《铃芽之旅》2K 的 mkv 打包的视频,大小为 10.64GB(9.91GiB)足够传输个几秒钟了

suzume

测试环境,只用一根网线让 NAS 和路由器直连,然后由我的 laptop 通过 Wi-Fi 接入路由器,路由器本身开启 AP 模式。如果传输方式本身能够提供速度监控的话,那就按照监控本身为准,否则直接将 laptop 的整体网络下载速度为准

首先采用理论上 TCP 下最快的方案:在 NAS 上开启 tcp 监听,同时将输入流设置为视频文件,而后在本机上通过 tcp 直接连接到 NAS 的端口,并将结果写入到本地文件

# nas 上
nc -l 9090 < "~/Videos/Movies/Suzume/Suzume.2022.2160p.WEB-DL.H265.DDP5.1.2Audio-DreamHD.mkv"
# 本地机器
nc nas.com 9090 > "~/Download/Suzume.2022.2160p.WEB-DL.H265.DDP5.1.2Audio-DreamHD.mkv"

可惜的是群晖系统没有默认携带 netcat,再去下一个的意义不大,毕竟说白了也没人这么用 NAS 的,谁下载个东西都用 netcat 啊(虽然好像我经常这样给服务器传输文件) 当然也可以退而求其次,选择使用 SCP 的方式来拷贝文件,但也和上述问题一样:没有人平时会这样用 NAS,也就不再过多测试了

那就直接上 SMB 的下载吧

smb-private

速度基本上可以稳点在 100MB/s+

然后是内网通过 HTTP 协议下载的速度

http-private

也差不多,这两者的误差几乎可以忽略

然后是 QuickConnect 的在最坏的情况下(采用转发的方案)外网访问速度,我才用了 5G 热点的方式接入,也是在外网最常见的访问场景

qc-forward

这就有点丢脸了,也是这个方案下最让人难以接受的原因

当然还有一个令人难以接受的就是,他强制会将你的文件分享地址改成 gofile.me 这个域名,看起来就让人不太舒服

qc-share

DDNS 和 IPv6

这两个方案本是个人最喜欢的方案,没有什么比直接连接更加干净利索的了,但……目前的居住环境既拿不到公网的 IPv4 地址,又被光猫的防火墙拦截了 IPv6 的数据,这确实让人没办法接受

内网穿透

最终,只能选择内网穿透方案。考虑采用 frp 作为内网穿透的方案

外网访问配置

租一台阿里云的 ECS,在按量计费的阿里云 ECS 的成本确实很低,百兆带宽,也只要 1k 就能用 5 年,虽然流量挺贵,1GiB 需要 ¥0.8 但通常也不太会在外面直接看视频,毕竟要么还需要消耗手机的移动网络,要么是有预期要出远门,通常更多会提前下载在本地,比如坐飞机的时候。另外,一部电影 20G 的话,也花不了几块钱才是

aliyun

然后通过 frp 的方式进行数据传输,简单起一个 docker 镜像。

docker-compose.yml 的大概信息

version: '3.3'
services:
  frps:
    restart: always
    network_mode: host
    volumes:
      - './frps.ini:/frp/frps.ini'
    container_name: frps
    image: stilleshan/frps

之所以选择 network_modehost 的目的也是懒了,毕竟但凡来一个端口需要转发的,就又要再配置一下 docker 镜像的端口映射,确实有些麻烦了

frps.ini 配置信息

[common]
bind_port = 7000
token = XXXXX

frpc.ini 的配置参考信息

[common]
server_addr = nas.com  # 阿里云服务器的 IP/域名
server_port = 7000
token = XXXXX          # frp 的 token,和服务端配置一致即可

[nas_dsm_http]
type = tcp
local_ip = 127.0.0.1
local_port = 5000      # DSM 配置端口,因为一般不允许修改为 80
remote_port = 80       # 阿里云服务器上暴露的端口,后续访问直接使用此端口即可

[nas_dsm]
type = tcp
local_ip = 127.0.0.1
local_port = 5001      # DSM 配置端口,因为一般不允许修改为 443
remote_port = 443      # 阿里云服务器上暴露的端口,后续访问直接使用此端口即可

[nas_smb]
type = tcp
local_ip = 127.0.0.1
local_port = 445       # NAS 的 SMB 端口,默认是 445
remote_port = 12345    # 阿里云服务器上暴露的 SMB 端口,因为国内防止蠕虫病毒,默认都是禁用了 445,至少我连不上我自己阿里云服务器的 445 端口,故只好换一个端口用

然后再配置一下域名和证书。去阿里云购买一个域名,比如 nas.com,然后将其 A 记录指向购买的阿里云服务器的外网地址。然后再申请一张免费的证书,上传到 NAS 的证书上。

然后再将阿里云的服务器的防火墙开放 80、443 和 12345 的连接,这样就可以直接通过域名访问到 NAS

内网优化

目前这样做的坏处是:内网使用的是 192.168.xxx.xxx 地址访问,而外网则是用 nas.com 进行访问,有一种奇怪的割裂感,于是打算继续优化一下

路由器上,为 NAS 的 mac 地址绑定固定的 IP,避免 DHCP 每次得到的地址不同。比如绑定到 192.168.1.100,然后再进行 DNS 挟持,将 nas.com 挟持到 192.168.1.100。这样内外网访问的域名就相同了

但稍微有些不适的问题,内网下,访问地址为 nas.com:5001 而外网则为正常的 nas.com。当然你也可以把 frp 的 [nas_dsm] 下的 remote_port = 443 改成 remote_port = 5001 来强行相同。但仍然让人有点膈应

那就继续优化内网的访问,通过 ssh 进入群晖的后台,通过这个方案解除对 80/443 端口的占用,然后修改 /usr/syno/etc/www/DSM.json 文件,将控制台的端口强制改为 80/443。注意要同时修改 frpc.ini 文件

个人想法

由于阿里云的服务器通常还有很多用处,NAS 只是其中之一,所以还需要再做一层调整,为其再套一层 nginx 服务。首先修改一下 frpc.ini 配置,将 80/443 端口释放出来。因为大部分其他服务通常都需要使用这两个端口,不如统一架设一层 nginx 来实现代理访问

[common]
server_addr = nas.com  # 阿里云服务器的 IP/域名
server_port = 7000
token = XXXXX          # frp 的 token,和服务端配置一致即可

[nas_dsm]
type = tcp
local_ip = 127.0.0.1
local_port = 443      # DSM 配置端口,因为一般不允许修改为 443
remote_port = 5001    # 阿里云服务器上暴露的端口,后续访问直接使用此端口即可

[nas_smb]
type = tcp
local_ip = 127.0.0.1
local_port = 445       # NAS 的 SMB 端口,默认是 445
remote_port = 12345    # 阿里云服务器上暴露的 SMB 端口,因为国内防止蠕虫病毒,默认都是禁用了 445,至少我连不上我自己阿里云服务器的 445 端口,故只好换一个端口用

而后在阿里云服务器上,再起一个 docker 容器,作为服务器的主 nginx 配置

version: '3.1'

services:
  http:
    container_name: http
    image: nginx
    extra_hosts:
      - "host.docker.internal:host-gateway"
    restart: always
    volumes:
      - ./cert:/etc/nginx/cert
      - ./templates:/etc/nginx/templates
      - ./html:/usr/share/nginx/html
    ports:
      - 80:80
      - 443:443

而后将证书也上传到阿里云的服务器,并配置 nginx 的配置文件

server {
  listen       443 ssl;
  listen  [::]:443 ssl;
  server_name  nas.com;

  ssl_certificate cert/nas.com.pem;
  ssl_certificate_key cert/nas.com.key;

  ssl_session_cache shared:SSL:1m;
  ssl_session_timeout 5m;

  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
  ssl_prefer_server_ciphers on;

  charset utf-8;

  client_max_body_size 20m; # 务必设置客户端最大上传文件大小,否则部分文件上传将会失败

  location / {
    proxy_pass              https://host.docker.internal:5001;
  }
}

server {
  listen       80 default_server;
  server_name _;

  # 将所有 HTTP 请求通过 rewrite 指令重定向到 HTTPS。
  return 301 https://$host$uri;
}

这样,如果后续还要新增服务,只需要通过在这个主的 nginx 内配置相关的路由和转发即可,由主路由实现代理访问和证书管理