mirror.dongdigua.github.io/org/nanopi_freebsd.org

8.6 KiB

在 NanoPi R2S 上运行 FreeBSD

曾经有两个树莓派, 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), 耶!
  • 合上外壳

关于镜像制作

总的来说就是:

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

开始

  • 中国用户第一件事先换源: bjtu FreeBSD 镜像
  • 然后像之前 OpenBSD 一样还是装机必备软件, 因为是服务器所以没几个
pkg install neofetch oksh sudo git fzf frp
  • 改密码, /usr/local/etc/sudoers 不用 doas 因为 persist 选项只在 OpenBSD 上可用
  • 主机名, 路由器配置 DHCP 静态 IP, 本机 /etc/hosts 加入主机名解析
hostname freebsd-r2s
vi /etc/rc.conf

在 fortune 里看到一个不错的 PS1, 弄个新 PS1 换换口味

PS1='(\[$(tput md)\]\t <\w>\[$(tput me)\]) $(echo $?) \[\033[01;31m\]\[\033[00m\] '
  • HZ? 在 Linux 上降低 HZ 是能减少能耗的, 但这里至少温度没降, 先改成 250 吧 /boot/loader.conf
  • 降 CPU 频率是当然能减少能耗的 /etc/sysctl.conf

第一个服务: gopher

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

frpc daemon

frp 这完意好啊, 但是 Debian 搁置了挺长时间也没加入 我作为 RHEL7 入坑 Linux 的用户, 没有体验过 systemd 之前的服务管理, 这里可以体验一把. 本来以为还得学 rc 脚本, 结果把同目录的 frps 改改就行了 别忘了把 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

exec.clean;
exec.start="sh /etc/rc";
exec.stop="sh /etc/rc.shutdown";
mount.devfs;

in-jail

/etc/crontab 取消 save-entropy 和 adjkerntz /etc/rc.conf 进程越少越好, 似乎我不需要 sendmail

sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

microbin

足够 micro, 不需要 jail 终于更新 2.0 了, 虽然没到 quarterly, 但可以 pkg add <url> 安装

Gemini

曾经我的 Gemini 是用 Docker 跑在朋友的服务器上, 但是一出问题调试很费劲. 现在有个稳定的服务器, 就可以本地跑, 省去许多麻烦.

依旧使用 jail

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

then run in 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"

# disable save-entropy and adjkerntz
vi /etc/crontab

/usr/local/etc/gmid.conf:

user "_gmid"

server "freebsd-r2s" {
        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"
}

/etc/periodic/daily/update-git:

#! /bin/sh

cd /dongdigua.github.io
git pull --rebase
python misc/mdlist2gmi.py > posts.gmi
cp -r gmi/docker/cgi .
rm index.gmi
git checkout -- index.gmi

pf

我唯一能控制机器的方式就是 SSH, 使用 pf 可能会有危险. 反正服务器是在内网, 只有少数服务通过转发暴露出去.

samba

弄着个电子垃圾 64G U盘, 想架个 Samba 要安好多软件包, 果断开 jail security = share 在 4.x 版本被移除了, 注意下 samba 分为 smbd, nmbd, winbindd. 我只用 smbd, 但是跑起来发现光是 smbd 就占用了 1G 的 25%, 15%, 15%, 太耗资源了.

所以这使我必须得用 port 精简功能了. 然后解压 ports tree 的时候死机了, 拔电然后文件系统坏了…

还是 NFS 吧, 反正我又不用 Windows. 至于权限, -mapall=freebsd 就行

LED

死机这一教训使我意识到必须得有一个不用网络的方式观察服务器状态, 正常 LED 是常亮的, 但死机也亮着. 先写一个 blink, 就像 Arduino 入门那样.

…太无趣了, 不是吗. 我看 led(4) 的时候发现 morse(6) 有意思, 于是就写了一个用摩斯码打印温度和内存的 rc

#!/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
        tm="$(sysctl -n hw.temperature.CPU | cut -c 1-2) $(($(sysctl -n vm.stats.vm.v_free_count) * $(sysctl -n hw.pagesize) / 1048576))"
        morse -l $tm > /dev/led/nanopi-r2s\:red\:sys
        sleep 60
done
}

load_rc_config $name
run_rc_command "$1"