Homelab: ESXi 软路由和家庭影院最佳实践

Homelab Aug 29, 2020

修订记录

  • 2021.08.19 - 优化网盘配置
  • 2020.12.01 - 重构网络结构
  • 2020.08.29 - 初稿完成

最近折腾软路由也有一阵子了,摸索出来一套适合自己的方案,关键词是两个,轻量级和最佳实践。

首先说轻量级,轻量级意味着不需要太强性能的设备,其次功耗要低否则电费也会吃不消,另外也不需要太大容量的硬盘。而最佳实践首先意味着可靠,也就是不管什么时候都得能连得上网,对于小白来说,折腾的时候家里网断了才尴尬,这就要求软路由方案要尽可能的减少对当前网络的侵入性,另外网络架构还要尽可能的简单,因为简单意味着可靠,要尽可能的减少内网的层级,多一层内网就多一层 NAT,这对于某些应用是不可接受的。

下面是拓扑图,可以看到对于普通的设备来说,一切都跟以前一样,而对于需要特殊功能的设备,只需要将网关和 DNS 改成软路由的即可。

注:下图已弃用,现在软路由里面只装了一个 Linux。最近整理了一下需求,发现基于 Linux 完全自己配置更自由,也更稳定一些。这么看来,openwrt 还有 openmediavault 这类系统存在的意义,就是提供一个简单的界面给人们使用,对于性能有极致追求的,还是踏踏实实自己调参吧。

太细节的东西我就不太想写了,下面放一些结论欢迎食用。

先上几个图来,这是我手上这台工控机,处理器是 3865u,搭配 8GB 内存 128GB SSD 和 1.5TB 的 HDD。无风扇设计,平时功耗大概 8W,第七代的 CPU,相当够用了。

软路由硬件配置选择

目前来看,可选的一般有 J1900 / 3865u / 3965u / 4415u / i3 / i5 / i7,基本上还是要大家想清楚自己的需求的,一般来说 3865/3965 绝对够了,如果不够,不是 CPU 的问题,而是你的问题。

对于局域网跑满千兆带宽的需求,普通路由器是足够的,J1900 在探索国际互联网的过程中,没办法跑满千兆,所以这一款最先被放弃,当然了对于需求不高的人来说 J1900 也是足够。

接着说后面几款,3965 纸面数据性能比 3865 高 20%,实际上可以认为没什么用,因为 3865 足够你装虚拟机,跑满带宽,包括装一个 Linux 里面挂几个网站开几个服务,这个 CPU 也是够的,绝大多数 web app 都不是 CPU 密集型的程序。

那什么是 CPU 密集型的呢,音视频转码,对于音视频转码的需求来说,多强的 CPU 也照样不够用,都会觉得慢。如果真遇到了运算能力的瓶颈,有一万种优雅的方法绕过他,等下在流媒体服务器方案中详细说明。

当然了如果 3865u 和 3965u 差价在 100 以内,还是选 3965u,再贵就不建议了,因为付出了差价但是基本上用不到多出来的性能。

很多人会高估自己对 CPU 的要求,根据我个人经验来看,除非编译很大的程序,或者渲染视频,手上这台 MacBook 的 CPU 一般都在 10% 以内趴着。以及,关于阿里云的服务器,我惊奇的发现即使选了突发性能型号 T5 的 ECS,每天也只消耗了 5% 的计算配额。

内存建议 8GB 起步了,SSD 64G 是够的,128 也可以(可以装一个 windows 虚拟机),再高真的没必要。

网线取决于使用场景,如果只是作为跳线,1 米以内 5 类线也可以跑满千兆带宽,如果有得选建议还是圆形有十字骨的 6 类线,除非有特殊需求否则避免扁网线,尽管一米以内只要是根 RJ45 线就能跑满千兆。根据网友的测试,6 类线百米以内跑满 10G 带宽也没问题,所以对于普通家庭来说,质量好的 6 类线可以满足需求,当然了如果是装修布线,还是选光纤或者更高规格的线材吧。

ESXi 配置相关

注:我在最新的方案已经不再使用 ESXi,不过下面的结论仍然适用。

ESXi 毫无悬念肯定选 6.7 版本,因为 7.0 对个人用户很不友好,比如驱动问题,比如磁盘占用,比如内存占用。

至于 PVE 和 ESXi 选哪个,这个问题大概相当于 MariaDB 和 MySQL 你选哪个,照着自己一贯的做法去选就行了。这是一个开源软件和商业软件社区版之间的选择,个人建议是如果商业软件没有针对散户的重大缺陷,优先考虑商业软件。

如果遇到了 SSD 速度只有 30MB/s,一种可能是 ESXi 对这个牌子的 SSD 兼容有问题,另一方面也可能是 BIOS 设置的不对,在硬盘的选项中好好看看,改成正确的信息即可。

ESXi 需要配置的地方很少,我把他们分为如下几项:

  • 静态 IP 的设置

这个可以在开机之后外接显示器,F2 修改静态 IP。

  • 硬件直通

直通完毕切记相关虚拟机要预留所有内存,否则无法启动。

  • SSL 证书

首先明确,ESXi 不支持 ECC 证书,擅自安装 ECC 证书之后会导致无法开启 web 管理界面,解决方案只有一个,那就是外接显示器打开 SSH,换一个 RSA 的证书,附一条重置证书的命令,会自动生成一个自签名的证书,可以解决上述 ECC 证书的问题。

/sbin/generate-certificates

其实 ESXi 的 openssl 版本是支持 ECDSA 算法的,并且曲线里面也包含了 secp384r1 曲线,奈何就是网页不能配置 ECC 证书。

网上很多暴力教程,要我说都是瞎 jb 写,官方的建议是 key 文件不要碰它(400 权限),那么方法就来了,用这个 key 生成一个 CSR,只编辑证书文件就行了。

For Commercial CAs:
1. Take the certificate request ( rui.csr, as generated above) and send it to the authority in question.
2. The authority will send back the generated certificate.
https://kb.vmware.com/s/article/2113926
// 重启管理网络生效 SSL 证书
/etc/init.d/hostd restart
/etc/init.d/vpxa restart
  • 交换机设置

默认交换机的设置里面,建议设置一个混杂模式,方便少插一根网线,缺点是会依赖 OpenWrt 的启动,因为 OpenWrt 要做这个口的桥接。

ESXi 直通相关

NAS 数据盘直通不用说了,关于网卡直通,路由器性能一般要么是过剩,要么是不够,不够的时候肯定用直通,但是过剩的时候,选虚拟网卡也没太多损耗,纯虚拟的兼容性更好一些。实际可以根据网卡兼容程度和自己强迫症程度来选。

经过实测,我的软路由固态盘和机械硬盘同属一个 SATA 控制器,直接直通硬盘会导致很严重的后果,如果谁遇到相同问题,建议重装,修复起来过于麻烦。

再就是 ESXi 自带的 RDM 直通,实测效果跟 PCIe 直通性能差距几乎没有,唯一的区别就是不能读取 SMART 信息,硬盘插到别的系统里照样可以读取文件。

关于显卡直通,本来想直通一个核显给 Debian 系统,做流媒体的硬解码,后来发现 ESXi 不认 HD610 这个核显,遂作罢,硬解的问题稍后再说。

OpenWrt 和 ROS 的选择

普通用户真的没什么必要上 ROS,带来的体验会边际递减,OpenWrt 选一个稳定的发行版本即可。OpenWrt 的官方固件功能有限,可选的有 koolshare 和 Lean 的 LEDE,前者 700M 功能更强后者 100M 更稳定但是需要自己编译。

OpenWrt 的设置

基本上国内用户的需求就是探索广阔世界了,这部分因为个人不需要就不再介绍。

关于去广告,直接上结论,koolproxy 一是不再维护了,再就是他需要 Root CA,综合所有考量还是用 adbyby 比较好。另外,adbyby 自带的规则太少了,建议订阅 https://github.com/privacy-protection-tools/anti-AD ,选 dnsmasq 规则,因为 dnsmasq 是从域名解析入手来屏蔽这些广告,跟其他几种(hosts, easylist)比起来,效果差不多,但是效率高。

注:在只安装 Linux 的方案中,adbyby 可以用自建 DNS 方案代替,反正只要不引入 MITM 效果都一样。网易云解锁在 OpenWrt 上面还用到了 ipset,实际上 Nginx 反代一下,配合上述 DNS 指向这台机器就行了。旁路网关毕竟还是太麻烦了,投入回报率不行。简单的说,就是通过自建 DNS,就可以解决去广告,网易云,KMS 等等服务。软路由最大的麻烦在于转发包的能力很弱,当路由器拨号的话,上网速度肉眼可见的慢。旁路网关模式也是一样,并且会增加一跳,实在是没有必要。

去广告整个机制其实很麻烦,如果在浏览器上,插件可以根据 HTML 内容过滤标签,所以是最精准的,缺点就是必须 Chrome,连 Safari 都不行,而且只能在浏览器上实现。从路由器上如果想实现相同功能,现在很多网站都用 HTTPS,必须信任自己的 root 证书,解密流量然后过滤,是一个很脏的做法。综合所有考虑,我的核心诉求其实是禁止追踪,尤其是 mmstat 这个混蛋流氓,只要能屏蔽 mmstat 就很幸福了。

关于网易云解锁灰色歌曲的功能,如果不放心还是建议自己签一个 Root CA 证书,避免日后的麻烦。另外还有一个小技巧,作者的方案里面,网页版的播放器会废掉,因为打开网页不会加载 CSS 和部分 JS。解决方案就是在签发证书的时候,除去是作者推荐的两个域名 DNS:music.163.com,DNS:*.music.163.com,再加两个,签发这四个域名的证书 DNS:music.163.com,DNS:*.music.163.com,DNS:*.126.net,DNS:*.music.126.net

私人网盘的方案

自建网盘经过一阵子的摸索,总结出来一套用法,应该不输任何大厂的解决方案。一般来说,网盘我们有两种用法:

  1. 本地一个文件夹和云端实时同步
  2. 直接挂载网盘

实时同步的好处就是读写很快,毕竟都是在本地,那坏处也显而易见就是占磁盘空间。直接挂载网盘刚好相反,延迟比较高,做不到指哪打哪,像是用 2000 年代的硬盘反应速度,单论速度其实还好,Wi-Fi 能跑到 60M 有线能跑满 G 口带宽。

同步盘

针对方案 1,个人建议采用 syncthing,配置好两台机器之后直接共享一个文件夹就行。关于设置方面,建议可以打开 Simple File Versioning 可以自动保存五个版本,防止手残删了不该删的东西。关于 ignore,建议写一个全局的 .stglobalignore,每次创建新的分享都直接 #include .stglobalignore 省去很多麻烦。

//---Mac-specific---//
//Mac Comments, Finder Windows Size, Tags, ...
(?d).DS_Store
.DocumentRevisions-V100
//Mac Folder Icons, which will not sync to Windows
(?d)Icon*
.Spotlight-V100
.TemporaryItems
.Trashes
.fseventsd
//Mac Flag to enable translation of Folder Names
(?d).localized
//Mac Temporary iCloud files while synching
.iCloud
//Mac OS Metadata on Windows or Linux filesystems
(?d)._*

//---Windows-Specific---//
(?d)desktop.ini
(?d)Thumbs.db
(?d)$RECYCLE.BIN
*.lnk

//---Linux-specific---//
.Trash-*

//---QNAP-specific---//
(?d).@__thumb
(?d).AppleDB

//---Synology-specific---//
(?d)@eaDir

//---Application-specific---//
//-Syncthing
(?d).stignore
(?d).stfolder
//-vi(m)
(?d)*.*.sw[a-p] # Thankys to Tom Hale!
//-Dropbox
.dropbox
.dropbox.attr
//-Microsoft Office temporary files/lock files
(?d)~*
//-KDE
.directory

//---OTHER---//
Microsoft-Benutzerdaten
Notizbuch von Wolf.url
Outlook-Dateien
RDC Connections
.parallels-vm-directory
Default.rdp

syncthing 用起来还是比较容易的,没有太多要配置的地方。服务器上关于 syncthing 的开机自启,可以用 sudo service syncthing@xxx start xxx 为用户名这样可以实现权限管理。

NextCloud 吐槽

另外是第二种,直接挂载网盘。普遍来说有两种技术比较容易实现,SMB 和 WebDAV。我试过并且调优过 NextCloud。结论就是 NextCloud 就是个垃圾,垃圾,垃圾。

NextCloud 最大的缺陷在于磁盘 IO 控制的不到位,在线播放视频本来应该网络传输多少读多少磁盘,根据 HTTP Header 头里面的 Range 决定读取多少文件内容,但是 NextCloud 会读取整个文件,经常服务器的负载会从 0.02 飙升到 50+,经过排查发现是 IO 导致的。我在 GitHub 提过好几个 issue,但是官方解释说这个问题在目前的代码框架下很难解决。

并且,NextCloud 在 WebDAV 协议下同步多个小文件的时候也存在 IO 的问题,总的来说,NextCloud 玩玩可以,当个网盘替代品可以,别使劲操,否则代价就是网站卡死,半个小时后见,除非手动重启 php 进程。

而这种问题几乎是无解的,总不能无限的增加磁盘速度,而且重点在于,磁盘是被完全不必要的读写给占满的,根本没发挥出应有的价值,比如打开一个视频再关闭,NextCloud 仍然会坚持读完这个文件,如果打开多个大文件再关闭,那服务器的负载会高到爆炸,直到网站卡死。

这里有一个投机取巧的方案:数据盘单独挂载,比如挂载到机械硬盘,而 NextCloud 源代码,php 程序放在 SSD 里面,这样即使机械盘的 IO 占满,也不至于网站卡死。为什么网站会卡死呢,因为 php 是一门脚本语言,运行时要从磁盘读取的,当然也可以打开 opcache,但是总归治标不治本。

挂载磁盘

自己配置 SMB+WebDAV,文件权限是重中之重,其他配置都是陪跑的。

WebDAV 可以采用 Nginx 来部署,把 Nginx 的用户名改成那些文件的所有者即可。同理 SMB 也是,这两个都是可以无缝挂在到 Mac 和 Windows 上的。关于授权可以用 Nginx 自带的 HTTP 授权登录,方便易用。安全性也没问题,可以放心映射端口到公网。配置如下:

    location / {

        set $dest $http_destination;
        if (-d $request_filename) {
            rewrite ^(.*[^/])$ $1/;
            set $dest $dest/;
        }
        if ($request_method ~ (MOVE|COPY)) {
            more_set_input_headers 'Destination: $dest';
        }
        if ($request_method ~ MKCOL) {
            rewrite ^(.*[^/])$ $1/ break;
        }

        root /mnt/d/;
        client_body_temp_path /mnt/d/lib/tmp;
        autoindex on;
        dav_methods PUT DELETE MKCOL COPY MOVE;
        dav_ext_methods PROPFIND OPTIONS LOCK UNLOCK;
        dav_ext_lock zone=cloud;
        create_full_put_path on;
        dav_access user:rw group:r all:r;

        satisfy any;
        allow xxx.xxx.xxx.0/24;
        allow xxxx:xxxx:xxxx:xxxx::/64;
        deny all;
        auth_basic "Authorized Users Only";
        auth_basic_user_file .htpasswd;
    }

    location ~ \.(_.*|DS_Store|Spotlight-V100|TemporaryItems|Trashes|hidden)$ {
        access_log  off;
        error_log   off;

        if ($request_method = PUT) {
            return 403;
        }
        return 404;
    }

    location ~ \.metadata_never_index$ {
        return 200 "Don't index this drive, Finder!";
    }

SMB 的配置别的不多说了,网上说 SMB 的安全性不够,所以尽量内网使用,配置如下:

[debian-data]
    comment = Jie's file on Debian Server
    path = /mnt/d
    read only = no
    browsable = yes
    create mask = 0644
    directory mask = 0775
    veto files = /._*/.DS_Store/
    delete veto files = yes

有一点需要注意的是,macOS 下的 webdavfs_agent 实现不太合理,从 WebDAV 服务器下载文件到移动硬盘的时候,也会在系统盘里面写缓存,相比之下,SMB 的实现依赖于 kernel_task 是 0 开销,猜测是减少了一层内核态到用户态的拷贝,类似于 nginx 中的 sendfile。所以拷贝大文件,为了避免不必要的磁盘损耗,尽量内网使用 SMB 协议。

流媒体服务器

流媒体服务器是花了我最长时间的模块,最开始用 NextCloud,奈何 IO 问题会导致硬盘速度占满,虽然后来经过调整也勉强能用,但是没办法我有强迫症,不该他读盘的时候就是不能纵容他读盘。所以首选就是 Nginx 映射一个静态服务器到视频目录,不得不说 Nginx 真牛逼,几乎做到没有 IO 开销,响应极快,然而好景不长很快就遇到问题了,有的视频是 mkv 容器的,里面虽然视频流是 H.264,奈何音频不是 aac,交给浏览器是没办法解码的。于是乎我在网上看到个骚操作,让 Nginx 识别 mkv 格式,本来以为自己要成了,结果发现视频是可以播放,但是没声音。所以这个方案基本上不可行,除非你打算给每个视频做转码。

接着就发现了一个神器,Emby。Emby 有一个很神奇的功能,假设一个视频是 H.264 编码音频是 DTS 编码,Emby 可以做到只转码音频,达到在线推流的效果。所以这里我想回应一下上面的观点,为什么 3865/3965 CPU 性能足够,并且再高几乎没什么用,因为如果只是给音频解码,3865/3965 足够了,网上漫天飞的 H.264 资源,真遇到 CPU 瓶颈,不是 CPU 的问题而是你的问题。

不得不说 Emby 帮用户解决了很多问题,漂亮的布局,metadata 搜刮,字幕下载等等,必须说一句 Emby 真香!

ESXi 下直通核显给 emby 比较麻烦,有些核显确实不能被识别,瞎搞容易搞崩系统然后就麻烦了,为了一劳永逸,直接关闭用户 transcoding 功能就行了,只允许 audio transcoding,因为网上的资源基本上都是 H.264 编码,所以使用起来没问题。关了之后,副作用是用户没法看其他编码的视频,但是一般种子都会写清楚是否 H.264 编码,所以可以认为这样做不存在问题。

Emby 是一款免费的软件,部分高级功能需要会员才行,119 美元买断,具体高级功能自己看官网去 https://emby.media/premiere.html 。当然了也是有办法绕过验证,实现方法就是跟上面网易云解锁灰色歌曲差不多,自己签一个证书,并且劫持 DNS 到对应的服务器,在对应的验证 URL 返回硬编码的 json 即可。

对了有一个小技巧,如果遇到激活不成功,或许是因为 Emby server 端代码里面写死了一个 root 证书列表,需要编辑这个列表加入自己的 root 证书。

VPN 方案的选择

注:在自建 Linux 的方案中,自己搭建 VPN 服务连接速度超快,基于 Linux 的 VPN 方案有很多我就不多说了。如无特殊需求建议抛弃 OpenWrt 这类操作系统。

端口转发毕竟还是风险大,总有一些孤儿选手没事扫你服务器,一些高级别的权限端口还是隐藏下来,外面套一层 VPN 比较好。

OpenWrt 上面我尝试过自带的 IPSec 方案,在 OpenWrt 作为旁路网关/旁路由的时候,只能连上 VPN 服务器,也就是说只能连上 OpenWrt 系统,不能上公网也不能访问内网服务,网友们的测试结果是 OpenWrt 作为主路由的时候,问题似乎少一点,具体测试结果如下:

  • 4.14 内核:大概率用不了
  • 4.19 内核:大概率重启
  • 5.4 内核:只能访问内网

总而言之,唯一可行的方案就是 SoftEther,大概步骤如下:

  1. OpenWrt 安装 softethervpn5-serversoftethervpn5-libssoftethervpn5-bridge
  2. 官网下载一个配置工具开始配置

要注意一点就是,如果使用旁路网关方案,SoftEther 里得添加一个本地网桥,OpenWrt 配置里面要桥接上这一个网口,最后就是主路由上面记得转发这几个端口:UDP 500,UDP 4500 和 TCP/UDP 1701,正常情况下这个方案是支持同时访问内网和外网的。

Singtel 的光猫和 AP

Singtel 的宽带有一个 HG8244H 光猫还有一个 AC1900 的路由器,两个的访问地址都是 192.168.1.254,由于路由器关闭了 DHCP,所以默认会连到光猫的管理后台。如果想设置路由器,把光猫拔下来,使用自己的子网,即可实现路由器管理。

另外光猫上面也有一些小技巧,背后标签贴的账户 root 密码 admin 只是一个普通用户,不能改变光猫的工作模式,实际的控制账户密码是其他的,谷歌可以找得到。

备份

这个其实是因人而异,但是原则很简单,自己产生的数据必须备份,网上可以下载到的尽量不备份,对于我个人来讲,重要的文件有这么几个:

ESXi 系统配置

ESXi 的配置可以通过人肉记忆,也可以通过导出配置。值得一提的是,ESXi 是运行在内存里的,所以带来的一个副作用就是数据持久化不是实时的,很多人可能已经发现修改完 ESXi 的设置,拷贝出来配置文件依旧是老的。通过强制同步命令可以解决:

vim-cmd hostsvc/firmware/sync_config

vim-cmd hostsvc/firmware/backup_config

OpenWrt

OpenWrt 很多发行版本里面自带一个备份,导出之后可以满足绝大多数场景的备份,唯一一个就是替换掉 UnblockNeteaseMusic 自带证书之后,证书默认不备份,需要自行解决。

Debian 服务器

  • etc 存放各种精心调整过的配置
  • home 目录以及所有命令行历史,但是不包括 .npm .composer .cache 这些
  • 数据库
  • 网站的配置文件
  • Emby

我的做法是写一个备份脚本,每天打包前四处文件,加起来大概 3MB,并且同时删除当前天减去三这一天的备份,也就是说永远只保留三天的备份。至于备份是传到网盘,还是 OSS,还是其他储存介质,这个因人而异。

同时我也会保证至少一个月一次的全盘备份,把虚拟机关机,直接拷贝出来所有文件放在移动硬盘里,这么下来基本上就不会有任何问题。

Emby 的备份可以通过内置的备份模块来做,默认每 12 小时备份一次,记得修改备份目录的权限为 emby:emby

sudo chown -R emby:emby backup/folder

总的来说,每套方案只会适合某个群体,上面这套相对更适合轻量一点需求的用户,在保证了高可用性的同时也提供了丰富的可玩性。

Tags

Jie Li

🚘 On-road / 📉 US Stock / 💻 Full Stack Engineer / ®️ ENTJ