诗盗·七鹰鸣

《#诗盗#·七鹰鸣》:七鹰鸣十几夜,语纷纷,戮殇兮,应人欲,度顽魂。几夜温酒,家何处?游牧童谣,只许樱花处问。

注解

改编自唐代杜牧的《清明》:

清明时节雨纷纷,路上行人欲断魂。
借问酒家何处有,牧童遥指杏花村。

跟 UMU 一起玩 OpenWRT(入门篇18):更换 opkg 源

问题

默认源在国内访问速度普遍比较慢。

PS: 本篇理论上应该几年前就写的……以前经常用台湾省的网络,没发现,现在补一篇。

解决

  1. 更换清华大学源
1
2
sed -i 's/downloads\.openwrt\.org/mirrors\.tuna\.tsinghua\.edu\.cn\/openwrt/g' /etc/opkg/distfeeds.conf
opkg update
  1. 使用 https
1
2
opkg install libustream-mbedtls
sed -i 's/http:/https:/g' /etc/opkg/distfeeds.conf

相关

如果您想把整个软件源下载到本地,可以参考:https://github.com/UMU618/openwrt-opkg-cache

跟 UMU 一起玩 OpenWRT(入门篇17):卸载 U 盘

需求

在 PC 插入 U 盘/移动硬盘,Windows 会发出令人愉悦的“灯等灯”声,然后 U 盘灯开始牛逼闪闪(如果有灯);安全弹出时,又会发出“的的等”,灯熄灭(有些 U 盘不会灭灯,而是常亮着,不会再闪;移动硬盘一般都会灭灯)。

OpenWRT 这么强大,怎么能不支持?

  • 什么?你说 umount?那 /dev/sda 还能重新挂载呢!那灯还亮着呢!(有些 U 盘弹出后灯常亮,设计好的才会灭灯。)

  • 什么?你说直接拔掉?你赢了!但有时候,稣是在远程操作,要是没人配合拔掉,岂不是要插着耗电?穷人可是交不起电费的……

解决

1
2
3
4
opkg update
opkg install eject

eject /dev/sda

终于安全弹出啦!

注意:弹出后,​/dev/sda 还会存在,但无法再 mount,而且它下面的分区 /dev/sda1 ​等,都会消失。

eject 默认会先后尝试使用 CD-ROM 和 SCSI 命令弹出设备,可以用 -v 参数查看详细流程,一般 U 盘用 -s 参数指定使用 SCSI 命令更为直接。

相关

跟 UMU 一起玩 OpenWRT(入门篇6):挂接 U 盘

在树莓派上编译 go-ipfs

1. 需求

用 PC 当 Server 测试环境,费电!挖出吃灰多年的树莓派 Model B Rev 2 000f,打算用它跑 ipfs!

2. 系统选型

  • 较熟悉的 CentOS、FreeBSD、Ubuntu Server、Windows IoT 的当代主流版本都不支持这款古老的树莓派。

  • ArchLinux 支持,然而稣个人认为 ArchLinux(属于 Linux 中的邪教)不适合当 Server。

  • 尝试刷 OpenWRT,发现即使设置密码,本地控制台也是没密码就能登录。这不太安全,虽然本地就是不安全的,但别的系统可不是这么设计的!

  • 还是官方的 Raspbian Buster Lite 吧!

3. 安装系统

主要参考官方文档:

  • Setup:选个 16GB 的 SD 卡。

  • Installing operating system images:用官方 Raspberry Pi Imager 工具把系统镜像刷到 SD 卡。

  • 接 HDMI 显示,通电。首次启动,系统会自动对 SD 卡的分区进行扩容,使第二个分区扩满未分配空间。

4. 配置系统

通过 sudo raspi-config 做基本配置:

  • 进“本地化”把默认语言 en_GB.UTF-8 去掉,勾选 en_US.UTF-8。

  • 键盘布局改为通用 105 键(国际)美国布局(默认的英国布局下按 | 会变 ~)。

  • 时区改为当地。

  • 改机器名(如果您有多个树莓派,不改会重名),稣将之改为 rp1b。

  • 改 pi 用户的密码。

  • 开启 SSH,插上网线或者 USB 无线网卡,就可以从别处远程登录它了。

5. 配置国内 apt 源

1
2
3
4
5
6
7
sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
# 增加阿里云源
echo 'deb https://mirrors.aliyun.com/raspbian/raspbian/ buster main non-free contrib
deb-src https://mirrors.aliyun.com/raspbian/raspbian/ buster main non-free contrib' | sudo tee /etc/apt/sources.list.d/aliyun.list
# 增加清华大学源
echo 'deb https://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib
deb-src https://mirrors.tuna.tsinghua.edu.cn/raspbian/raspbian/ buster main non-free contrib' | sudo tee /etc/apt/sources.list.d/tsinghua.list

6. 安装 Go 编译器

打算直接在树莓派上编译,所以要先在树莓派上安装编译环境。不过不要通过 sudo apt install golang 安装,因为截至今天(2020-03-28),这命令安装的是 1.11.6 版,这对 go-ipfs 项目来说太低了。

golang 官网下载 ARMv6 安装包,目前最新版本是 1.14.1

压缩包里是有一个 go 文件夹的,所以只要解压到 /usr/local/ 下即可。

1
2
3
4
5
6
# aria2 比 wget 强大
# sudo apt install aria2
aria2c https://dl.google.com/go/go1.14.1.linux-armv6l.tar.gz
tar -C /usr/local -xzf go1.14.1.linux-armv6l.tar.gz
sudo ln -s /usr/local/go/bin/go /usr/bin/go
sudo ln -s /usr/local/go/bin/gofmt /usr/bin/gofmt

7. 编译项目

1
2
3
git clone https://github.com/ipfs/go-ipfs
cd go-ipfs
make build

有很多依赖库需要下载,开始漫长等待……如果代码都下载完,则 make build 的输出为:

1
2
3
4
5
go version go1.14.1 linux/arm
bin/check_go_version 1.14.1
plugin/loader/preload.sh > plugin/loader/preload.go
go fmt plugin/loader/preload.go >/dev/null
go build "-asmflags=all='-trimpath='" "-gcflags=all='-trimpath='" -ldflags="-X "github.com/ipfs/go-ipfs".CurrentCommit=3561de074-dirty" -o "cmd/ipfs/ipfs" "github.com/ipfs/go-ipfs/cmd/ipfs"

最后一行会卡很久!em……用高性能机器来交叉编译才是正确的方式!

8. 在 macOS 上编译树莓派程序

树莓派的 CPU 架构是 armv6l,所以用以下命令编译:

1
CGO_ENABLED=0 GOOS=linux GOARCH=arm GOARM=6 make build

在 MBP15 上编译快很多!(前面纯属折腾!)编完复制到树莓派:

1
scp ./cmd/ipfs/ipfs pi@rp1b:/home/pi/

在树莓派上测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
pi@rp1b:~ $ uname -a
Linux rp1b 4.19.97+ #1294 Thu Jan 30 13:10:54 GMT 2020 armv6l GNU/Linux

pi@rp1b:~ $ ./ipfs version
ipfs version 0.5.0-dev

pi@rp1b:~ $ ./ipfs init
initializing IPFS node at /home/pi/.ipfs
generating 2048-bit RSA keypair...

pi@rp1b:~ $ ./ipfs daemon
Initializing daemon...
go-ipfs version: 0.5.0-dev-3561de074
Repo version: 9
System version: arm/linux
Golang version: go1.14
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/192.168.1.91/tcp/4001
Swarm listening on /ip6/240e:379:254c:9d00:969d:e453:9448:1efb/tcp/4001
Swarm listening on /ip6/::1/tcp/4001
Swarm listening on /p2p-circuit
Swarm announcing /ip4/110.87.124.125/tcp/21551
Swarm announcing /ip4/127.0.0.1/tcp/4001
Swarm announcing /ip4/192.168.1.91/tcp/4001
Swarm announcing /ip6/240e:379:254c:9d00:969d:e453:9448:1efb/tcp/4001
Swarm announcing /ip6/::1/tcp/4001
API server listening on /ip4/127.0.0.1/tcp/5001
WebUI: http://127.0.0.1:5001/webui
Gateway (readonly) server listening on /ip4/127.0.0.1/tcp/8080
Daemon is ready

学习 Rust【4】调用 libc

问题

Rust中如何使用linux的原生api? - 知乎

概述

很多语言调用 C 语言写的模块来弥补自己某些不足。Rust 当然也可以调用 C 语言开发的模块,不过这是不安全的。

代码

  1. 在 Cargo.toml 中加入依赖库:
1
2
[dependencies]
libc = "0.2.68"
  1. Rust 示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
use libc;

fn main() {
let pid = unsafe { libc::fork() };
if pid < 0 {
eprintln!("错误!");
} else if pid == 0 {
println!("子进程空间");
} else {
println!("父进程空间, 子进程 pid 为 {}", pid);
}
}
  1. macOS 测试通过。

家用 WiFi 方案

一、问题

我房子太大,一个无线路由器覆盖不了怎么办? - 知乎

二、经验

  • 1000 多平方米的办公室够大吧?一个小米路由器 Pro 放在中间,办公区域覆盖完全,仅厕所信号较弱。

  • 100 平占地面积,三层楼(无电梯、楼梯洞很大),在二楼放一个 79 块的路由器,日常无痛使用 4 年以上。

WiFi 信号是通过漫反射传播的,不是什么“穿墙”!所以重点不是“太大”,而是钢筋混凝土墙的格局。

震惊!WiFi 信号在空旷的地方轻松覆盖你家十栋大别墅的面积!

真正能靠透射、衍射穿透的是玻璃、木头、塑料之类。5.8G 信号是厘米波,能穿透的厚度也不大,稍微厚点的木门都不行,只能从门下的缝钻进去。您可以在房间里做开关门试验,结论是:穿墙太难了,撞墙倒是会反弹……

5G WiFi 就是 5.8GHz,为和 5G 蜂窝网络区分开,特意采用 5.8G。

三、廉价而靠谱的方案

主路由 + AP 方案!中间当然是千兆网线连接,如果您没有布网,那就跳过,看后面分析为什么其它方案都不靠谱。

1. 硬件

本方案需要的硬件是 N 个刷 OpenWRT 的路由器:

  • 主路由器,自然就是放在多媒体箱里,接光猫或入户网线。

  • AP,其实也是个 OpenWRT 路由器,只是关闭 DHCP 服务,配置和主路由器同网段,然后用 LAN 口接主路由器的 LAN 口。

AP 可以有多个。比如稣家,是长方形结构,距离多媒体箱最远的主卧关上门基本零信号,只能在主卧放一个 AP,然后全家都覆盖完整。

2. 软件

  • 只开 5.8G,尽量不开 2.4G。稣家的“只支持 2.4G 的终端设备”全部集中在大厅区域,所以只有主路由器开启 2.4G。如果开多个 2.4G,注意信道隔离。每个 5.8G 信号都用同样的 SSID,以实现漫游。

  • AP 的 IP 地址可以使用静态,也可以使用 DHCP client,然后在主路由器上绑定地址。AP 有固定 IP 方便登录管理。

  • 如果 AP 需要 IPv6 地址,再创建一个 lan6 接口,物理 Interface 选择 br-lan(和 lan 接口一样,但不能勾选 Bridge interfaces),协议是 DHCPv6 client。

3. 测试

有人说,这样的方案缺乏 AC 管理,会导致终端设备可能不会自动切换信号。稣特地拿出祖传的 iPad2,从大厅漫步到主卧,神奇的事情发生了——居然可以自动切换 5.8G WiFi 信号!终端能不能自动切换,这显然是驱动程序决定的,虽然 iPad2 已经很老,但系统有更新到 iOS 9.3.5……

实在找不到一个不能自动切换信号的设备!好,测试结束。方案完美上线。

4. 为什么这个方案可行?

  • OpenWRT 说它确实可行!

  • 移动中使用设备的机会不高。您不会在家里跑来跑去,同时费劲地使用设备,有可能您根本就不需要自动漫游。

  • 您不会在家里的每个角落使用 WiFi,所以有很多地方并不需要有信号,比如洗手台、走廊、厨房。

四、AC+AP 方案?

买不起!什么?你说某些乐射 AC 很便宜?不好意思,很便宜也不是免费,还耗电!做人,难,做穷人,难上难!

AC+AP 方案的原理:AC 会自动发现并管理 AP,设定 AP 的 RSSI 阈值,将信号不稳定的设备【踢下线】,迫使终端设备重新连接信号最强的 AP,实现 AP 的自动切换。

请注意【踢下线】三个字,用 AC,在终端移动时,一样会断线。既然都会断,那就没有本质的区别,让终端自己选择,体验并没有比较差!

所谓 AC 管理,无非是促使那些不支持 802.11k-2008 的设备重新连接而已。如果您有这样的设备,建议还是换掉他们,或者固定他们,古董啊,可别让它们逃跑了!

五、Mesh 方案?

贵!Mesh 的主节点就是个 AC,绕回 AC+AP 方案。有网线的话,为什么不用 AP 方案?根本就是一样的嘛!

六、电力线?

懒得喷……

七、参考

在 iOS 上通过 802.11k、802.11r 和 802.11v 实现 Wi-Fi 网络漫游

chsh -s zsh

标题是个坑

不要在 Ubuntu 上运行这条命令!都说 CentOS 比 Ubuntu 稳定,总算见识到具体案例!

没有对比就没有伤害

CentOS

1
2
3
4
5
6
$ cat /etc/centos-release
CentOS Linux release 7.7.1908 (Core)

$ chsh -s zsh
Changing shell for root.
chsh: shell must be a full path name

可见,机智的 CentOS,早就料到这个运维事故!

Ubuntu

1
2
3
4
5
6
7
8
9
10
11
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04.4 LTS"

$ chsh -s zsh
chsh: Warning: zsh does not exist

$ cat /etc/passwd
root:x:0:0:root:/root:zsh

SSH 到 Ubuntu Server 上,运行 chsh -s zshexit 后就再也无法登录……

如果您要远程做这个试验,记得 exitchsh -s /bin/zsh,或者 vi 手动纠正 /etc/passwd。

macOS 研究经验【2】:简单的破解

1. Beyond Compare

BC 试用版过期,思考 3 秒钟:稣太穷,买不起!

macOS 和 iOS 一样,App 都是独立存储,找出安装信息保存在哪个文件应该很容易。

确实如此!居然只要两步:

1
2
cd ~/Library/Application Support/Beyond Compare
rm registry.dat

2. X-NG

由于子公司、分公司众多,稣的服务器列表里有好多个项,想备份这个列表,发现还不是很容易!

ServerProfileManager

首先,找到 ~/Library/Application Support/X-NG/-local-config.json,但这个文件里只有当前选择的项。

然后,就看代码吧!Swift 写的,应该还好:

1
2
let defaults = UserDefaults.standard
let keys = [

根据代码线索找到:

1
defaults read ~/Library/Preferences/com.yuzhou.X-NG.plist

哇~全部出来了!

macOS 研究经验【1】:关于 APFS Container

起因

最近 MBP15 的硬盘空间告急,打开“磁盘工具”查看,却发现居然有两个“宗卷”!从没认真研究过 macOS 磁盘管理的稣疑惑了。

“磁盘工具”默认“仅显示宗卷”,“显示所有设备”后是这样的:

disk0

disk1

disk1s5

disk1s1

分析

肉眼观测 disk1 是放在 disk0 里的……嗯,想起容器!但 GUI 有时候是会骗人的,用 diskutil 来检查一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *251.0 GB disk0
1: EFI EFI 314.6 MB disk0s1
2: Apple_APFS Container disk1 250.7 GB disk0s2

/dev/disk1 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +250.7 GB disk1
Physical Store disk0s2
1: APFS Volume Macintosh HD - 数据 209.2 GB disk1s1
2: APFS Volume Preboot 79.9 MB disk1s2
3: APFS Volume Recovery 526.6 MB disk1s3
4: APFS Volume VM 8.6 GB disk1s4
5: APFS Volume Macintosh HD 11.2 GB disk1s5

以上可知,只有 disk0 是物理的,disk1 是由 disk0s2 这个分区虚拟出来的。

下面查看两者详细信息对比:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
$ diskutil info /dev/disk0
Device Identifier: disk0
Device Node: /dev/disk0
Whole: Yes
Part of Whole: disk0
Device / Media Name: APPLE SSD AP0256M

Volume Name: Not applicable (no file system)
Mounted: Not applicable (no file system)
File System: None

Content (IOContent): GUID_partition_scheme
OS Can Be Installed: No
Media Type: Generic
Protocol: PCI-Express
SMART Status: Verified

Disk Size: 251.0 GB (251000193024 Bytes) (exactly 490234752 512-Byte-Units)
Device Block Size: 4096 Bytes

Read-Only Media: No
Read-Only Volume: Not applicable (no file system)

Device Location: Internal
Removable Media: Fixed

Solid State: Yes
Virtual: No
Hardware AES Support: Yes

$ diskutil info /dev/disk1
Device Identifier: disk1
Device Node: /dev/disk1
Whole: Yes
Part of Whole: disk1
Device / Media Name: APPLE SSD AP0256M

Volume Name: Not applicable (no file system)
Mounted: Not applicable (no file system)
File System: None

Content (IOContent): EF57347C-0000-11AA-AA11-00306543ECAC
OS Can Be Installed: No
Media Type: Generic
Protocol: PCI-Express
SMART Status: Verified
Disk / Partition UUID: 1DDCC569-2632-4CD5-88E7-66E2BBE745C9

Disk Size: 250.7 GB (250685575168 Bytes) (exactly 489620264 512-Byte-Units)
Device Block Size: 4096 Bytes

Read-Only Media: No
Read-Only Volume: Not applicable (no file system)

Device Location: Internal
Removable Media: Fixed

Solid State: Yes
Virtual: Yes
Hardware AES Support: Yes

This disk is an APFS Container. APFS Information:
APFS Physical Store: disk0s2
Fusion Drive: No

两者 Virtual 属性的不同,说明前面的猜测是对的。

理论求证

搜到如下参考:

推理正确!