二次踩坑去中心化博客Plume

最近又重新折腾了一次Plume,记录一下。

Plume是一个去中心化的博客引擎。意思是说,在一个Plume站点上不仅可以写文章,还可以跨站看到其他Plume站点上的文章(本站推流/跨站推流)。因为是基于activitypub,也支持各种基于activitypub的分布式社交网络,例如mastodon、pleroma等,在那些站点上会表现为一个正常的远程用户,可以被关注,发布的文章会表现为一个正常的嘟文/状态,赞转评也会同样变为文章页面的赞转评。

发布文章流程:仪表盘 -> 创建新博客 -> 创建文章。

plume2mastodon

(Mastodon上是标题+链接)

plume2pleroma

(Pleroma是直接展示全文)

看起来很美好,实际折腾的时候发现有很多坑。(如果只是想了解Plume是什么,可以不用再往下看)

第一次折腾Plume是一年前了,倒也因此发现了gitea这个好东西。最早知道是因为看到有人向Gargron吐槽Mastodon限制500字,Gargron说写长文可以用Plume。于是我就去搞Plume了。

跑起来还算顺利,但是很快发现和开了白名单模式的Mastodon实例并不能正常交互,最多单方面可见。经过print大法(虽然我其实完全不会rust)+群里问Plume的主要开发者(正好他们用的Matrix,就很舒服)+去github问Gargron,终于搞明白了,是因为Plume的发的请求没有签名,所以拉不到完整的信息。另外还有个不严重但是会干扰排查的问题是,Plume不支持任何bot账号,所以拉取到的远程用户如果是bot("type":"Service")就会报错。总之,因为对我需要的场景来说问题太致命了,就没实际投入使用,到此弃坑。

过了一年,因为又觉得有写博客的需求,想着当时他们说要修http sign过了这么久也该修好了,决定二次踩坑。这次的一个大坑是编译Plume。具体遇到的问题和这个issue完全一样,我就不重复了,核心就是报

error: failed to run custom build command for `rocket v0.4.10` 

Error: Rocket (core) requires a more recent version of rustc.
  Installed version: 1.53.0 (2021-03-30)
  Minimum required:  1.54.0-nightly (2021-05-18)
	

如果删掉/修改 rust-toolchain 使用更高版本的rustc,Plum本身的代码则又各种编译错误。

这事折腾了我很久(rust编译起来是真的慢),git clone了一份rocket,checkout到v0.4.6,发现用rust-toolchain里指定的 nightly-2021-03-25 编译是完全ok的。这才注意到Cargo.toml里面明明写的 rocket = "0.4.6" 它为什么要去尝试编译0.4.10呢,是不是吃饱了没事干。使用cargo tree检查了依赖链也完全看不出为什么非要用0.4.10(完全不会rust的我当然是现场谷歌的)。甚至试着把Cargo.toml里的rocket全部改成用本地的rocket,也还是有问题。

后来突发奇想加大胆尝试,把rocket = "0.4.6" 改为 rocket = "=0.4.6",终于神奇地解决了。完整的过程是,改成 <=0.4.6, 发现莫名其妙用了很低的版本导致编译错误,准备再改成 >=0.4.6,<=0.4.6 ,诶那要不试试直接写=,居然可以!

然而我没在任何文档里看到过有这种写法(反正我完全不会rust)。

解决编译过程中的其他插曲:

  • 注意 git.joinplu.me 是被墙了的,墙内如果要在本地拉取代码需要代理(我是因为编译太慢+连服务器有点卡所以后来本地搞了),我用的proxychains来给终端命令加代理。我猜墙的逻辑是,听说plume是一个社交网站,墙掉!plume的网址是什么?哦,joinplu.me,好,把相关网站全部墙掉!fuck gfw

  • 尝试用docker,还是比较顺利的,但是仍然交互有问题,没法改代码用print大法查问题,加上不想放弃之前的那点数据,把数据从postgresql迁移到postgresql的docker也是个麻烦事,放弃。

  • 尝试用writefreely替代Plume,发现这完全是个残疾品,直接没有赞转评,放弃。

终于解决编译问题后,跑起来了,又是一通print大法查错,发现一年前的那两个问题根本还是老样子啊。这一年除了把版本号从0.4.0升到0.6.0/0.6.1-dev外到底干了啥(摔)。

不认识bot账号先不管,没有签名这个是致命问题必须解决。搜issue发现作者表示0.6.0没有signature Host header但主线上的最新版本已经有了(那我应该算运气不错?),那这是怎么回事呢。仔细看了一下代码和搜commit发现,原来这个有了只是部分请求有了,拉取 inbox 的那个请求仍然没有签名(摔)。

至少问题比较清晰了。第一反应还是比较守序善良的,反正已经有可以抄的代码了,就模仿已有的签名给这个请求也加上签名呗,搞完还可以给Plume提个pr。发现还是有点麻烦以后就混乱邪恶起来了,反正我的目的是尽快能用起来,涉及到的Mastodon实例也是我自己的,改这边麻烦那就改那边呗,没签名也没关系,直接放行。

signature

第一个版本是给Plume那边加了个Signature header,内容是一段“密码”,Mastodon那边取request.headers['Signature'] 如果等于这段密码就不需要后面的检查直接放行。觉得有点过于离谱了又搞了第二个版本,不再魔改Plume,Mastodon那边如果request.ip 是 127.0.0.1 就直接放行。

总之能用了。现在可以在这边舒服地写小作文了。