blob: fd76b1aa284b759fd893723219982e362da7a530 (
plain)
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
+++
title = "极客死亡计划书 III"
subtitle = "Are we out of the woods yet?"
tags = [
"自由软件",
"写作",
]
categories = "极客死亡计划书"
date = 2026-01-24T23:36:43
slug = "site-report-3"
draft = false
toc = true
toot = "https://akk.eltr.ac/objects/50eeb7dc-da11-476a-8d72-4bb8836a17d2"
url = "/posts/site-report-3/"
+++
嗯?这个系列好像快一年没更新了?<!--more-->
没错,上一次发布《极客死亡计划书》,还是在 2025 年的三月底,现在 2026 年的一月份已经快要结束了。[上一篇计划书](/posts/极客死亡计划书-II)写了自己对写博客这件事情的一些思考,以及公开写作和私有笔记的区别,还介绍了「卡片」分区,不过这个分区已经被弃用了。
这次的计划书会更偏技术,反映了我最近关于「技术自由」的思考。
## Hello, Fediverse!
Fediverse 是 Federation(联邦)和 Universe(宇宙)的混成词,可以理解为一个巨大的分布式社交网络。所有人都可以建立自己的实例服务器,或者加入一个现有的服务器,就能和整个联邦宇宙网络中的居民互动。这些服务器运行的通常是支持 ActivityPub 协议的自由软件,常见的是 Mastodon、Misskey 和 Pleroma,以及各种分支。联邦宇宙一般用来代替大科技公司提供的网络服务,比如 Twitter、Instagram 和 YouTube 等。
在我看来,联邦宇宙解决了因数据和社交网络无法迁移而造成的被大科技公司「锁住」的局面,譬如,现代中国人很难离开微信的原因并非是微信的软件质量极佳,而是因为工作需要、已有的聊天记录和联系人无法迁移到其他软件,以及「身边人都用微信」。联邦宇宙提供了这样一种解决方案:我们不需要在同一个平台上,只要我们使用的平台支持同一种通信协议,我们就能够发信和互动。这其实和电子邮件的逻辑如出一辙:A 使用的可能是 Outlook,B 使用的是 Migadu,C 使用的是自己搭建的邮件服务器,A、B、C 的邮件服务器由不同的商家提供,底层的软件实现也不一样,甚至不在同一个国家和地区,但只要他们知道了对方的邮箱地址,就能够相互通信,因为几乎所有邮件服务都使用 SMTP 协议。如果某天 Microsoft 干出了什么令 A 作呕的事情(*这样的事情难道还不够多吗?*),觉得继续用 Outlook 是十分令人反胃的事情,A 可以随时走人,只要告知其他人他的新邮箱地址就好。如果使用自己的域名,只需要修改 DNS 记录,不需要更换地址。
联邦宇宙也是如此,几乎所有联邦宇宙实例都运行在开源的自由软件上,也几乎都支持数据导出。如果你看不惯某个软件,你可以随时换到安装了另一个软件的服务器上;如果你不太喜欢某个服务器的风气或者管理者的行事风格,你也可以带着你的粉丝和关注者列表走人(粉丝甚至不需要做任何操作,只需要一些简单的账号迁移步骤,他们就会自动关注你的新账号)。由于软件是开源的,如果找不到自己喜欢的软件,也可以自己 Fork——我目前使用的 Akkoma 就是 Pleroma 的一个 Fork。==这也是开源软件的好处之一,你永远不需要妥协,遇到不爽就大喊一声「Fork it!」[^1],把软件变成你认为它应该成为的样子。== 广告?售卖个人数据?追踪用户?违禁词?算法?不好意思,没听说过。人们在大公司网络上呆久了,尽管也时常讽刺、嘲笑和表达忧虑,但往往忘记了自己还有选择。
*等等,你不是要讲博客的计划吗?为什么开篇讲了这么多联邦宇宙相关的内容?*
~~别急,我能圆回来的。~~ 2024 年年底我写过一篇题为《[我与社交媒体](/essays/我与社交媒体/)》的文章,当时的我认为我可以用博客来代替社交媒体,因为博客完全满足了「发表想法,然后收到回应」的需求,而社交媒体往往是更短的信息载体,更喜欢用长文本持续记录的我,当时并不看好这种方式。而且,在当时的我看来,社交媒体和主流互联网上更容易爆发争吵,而独立博客之间所组成的「网络」反而在*大多数时候*显得风平浪静。
使用了快一个月的联邦宇宙之后,我甚至搭建了自己的 Akkoma 实例(名为 [Eucalyptus](https://akk.eltr.ac/),欢迎来访),我显然已经投入了不少金钱和精力在上面了。那么,我对社交媒体的想法有改变吗?
很遗憾,没有。我仍然认为博客等长文本媒介是更好的表达平台,不过,在联邦宇宙上和网友互动的过程中,我有想清楚一些事情。原本我在正式加入联邦宇宙,重回社交媒体时,以为联邦宇宙会比由大公司网络组成的主流互联网要更和谐,但实际上并非如此:我仍然能见到不少的争吵,读到一些偏激且令人难以理解的观点,我仍然会因为浏览社交媒体而感到焦虑(这和我在上文提到的那篇文章中所写的,社交媒体对心理健康的影响相关)。显然,社交媒体的问题并没有因为其使用的技术的倾向而被修正,它在形式上就是有缺陷的(或者,一个更偏激的观点:人类就是有缺陷的,一群完全不同的人聚在一起就是会吵架),这与是否去中心化、是否开源、是否自由无关。
不过,我之所以选择继续留在联邦宇宙上,是因为我逐渐开始区分「智识交流」和「社交交往」。
## 文字的目的可能比内容本身更重要
约莫半个月前,在联邦宇宙上看到一条帖子,我认为发帖人有些不公正且不准确地对我喜欢的一个播客主播表达了批评,我感到了些许气愤。我本来想反驳,但使用社交媒体的几年经验阻止了我。我开始反思:我为什么会生气?
我当然知道,我应该接受并倾听自己不赞同的观点,避免陷入到信息茧房里。然而,我并没有真的倾听到对方,我只是看到了一个单薄的、没有支撑和阐述的「结论」——是的,这就是问题!人们在社交媒体这样的短文本媒介上,总是更喜欢给结论,而不在乎其他能够支撑论点的必要内容。我相信,如果对方给出详细的批评理由,我能够更好地理解对方,即便不能完全赞同,我也能看到对方的出发点。*我不赞同你的观点,但我理解你为什么会那样想。* 我意识到自己的愤怒,很多时候源于不理解——*怎么会有人能做出这种事情?我真的搞不懂你!?* 如果不理解某人的行为逻辑,在其他人眼里看来,就容易被解读为「蠢」甚至「坏」。
显然,短文本并不是承载阐述、论述和论据的好媒介。阐述是指描述清楚观点本身,社交媒体上简单的一句「我觉得 Markdown 很蠢」背后表达的可能是「Markdown 的标准不统一,在声称支持 Markdown 的平台上使用这种语法不总是能得到相同的结果,并且不支持下划线……」,但过多的留白使得发言者很容易被想象为一个*不懂得纯文本之美的麻瓜*,收到「你听起来像是只会用 Word 文档写东西的人」这类冷嘲热讽。
可怕的是,这种倾向于不阐述、不论述、不提供论据的表达方式,已经从社交媒体蔓延到现实生活中了。我的一个朋友跟我聊起佛教与精神分析的共同之处,他只是抛出了一些支离破碎的结论,并没有给出阐述让我理解,也没有提供论述和论据,这让我在得到碎片化的信息之后产生了「这像是一群学者没事做了硬搞出来的课题」的印象。我提出我的想法之后,他也没有进一步解释自己的观点(或者说他读到的结论),而是有些冷嘲热讽地说「这两个东西就是有联系的呀,**我**觉得很有意义啊」。我感到不舒服,直接走开了,没有继续对话。显然,这是不愉快的——为什么有深度的知识和观点给人带来的是这种不悦呢?
听《独树不成林》的主播树老师时常批评,如今从事哲学的学者总是喜欢用一些令大众难以理解词汇,或许是为了提高哲学的门槛,又或许是为了将「高尚」的哲学和「低俗」的大众文化区分开来。这点在译者上尤为明显,他们会把原文本身就非常通俗的文本翻译得文绉绉的。我发现,许多人会把理解的门槛故意抬高,以此来凸显自己的孤傲。前文提到的那个朋友,曾经跟我说过,他觉得能理解的人能理解,不能理解的人就是不会理解,不需要费心解释。然而,他从一开始就没能把想法表达得足够清晰,==他把表达的责任转化为了听众的理解责任,以使得自己不需要清晰地组织词句,只是用有些决定论的想法定义那些不能够理解的人==。在《[阈限思维](/library/2025/阈限思维/)》这本书里,作者提到了一个观点,很多想法、事实、观点在一群人眼里是「显而易见」的,在另一些人眼里则不是,这是由我们的经验塑造的。假设所有人都和自己拥有相似的经验,同样的思维方式,把这种差异解读为「理解的无能」,何尝不是一种愚昧?很可惜,这样的思想无处不在。
我无意改变任何人,我只是意识到,我不应该以「智识交流」的要求规范「社会交往」。如果有些人就是希望在人群中说一些大家都听不懂的话,或者给人一些神神叨叨的建议,以此来塑造具有神秘感的人设,那就随他去吧!反正我不会和这类人做朋友。在社交媒体上也是如此,直接抛出结论是高效的,也能迅速收获和自己处于同一个「显而易见」群体的其他人的支持,而那些与自己经验和认知差异巨大的人,可以通通归类为「蠢」和「坏」,以此保持自洽。虽然我讨厌这种下意识的反应,但人的确应该保留**一定程度**的信息茧房,因为和与自身经验和认知差异巨大的人相处是非常费心费力的,人不应该**每时每刻**都暴露在自己不认同的观点里。
总而言之,现在我把社交媒体看作「社会交往」的一个媒介,把博客看作「智识交流」的一个媒介。我享受社交媒体给我带来的社交满足感,并且包容不理性、缺乏逻辑连贯性的言论,而且,那些观点即便没有充分的阐述,也能给我带来一些思考。我仍然坚信,真正的思考应该发生在写作当中,博客等长文本媒介是不可或缺的。
---
## 自由与代价
我曾经非常在意网页的加载速度,所以在不久之前,博客的图片等静态资源都是储存在又拍云上的,由他们的 CDN 提供加速服务。这是个国内的云服务商,所以要求使用备案域名。为此,我把早年前注册的一个 `.cn` 域名(出于某些考量,我就不在这里给出完整的域名了)提交了备案,并一直用它作为图床的加速域名。我对又拍云的印象其实很好,如果你选择使用国内服务,我会推荐他们。不过,我在今年一月决定注销备案并且弃用 `.cn` 域名。
我对智识交流的一个要求是「自由表达」和「尽可能少的审查」(审查是不可能没有的,就算没有制度上的审查,也会有舆论审查和自我审查),所以我一直没有把博客使用的域名 `geedea.pro` 提交备案。最近我意识到,即便我使用一个单独的备案域名,这个域名也与我是强绑定的。再者,使用 `.cn` 域名没有办法隐去真实姓名和联系信息,无法保障隐私。表达了我的想法之后,联邦宇宙上也有人建议我停止使用 `.cn` 域名。权衡之下,我注册了 `eltr.ac` 这个域名,并用它代替旧的 `.cn` 域名。
截止目前,我已经注销了旧域名备案,并完全停用了旧域名。现在我只有两个域名:`geedea.pro` 和 `eltr.ac`,前者用于我的博客,后者作为我在互联网上的身份标识(我的联邦宇宙账号是 `@eltrac@eltr.ac`,我的个人主页是 [www.eltr.ac](https://www.eltr.ac)),之所以做这样的区分,也是出于区分「智识交流」和「社会交往」的考量。我把极客死亡计划视作我的作品,而不是我自己在互联网上的化身。
我也有在**避免**选择美国的服务商。一方面,我在 Hacker News 和 New Yorker 上读到了不少新闻报道,美国似乎把大科技公司变成了某种政治武器[^2],我并不希望美国的政治局势对我产生任何影响,我也希望通过自己作为消费者的微薄之力,通过自己的选择改变市场需求;另一方面,我更看好欧盟地区对隐私和用户数据的保护(GDPR[^3]),我希望尽可能把服务都迁往欧盟地区,或者对隐私保护更加强硬的瑞士。
我先是把自己的邮件服务迁往了 [Migadu](https://migadu.com/),一家瑞士的邮件服务商。之后…… 事情就变得复杂起来了。我只能说,自由的代价并不小。
首先是最难割舍的 Cloudflare。人称互联网大善人的 Cloudflare 位于美国旧金山,他们提供了十分全面的服务(DNS 解析、DDoS 防护、CDN、Serverless、CI/CD……),而且大部分服务都有完全足够个人用户使用的免费额度。这也使得互联网变得越来越中心化,不久前 Cloudflare 乱用 `unwrap()` 使得服务故障,大半个互联网都瘫痪了好几个小时。即便现在我想要迁出 Cloudflare,我也很难找到一个替代品,我甚至把又拍云的储存桶迁移到了 Cloudflare R2,因为实在是太好用了……
果然,免费的才是最贵的。其中一个代价就是我变成了麻瓜,我把 Cloudflare 当成了「网络安全的保障」,而不去思考抵御网络层攻击的原理。DNS 解析很容易替代,但是网络层的清洗、缓存,以及一个免费好用的 S3 储存服务,是需要花很多时间和精力才能找到替代方案的。如果不想思考和折腾,包括我在内的大多数人可能都会选择使用免费又省心的方案。
不过,Cloudflare 的 R2 储存桶有提供将数据存放在欧盟地区的选项,所以…… 也算是能用吧。我打算在未来半年点一点网络安全的技能,逐渐脱离对 Cloudflare 的依赖。
注销了备案,自然也就弃用了国内服务器。我在选购 VPS 的时候,看过了 CloudCone、RackNerds、Vultr 等著名的 VPS 提供商,在最后看上了 Contabo,一家位于德国的云服务提供商,他们以非常低廉的价格出售位于欧盟地区的 VPS。*4 核 8 GB 只要不到四美元一个月,确定不是疯了吗?* 据说 Contabo 经常超售,但从 TrustPilot 的评价和我目前的体验来看,其实并不差。我主要用这台服务器来跑 Akkoma(基于 Pleroma 这个资源占用很低的联邦宇宙软件)、Forgejo(用 Go 编写的轻量 GitHub 替代)和一些自托管 Web 应用,除了偶尔需要编译软件,对 CPU 的需求其实并不高,所以也还好。
值得一谈的是 Forgejo,我还安装配置了 Forgejo Runner,可以理解为 GitHub Actions 的替代品。目前 [www.eltr.ac](https://www.eltr.ac) 就是用 Forgejo Runner 构建,并使用 `rsync` 部署到 VPS 上,算是实现了自有的 CI/CD(持续集成/持续部署),和使用 Vercel 和 Cloudflare Pages 一样,只要推送更新到[远程仓库](https://src.eltr.ac/eltrac/eltrac),就会触发工作流,自动构建和部署网站。所以,Cloudflare Pages/Workers 我已经找到了替代品,未来也会把这个博客从 Cloudflare Workers 上迁移走。
目前我还没有找到很好的位于欧盟地区的 S3 兼容对象储存服务。Scaleway 似乎不错,但是不支持 PayPal 付款,而我现在找到的支持 PayPal 的服务都有些超预算。所以,我暂时还不知道如何替代 Cloudflare R2。
所以这就是自由的代价之一吧:一切都要自己学习,一切都要自己理解,一切都要自己负责。对我而言,这其实非常令人兴奋。
## 本地优先与源码优先
将服务逐渐迁移至欧盟地区,除了远离纷扰,还有一个重要的原因是数据安全。GDPR 法案提供了严格的用户数据保护策略。此外,我也逐渐意识到自己需要将数据掌握在自己手上,而不是任由他们留在某个平台。拥有数据的一个先决条件是:数据有副本在本地,最好是本地数据优先,并且数据应该以开放的格式储存,例如纯文本、JSON 和 XML 等。
同样地,这是对麻瓜非常不友好的要求,大多数人其实没有管理数据的能力,或者没有办法离开数据封闭的平台或软件。短期内这样的软件选择会带来便捷,但长期来看,会被平台困住,留在平台上并不是因为软件质量,而是因为数据无法迁移或者迁移太困难。我在审视我博客的架构时,也发现了不少数据隐患——我的 Webmention 后端由 [webmention.io](https://webmention.io) 提供,所有的 Webmention 都在他们的数据库里存放着;我的评论系统使用 Giscus,数据存放在 GitHub 上。如果哪天 webmention.io 这个免费服务倒闭,或者 GitHub 发病,我的数据不都没了?
Webmention 和 ActivityPub 一样,是一个 W3C 标准,用于在万维网上相互提及。理想情况下,在一篇文章里提及一篇位于其他网站上的文章链接,目标网站就会收到通知,可能还会把提及此文的其他万维网页面链接显示在页面中。不过实际上,这个过程涉及到发送 HTTP 请求,要实现自动发送 Webmention 的话,还是有点麻烦的,不过接收 Webmention 就很简单了,只要在 `<head>` 标签里声明接收 Webmention 的端点,指向可以接收 Webmention 的 POST 请求的服务器后端就好了。
```html
<link rel="webmention" href="https://webmention.io/www.geedea.pro/webmention" />
```
由于数据存放在服务器上,对于没有服务器的静态网站而言,一般的做法是:每次用户访问一个页面,网页都会通过 JavaScript 从 webmention.io 抓取这个页面的 Webmention 数据,如果有,就显示在页面中(有多少人喜欢了这篇文章、回应了这篇文章的链接……)。动态地加载数据其实很不优雅:首先,我崇尚「客户端极简主义」,需要在用户的设备上运行的代码应该越少越好;其次,我尽管没有特别在乎加载速度,但我关注网页的渲染速度和性能,如果用户已经加载了我的网站内容,却还要等待来自另一个网域的内容加载,我觉得是不合理的;再者,我使用的是 Hugo,一个静态网站生成器,我应该尽可能发挥 SSG 的优势,让数据在构建过程中就被写入页面中。
我的解决方案是,用 CI/CD 每隔半个小时从 webmention.io 的 API 抓取一次全站的 Webmention 并储存为 JSON 文件,Hugo 直接使用这个 JSON 文件里存储的数据渲染 Webmention。如此一来,数据就以开放格式储存在了本地,准确来说是代码仓库中,还享受了 Git 提供的版本控制能力。
有了这个先例,我又继续开发了 Hugo 渲染 JSON 和 XML 格式数据的能力。现在你可以访问[林卷](/linkroll)页面,你能看到直接从我的 RSS 阅读器中导出的 OPML 订阅文件被渲染为列表,以代替手动维护的链接列表;你还能看到同样通过 CI/CD 抓取到本地的来自 Linkding 的书签列表。尽管这些并非重要数据,但有意识地存储、使用和开发自己的数据,就是一种态度。
不过,还是那句话,自由是有代价的…… 接下来我不得不面对一个非常难啃的瓜——评论系统。
除了数据隐患,使用 Giscus 的体验并不美妙,虽然很方便,但 Giscus 的表单和评论展示都是在一个 `<iframe>` 内的,这使得数据交换和自定义 CSS 变得很麻烦。比如,以下是我获取评论数的代码。
```javascript
giscusIframe.addEventListener('load', () => {
// receive message from giscus iframe
window.addEventListener('message', function(event) {
if (event.origin !== 'https://giscus.app') return;
const giscusData = event.data;
if (giscusData.giscus?.discussion) {
const discussion = giscusData.giscus.discussion;
const totalComments = (discussion.totalCommentCount || 0) + (discussion.totalReplyCount || 0);
// set comment count
commentCountEl.textContent = totalComments.toString();
// if no discussion found, set to 0
} else commentCountEl.textContent = '0';
});
});
```
HTML 结构也完全不受我控制,这使得开发 Giscus 的 CSS 样式变得很麻烦。由于这个 `<iframe>` 在 `giscus.app` 上而非本地,再加上每次加载还需要用 GitHub API 获取 Discussion 数据,加载需要很长时间,我不得不在 JavaScript 层面做额外的处理,使 Giscus 延迟加载,来保证页面速度。
无论怎么说,Giscus 都很不好伺候,而且还要求访客有一个 GitHub 账号,这不太合理。
我在选择自托管评论系统的时候,看过了主流的 Waline、Twikoo 和 Artalk,总觉得没有中意的。一方面,我不想维护一个单独的用户认证系统,我讨厌不必要的注册和登录,我也不希望我的访客忍受这一点。可是,另一方面,如果没有用户认证,就很难避免垃圾信息,而且人人都可以伪装成另一个人进行评论,毕竟要获取到某个人的邮箱地址并不是什么难事。*等等…… 邮箱地址?*
发信是很难伪装的,如果有 OpenPGP 签名的加持,邮件发送者的身份就可以确认了。电子邮件是开放的协议,人人都可以使用,信息交换的格式也是开放的纯文本,非常容易保存、迁移和管理。所以,有没有办法开发一种基于电子邮件的评论系统呢?
我在这里先留一个引子,关于评论系统的变更,大概会留到《极客死亡计划书 IV》来写了。感谢你读到这里,希望你也不要放弃自由和真理。回见!
[^1]: 关联「Fuck it!」(去他妈的);Fork 本身在这里是「创建软件分支」的含义。
[^2]: 参见:[Every data centre is a U.S. military base](https://www.policyalternatives.ca/news-research/every-data-centre-is-a-u-s-military-base/),还有一些别的,我没有找到链接。
[^3]: General Data Protection Regulation,通用数据保护条例
|