#+TITLE: 在 NanoPi R2S 上运行 FreeBSD #+DATE: <2023-07-10 一> 曾经有两个树莓派, Pi3 因为碰水, Zero 因为腐蚀, 都报废了 我想在 R2S 上运行 BSD, 因为: 1) it's cool 2) base system 足够, 只需要安装少量包 3) 简洁, 适合小设备 * 艰辛的历程 - 带上手套防止腐蚀, 用螺丝刀和弯头镊子 (文具盒里随手使用) 撬开外壳 - 缝合了一个 OpenBSD 镜像, 用 Arduino Uno 当串口连接 UART, 输出毫无意义的字符 - 运行 OpwnWRT, 依旧输出垃圾 - 运行 Armbian, 依旧输出垃圾, 想到是不是串口出错了 - 翻箱倒柜找到一个 USB Mini-B 线用于 山寨版 Arduino Nano (CH340 芯片) - 重新烧写 OpenBSD 镜像, 成功启动, 但键盘无法输入, 无法安装 - 缝合 FreeBSD 镜像, 成功启动, ssh 登录 (user/passwd:freebsd), 耶! - 合上外壳 ** 关于镜像制作 - [[https://personalbsd.org][PersonalBSD.org]] 但是构建过程不知道, 不敢用 - [[https://asciinema.org/a/381979][asciinema: NanoPi r2s RK3328 with FreeBSD 13-CURRENT]] - [[https://asciinema.org/a/381973][asciinema: NanoPi r2s RK3328 with OpenBSD 6]] 总的来说就是: #+BEGIN_SRC sh dd if=FreeBSD-13.2-RELEASE-arm64-aarch64-ROCK64.img of=root.img bs=1M dd if=usr/lib/linux-u-boot-edge-nanopi-r2s_22.05.3_arm64/idbloader.bin of=root.img seek=64 conv=notrunc dd if=usr/lib/linux-u-boot-edge-nanopi-r2s_22.05.3_arm64/uboot.img of=root.img seek=16384 conv=notrunc dd if=usr/lib/linux-u-boot-edge-nanopi-r2s_22.05.3_arm64/trust.bin of=root.img seek=24576 conv=notrunc doas dd if=root.img of=/dev/sda #+END_SRC * 开始 - 中国用户第一件事先换源: [[https://mirror.bjtu.edu.cn/help/freebsd/][bjtu FreeBSD 镜像]] - 改密码, =/usr/local/etc/sudoers= 不用 doas 因为 persist 选项只在 OpenBSD 上可用 - 主机名, 路由器配置 DHCP 静态 IP, 本机 =/etc/hosts= 加入主机名解析 #+BEGIN_SRC sh hostname r2s vi /etc/rc.conf #+END_SRC - 改 shell 配置, [[https://github.com/dongdigua/configs/blob/main/.profile.in][基本还是之前那样]] 在 fortune 里看到一个不错的 PS1, 弄个新 PS1 换换口味 #+BEGIN_SRC sh PS1='(\[$(tput md)\]\t <\w>\[$(tput me)\]) $(echo $?) \[\033[01;31m\]\[\033[00m\] ' #+END_SRC - HZ? 在 Linux 上降低 HZ 是能减少能耗的, 但这里至少温度没降, 先改成 250 吧 =/boot/loader.conf= - 降 CPU 频率是当然能减少能耗的 =/etc/sysctl.conf= * 第一个服务: gopher #+BEGIN_SRC sh su # freecolor 用于 https://github.com/dongdigua/dongdigua.github.io/blob/main/gmi/docker/cgi/stat.cgi pkg add gophernicus freecolor vi /etc/inetd.conf echo 'inetd_enable="YES"' >> /etc/rc.conf mkdir /var/gopher # don't also chown nobody group so it belongs to wheel group chown nobody /var/gopher chmod 775 /var/gopher service inetd onestart #+END_SRC * frpc daemon frp 这完意好啊, 但是 [[https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1030841][Debian 搁置了挺长时间]]也没加入 我作为 RHEL7 入坑 Linux 的用户, 没有体验过 systemd 之前的服务管理, 这里可以体验一把. 本来以为还得学 rc 脚本, 结果把同目录的 frps 改改就行了 #+BEGIN_SRC sh cd /usr/local/etc/rc.d cp frps frpc sed -i '' 's/frps/frpc/g' frpc #+END_SRC 别忘了把 gophernicus 的 host 和 port 改成远程主机的 ** SSH 命根子 有时想加一个端口转发, 然后一 restart, SSH 也断了, 所以应该把 SSH 转发分开来单独一个服务 * git 服务器 本来想弄个 ssh git 和 cgit, 但仔细考虑感觉没有啥用, 我的 repo 都托管在我朋友的服务器上. 又想弄个 sourcehut, 但真的太麻烦了. 那不如弄个 gitea, 测试一下一些奇怪的功能, 再做一份镜像. 很重要的一点: =HTTP_ADDR= 应设置成 0.0.0.0 这种比较大的服务可以放在 jail 里, 参考 Absolute FreeBSD * jail(8) 通用 jail 设置: ** 主机 =/etc/jail.conf= #+BEGIN_SRC conf exec.clean; exec.start="sh /etc/rc"; exec.stop="sh /etc/rc.shutdown"; mount.devfs; #+END_SRC ** in-jail =/etc/crontab= 取消 save-entropy 和 adjkerntz =/etc/rc.conf= 进程越少越好, 似乎我不需要 sendmail #+BEGIN_SRC conf sendmail_submit_enable="NO" sendmail_outbound_enable="NO" sendmail_msp_queue_enable="NO" #+END_SRC ** rm: Operation not permitted #+BEGIN_SRC sh chflags -R noschg file/folder #+END_SRC * Gemini 曾经我的 Gemini 是用 Docker 跑在朋友的服务器上, 但是一出问题调试很费劲. 现在有个稳定的服务器, 就可以本地跑, 省去许多麻烦. 依旧使用 jail #+BEGIN_SRC sh su pkg -j gemini install gmid git # python39 and perl5 are included in git jexec -U root gemini git clone https://github.com/dongdigua/dongdigua.github.io.git --depth 1 /dongdigua.github.io jexec -U root gemini sh #+END_SRC then run in sh: #+BEGIN_SRC sh cd /dongdigua.github.io git config --global filter.dater.smudge 'perl -pe "\$last_date = `git log --pretty=format:\\"%ad\\" -1`;s/\\\$Date\\\$/\\\$Date: \$last_date\\\$/"' git config --global filter.dater.clean 'perl -pe "s/\\\$Date[^\\\$]*\\\$/\\\$Date\\\$/"' openssl req -x509 -newkey rsa:4096 -nodes \ -out /usr/local/etc/ssl/gmid/localhost.crt \ -keyout /usr/local/etc/ssl/gmid/localhost.key \ -subj "/CN=localhost" openssl req -x509 -newkey rsa:4096 -nodes \ -out /usr/local/etc/ssl/gmid/example.com.crt \ -keyout /usr/local/etc/ssl/gmid/example.com.key \ -subj "/CN=example.com" #+END_SRC =/usr/local/etc/gmid.conf=: #+BEGIN_SRC conf user "_gmid" server "r2s.local" { root "/dongdigua.github.io" cert "/usr/local/etc/ssl/gmid/localhost.crt" key "/usr/local/etc/ssl/gmid/localhost.key" cgi "/cgi/*" default type "text/plain" } server "example.com" { root "/dongdigua.github.io" cert "/usr/local/etc/ssl/gmid/example.com.crt" key "/usr/local/etc/ssl/gmid/example.com.key" cgi "/cgi/*" default type "text/plain" } #+END_SRC =/etc/periodic/daily/update-git=: #+BEGIN_SRC sh #! /bin/sh cd /dongdigua.github.io git pull --rebase python3.9 misc/mdlist2gmi.py > posts.gmi cp -r gmi/docker/cgi . rm index.gmi git checkout -- index.gmi #+END_SRC * samba 弄着个电子垃圾 64G U盘, 想架个 Samba 要安好多软件包, 果断开 jail =security = share= 在 4.x 版本被移除了, 注意下 samba 分为 smbd, nmbd, winbindd. 我只用 smbd, 但是跑起来发现光是 smbd 就占用了 1G 的 25%, 15%, 15%, 太耗资源了. 所以这使我必须得用 port 精简功能了. 然后解压 ports tree 的时候死机了, 拔电然后文件系统坏了... 还是 NFS 吧, Need For Speed, 反正我又不用 Windows. 至于权限, -mapall=freebsd 就行 * LED :PROPERTIES: :CUSTOM_ID: led :END: 死机这一教训使我意识到必须得有一个不用网络的方式观察服务器状态, 正常 LED 是常亮的, 但死机也亮着. 先写一个 blink, 就像 Arduino 入门那样. ...太无趣了, 不是吗. 我看 led(4) 的时候发现 morse(6) 有意思, 于是就写了一个用摩斯码打印温度和内存的 rc #+BEGIN_SRC sh #!/bin/sh # PROVIDE: blink # KEYWORD: shutdown . /etc/rc.subr name=blink rcvar=blink_enable blink_enable=${blink_enable:-"NO"} start_cmd="${name}_start &" stop_cmd="morse -l sos > /dev/led/nanopi-r2s\:red\:sys" blink_start() { while true do echo 0 > /dev/led/nanopi-r2s\:red\:sys morse -l "$(sysctl -n hw.temperature.CPU | cut -c 1-2)" > /dev/led/nanopi-r2s\:red\:sys sleep 60 done } load_rc_config $name run_rc_command "$1" #+END_SRC * obhttpd? httpd 其实算是一个比较年轻的软件, [[https://www.openbsd.org/papers/httpd-asiabsdcon2015.pdf][这里]]有关于为什么 OpenBSD 要自己做一个 Web Server 的历史 重载配置: #+BEGIN_SRC sh sudo pkill -HUP obhttpd #+END_SRC 当我弄 [[https://bluemap.bluecolored.de/wiki/webserver/ExternalWebserversFile.html][BlueMap]] 的时候, 发现只有 gzip 压缩文件的时间比原文件新的时候才会加上 =Content-Encoding: gzip= 但是, BlueMap 这种东西只有 .gz 文件, 所以就 404, httpd 也没有手动加 header 的方式. *nginx, 启动!* * [[https://www.mediawiki.org/wiki/Manual:Running_MediaWiki_on_FreeBSD][MediaWiki]]? don't 如果你不想被嵌入式设备糟糕的性能浪费一上午的时间最后得到加载时间大于10秒的网页, 放弃吧... 有足够性能的服务器还可以编译带 SQLite 支持的 port 我想使用 MediaWiki 主要想尝试 MinecraftWiki [[https://minecraft.fandom.com/wiki/Module:Schematic][Schematic Module]] * Avahi 两个都要开啊, 要不然会很慢的! #+BEGIN_EXAMPLE avahi_daemon_enable="YES" avahi_dnsconfd_enable="YES" #+END_EXAMPLE * nginx 由于默认的 nginx autoindex 太难看, 我想用 [[https://github.com/aperezdc/ngx-fancyindex][fancyindex]] 但是默认安装里又没带. 反正得自己编译, 那不如用 ports 编译一个. 其实 apache 的 autoindex 挺好, 还带 icon, 但是 apache 的配置我真的受不了. 之前有一次用 portsnap(8) 解包 ports 结果崩了, 这回用 git, 没事. 默认的 fancyindex 颜色有点丑, 写个 patch 改一下 (能 inline 就不加 CSS) 根本不用看 doc, 直接凭直觉照猫画虎, 先在 =Makefile.extmod= 里面加上 #+BEGIN_SRC makefile HTTP_FANCYINDEX_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-nginx-http-fancyindex-css #+END_SRC 颜色基本上是 aur.archlinux.org, Arch Blue 是[[https://bbs.archlinux.org/viewtopic.php?id=110936][这个帖子]], #39c5bb 懂的都懂. #+BEGIN_CENTER archlinux.org #08c wiki.archlinux.org #0077bb bbs.archlinux.org #07b aur.archlinux.org #07b #+END_CENTER #+BEGIN_SRC diff --- ../ngx-fancyindex-0.5.2/template.h.orig 2021-10-28 19:28:07.000000000 +0000 +++ ../ngx-fancyindex-0.5.2/template.h 2023-08-30 11:36:48.142878000 +0000 @@ -9,9 +9,8 @@ "body,html {" "background:#fff;" -"font-family:\"Bitstream Vera Sans\",\"Lucida Grande\"," -"\"Lucida Sans Unicode\",Lucidux,Verdana,Lucida,sans-serif;" +"font-family:monospace;" "}" "tr:nth-child(even) {" -"background:#f4f4f4;" +"background:#e4eeff;" "}" "th,td {" @@ -21,5 +20,5 @@ "text-align:left;" "font-weight:bold;" -"background:#eee;" +"background:#ecf2f5;" "border-bottom:1px solid #aaa;" "}" @@ -29,8 +28,9 @@ "}" "a {" -"color:#a33;" -"}" -"a:hover {" -"color:#e33;" +"text-decoration:none;" +"color:#1793d1;" +"}" +"a:hover {" +"color:#39c5bb;" "}" "" #+END_SRC 我甚至还可以把 SSL, MAIL, STREAM 的功能通通去掉, 因为我的环境用不到. * ZFS? 之前我只是在唯一的U口上插了一个 32G U盘, 但随着我在服务器上放的东西越来越多并越来越依赖它, 我开始对数据安全担忧: 万一哪天整个U盘坏了呢? 而且这似乎正在发生着, 我已经看到这样的报错了: #+BEGIN_EXAMPLE (da1:umass-sim1:1:0:0): CAM status: CCB request completed with an error (da1:umass-sim1:1:0:0): Retrying command, 1 more tries remain #+END_EXAMPLE 所以我考虑用 ZFS 组个 RAIDz, 这样 3 块 32G U盘可以得到接近 64G 的空间并且允许一个U盘坏掉. 创建存储池等基本操作请看 [[https://docs.freebsd.org/en/books/handbook/zfs/][Chapter 22. The Z File System (ZFS)]] 弄完我就开心地睡觉了, 后台把之前U盘的东西 =rsync= 过来, 寻思这么先进的文件系统不会出什么问题吧, 即使有也能自我修复. 第二天一早醒来, DEGRADED, 一个盘掉了, 查看 dmesg, 又是大量的报错: #+BEGIN_EXAMPLE (da1:umass-sim1:1:0:0): Retrying command, 0 more tries remain (da1:umass-sim1:1:0:0): SYNCHRONIZE CACHE(10). CDB: 35 00 00 00 00 00 00 00 00 00 (da1:umass-sim1:1:0:0): CAM status: CCB request completed with an error (da1:umass-sim1:1:0:0): Error 5, Retries exhausted (da1:umass-sim1:1:0:0): got CAM status 0x44 (da1:umass-sim1:1:0:0): fatal error, failed to attach to device da1 at umass-sim1 bus 1 scbus1 target 0 lun 0 da1: s/n 8355111095836336751 detached (da1:umass-sim1:1:0:0): Periph destroyed #+END_EXAMPLE 嘶~ 不应该呀, 新买的盘. 拔掉尝试修复以及几次重启和重新创建阵列后, 还是过一段时间三个盘中就会有 1~2 个坏的. 因为之前的盘一直没坏, 所以可以排除 USB 集线器的问题, 所以问题就出在 *朗科京东自营旗舰店* 上买的这仨盘. 上 #archlinux-cn-offtopic 问一圈: #+BEGIN_EXAMPLE 18:27 各位, 朗科京东自营旗舰店 的U盘质量怎么样啊, 我买了 3 个, 组 ZFS 坏了俩 ... 18:28 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] > <@matterbridge:nichi.co> [digua] 各位, 朗科京东自营旗舰店 的U盘质量怎么样啊, 我买了 3 个, 组 ZFS 坏了俩 18:28 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] 。。。。。 18:28 [gauge] u 盘还要 zfs 嘛 18:28 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] 你不知道 U 盘用的是最次最次的颗粒吗 18:29 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] 起夜级挑剩下来的给消费级 nvme 挑剩下来的给 sata 硬盘挑剩下来的给 U 盘 18:29 gauge, 用在软路由上( 18:30 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] ?你软路由还 zfs 18:30 [Kimiblock Moe] U 盘不就拿来刷 archiso 嘛 18:30 [Kimiblock Moe] 除此以外还有啥用啊 18:30 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] 我以为 j1900 跑 esxi 和 pve 已经够离谱了 18:31 弄着玩呀 18:31 🍋🙈🐰🙊🍈🌝 18:31 [啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊] 你真要弄的话 建议搞点硬盘盒然后插 nvme ... 18:34 [Jack Smith] > <@matterbridge:nichi.co> [digua] 各位, 朗科京东自营旗舰店 的U盘质量怎么样啊, 我买了 3 个, 组 ZFS 坏了俩 18:34 [Jack Smith] u盘不可靠🤣 ... 18:34 [Jack Smith] > <啥玩意啊 咋回事啊 那咋整啊 大佬帮帮忙啊> ?你软路由还 zfs 18:34 [Jack Smith] 我tf卡btrfs🙈 #+END_EXAMPLE ZFS 这个技术很棒, 但得等我弄到靠谱的盘... 又买了两个海康威视星云固态盘, 只买两个是因为我感觉小处理器可能计算校验和会有压力. 这回速度可以, 3MB/s 大量 IO 任务还是会阻塞, 可以用 =nq= 排个队列. * Upgrade to 14.0 我发现默认安装是带 debug symbol 的, 但对我来说没用, 想取消掉. #+BEGIN_EXAMPLE The following components of FreeBSD seem to be installed: kernel/generic kernel/generic-dbg world/base world/base-dbg The following components of FreeBSD do not seem to be installed: Does this look reasonable (y/n)? n #+END_EXAMPLE [[https://forums.freebsd.org/threads/how-to-remove-debug-components-from-system.57740/#post-329653][How to remove debug components from system]] 给出的方案是 =rm -rf /usr/lib/debug=, 但我也与下面帖子的人有一样的疑问: 是否在别的地方还有 debug 的东西? 我下了 base-dbg.txz 和 kernel-dbg.txz 然后 =tar tvf=, 哦, 只有 =/usr/lib/debug/=. 然后: #+BEGIN_EXAMPLE The following components of FreeBSD seem to be installed: kernel/generic world/base The following components of FreeBSD do not seem to be installed: kernel/generic-dbg world/base-dbg #+END_EXAMPLE * BBR #+BEGIN_SRC sh ftp ftp.freebsd.org tar -C / -zxf src.txz cd /usr/src/sys/arm64/conf mv ROCKCHIP ROCKCHIP-bbr cd /usr/src make buildkernel TARGET_ARCH=aarch64 make installkernel TARGET_ARCH=aarch64 DESTDIR=/root/aarch64 #+END_SRC 在 vbox 里 900 多秒就编译完了 ROCKCHIP-bbr #+BEGIN_SRC #+END_SRC /etc/src.conf #+BEGIN_EXAMPLE KERNCONF=ROCKCHIP-bbr MALLOC_PRODUCTION=yes #+END_EXAMPLE 重启时我心里也没底, 但没发生什么意外. * Ref - [[https://feng.si/posts/2019/06/freebsd-and-risc-v-the-future-of-open-source-iot-ecosystem/][FreeBSD 与 RISC-V: 开源物联网生态系统的未来]] - [[https://lists.freebsd.org/archives/freebsd-arm/2021-June/000149.html][freebsd-arm: FriendlyARM NanoPi R2S board support.]] - [[https://hauweele.net/~gawen/blog/?p=2662][FreeBSD on NanoPi R2S]] 提到网络有时会卡住, 我也遇到了 - 关于 systemd 有个不错的视频: [[https://www.bilibili.com/video/BV1oo4y1x7Nw][【人肉精翻】systemd的悲剧]] [[https://youtu.be/o_AIw9bGogo][YouTube]] - [[https://docs.freebsd.org/en/articles/rc-scripting/][Practical rc.d scripting in BSD]] - [[https://szclsya.me/zh-cn/posts/storage/zfs-setup/][ZFS 入门指北:规划与创建存储池]] - [[https://hostalk.net/posts/tor_bridges_proxy.html][如何优雅地用Tor_下篇]]