<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Rebel Zhang 的博客</title>
        <link>https://rebel1725.codeberg.page/blog/zh/</link>
        <description>Recent content on Rebel Zhang 的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-CN</language>
        <managingEditor>rebel1725@tilde.club (Rebel Zhang)</managingEditor>
        <webMaster>rebel1725@tilde.club (Rebel Zhang)</webMaster>
        <lastBuildDate>Wed, 10 Jun 2026 13:57:10 +0800</lastBuildDate><atom:link href="https://rebel1725.codeberg.page/blog/zh/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>我的 Eepsite 已重新上线</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/my-eepsite-is-back-online/</link>
            <pubDate>Wed, 10 Jun 2026 13:57:10 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/my-eepsite-is-back-online/</guid>
            <description>&lt;p&gt;我以前把我的 eepsite 托管在家里的服务器上，但大约两周前，出于安全考虑，我停止了托管。现在我找到了一种在 &lt;a class=&#34;link&#34; href=&#34;https://vern.cc/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;~vern&lt;/a&gt; 上托管它的方法，所以它又重新上线了。&lt;/p&gt;&#xA;&lt;p&gt;欢迎访问 &lt;a class=&#34;link&#34; href=&#34;http://rebel1725.i2p/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;rebel1725.i2p&lt;/a&gt;。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>使用 Net Qube 将流量路由到 SOCKS 代理</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/route-traffics-to-a-socks-proxy-using-a-net-qube/</link>
            <pubDate>Fri, 05 Jun 2026 00:08:03 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/route-traffics-to-a-socks-proxy-using-a-net-qube/</guid>
            <description>&lt;p&gt;&lt;strong&gt;免责声明：我是在一切“似乎”都正常工作之后才写下这份指南的。对于流量泄漏或其他意外问题，我不承担责任。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;本文说明如何使用 net qube，通过特定 qube 将流量路由到 SOCKS 代理。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第-1-步安装所需软件包&#34;&gt;第 1 步：安装所需软件包&#xA;&lt;/h2&gt;&lt;p&gt;你需要 &lt;code&gt;screen&lt;/code&gt; 和 &lt;code&gt;redsocks&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;# apt install screen redsocks&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;第-2-步创建一个-net-qube&#34;&gt;第 2 步：创建一个 net qube&#xA;&lt;/h2&gt;&lt;p&gt;请在你的 Qube Manager 中完成这一步。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第-3-步配置-redsocks&#34;&gt;第 3 步：配置 &lt;code&gt;redsocks&lt;/code&gt;&#xA;&lt;/h2&gt;&lt;p&gt;在新的 net qube 中创建 &lt;code&gt;/rw/config/redsocks.conf&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;base {&#xA;log_info = on;&#xA;log_debug = on;&#xA;log = stderr;&#xA;daemon = on;&#xA;redirector = iptables;&#xA;}&#xA;&#xA;redsocks {&#xA;local_ip = 0.0.0.0;&#xA;local_port = 12345;&#xA;&#xA;ip = &amp;lt;changeme&amp;gt;;&#xA;port = &amp;lt;changeme&amp;gt;;&#xA;type = &amp;lt;changeme&amp;gt;;&#xA;login = &amp;#34;&amp;lt;changeme&amp;gt;&amp;#34;;&#xA;password = &amp;#34;&amp;lt;changeme&amp;gt;&amp;#34;;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;第-4-步配置自动启动&#34;&gt;第 4 步：配置自动启动&#xA;&lt;/h2&gt;&lt;p&gt;将以下内容添加到新 net qube 中的 &lt;code&gt;/rw/config/rc.local&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;systemctl stop redsocks&#xA;&#xA;nft add table ip nat 2&amp;gt;/dev/null || true&#xA;nft &amp;#39;add chain ip nat prerouting { type nat hook prerouting priority -100; policy accept; }&amp;#39; 2&amp;gt;/dev/null || true&#xA;&#xA;nft add set ip nat bypass4 &amp;#39;{ type ipv4_addr; flags interval; elements = { &#xA;0.0.0.0/8, &#xA;10.0.0.0/8, &#xA;100.64.0.0/10, &#xA;127.0.0.0/8, &#xA;169.254.0.0/16, &#xA;172.16.0.0/12, &#xA;192.168.0.0/16, &#xA;224.0.0.0/4, &#xA;240.0.0.0/4 &#xA;} }&amp;#39; 2&amp;gt;/dev/null || true&#xA;&#xA;nft add rule ip nat prerouting ip daddr @bypass4 accept&#xA;nft add rule ip nat prerouting meta l4proto tcp redirect to :12345&#xA;nft add rule ip qubes custom-input iifgroup 2 tcp dport 12345 ct state new,established,related counter accept&#xA;&#xA;cp /rw/config/redsocks.conf /etc/redsocks.conf&#xA;systemctl start redsocks&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;第-5-步重启并配置&#34;&gt;第 5 步：重启并配置&#xA;&lt;/h2&gt;&lt;p&gt;重启该 net qube，然后把你希望通过这个代理转发流量的那些 qube 的 net qube 设置为这个 net qube。&lt;/p&gt;&#xA;&lt;p&gt;一切就绪，祝你使用愉快 :-)&lt;/p&gt;&#xA;&lt;p&gt;问题：有时 &lt;code&gt;redsocks&lt;/code&gt; 会收到 &lt;code&gt;SIGABRT&lt;/code&gt; 信号并崩溃。解决方法：运行 &lt;code&gt;systemctl start redsocks&lt;/code&gt; 将其重新启动。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>挑战-响应中的一个严重安全问题</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/a-serious-security-issue-of-challenge-response/</link>
            <pubDate>Thu, 28 May 2026 00:47:56 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/a-serious-security-issue-of-challenge-response/</guid>
            <description>&lt;p&gt;挑战-响应的一种做法是，把一个随机字符串（&lt;code&gt;nonce&lt;/code&gt;）发送给需要验证身份的人，并让对方使用自己的私钥对该字符串进行签名。然而，这会带来一个非常严重的安全问题。&lt;/p&gt;&#xA;&lt;p&gt;例如，Alice 想要验证 Bob。但 Mallory 插在他们中间。于是会发生下面的事情：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Alice 将挑战发送给被 Mallory 冒充的 &amp;lsquo;Bob&amp;rsquo;。&lt;/li&gt;&#xA;&lt;li&gt;Mallory 冒充 Alice，将该挑战转发给 Bob，并请求返回响应。&lt;/li&gt;&#xA;&lt;li&gt;Bob 把响应发回，然后 Mallory 再把响应转发回去。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;在这种情况下，Mallory 已经成功向 Alice 冒充了 Bob，现在就可以进行 MITM 攻击了。&lt;/p&gt;&#xA;&lt;p&gt;解决办法不是只把随机字符串当作挑战。一个好的挑战至少应包含以下内容：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;验证者和被验证者的信任锚的标识信息（例如 OpenPGP 指纹）；&lt;/li&gt;&#xA;&lt;li&gt;通道的标识信息（例如，面对面验证时的地点；在 XMPP 上验证时的 JID 以及 OMEMO 指纹；在 Matrix 上验证时双方的 Matrix ID 和房间）；&lt;/li&gt;&#xA;&lt;li&gt;时间戳；&lt;/li&gt;&#xA;&lt;li&gt;nonce，也就是随机字符串。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;换句话说，挑战应当把验证者和被验证者的身份、已认证的通道或会话上下文、用于保证新鲜度的时间戳，以及 nonce 绑定在一起。验证者必须将已签名的身份声明与已认证的传输元数据进行比对。&lt;/p&gt;&#xA;&lt;p&gt;在这种情况下，Mallory 就必须篡改通道上下文来欺骗 Bob（否则 Bob 会立刻识别出这个有问题的挑战并拒绝响应），而这样一来，由于挑战已被篡改，Alice 在验证时就会发现响应无效。&lt;/p&gt;&#xA;&lt;p&gt;为了获得更强的安全性，请彼此相互验证。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>使用 GDB 和 Iaito/Radare2 的逆向工程示例</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/a-reverse-engineering-example-with-gdb-and-iaito-radare2/</link>
            <pubDate>Wed, 27 May 2026 23:56:34 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/a-reverse-engineering-example-with-gdb-and-iaito-radare2/</guid>
            <description>&lt;p&gt;过去几周里，我一直在学习逆向工程，并且&lt;a class=&#34;link&#34; href=&#34;../a-brief-introduction-into-reverse-engineering/&#34; &gt;写了一篇博客文章&lt;/a&gt;来分享我的第一次体验。最近，我又深入了一些，正在用静态分析和动态分析相结合的方式解决一个 CTF 题目，而我觉得这正是进一步解释逆向工程的一个很好的例子。&lt;/p&gt;&#xA;&lt;p&gt;我之前原本打算写一篇关于使用 GDB 进行动态分析的文章。不过，我发现这个题目同样非常适合用来解释 GDB。为了解出这个题目，我还会使用另一个工具，&lt;strong&gt;iaito&lt;/strong&gt;，它是 radare2 的图形前端。&lt;/p&gt;&#xA;&lt;h2 id=&#34;题目&#34;&gt;题目&#xA;&lt;/h2&gt;&lt;p&gt;cIMG 可以说是一种图像格式，用来在终端中表示由不同颜色字符组成的图像。它由以下部分构成：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;魔数，也就是 &lt;code&gt;cIMG&lt;/code&gt;；&lt;/li&gt;&#xA;&lt;li&gt;版本号；&lt;/li&gt;&#xA;&lt;li&gt;宽度和高度；&lt;/li&gt;&#xA;&lt;li&gt;数据，每个像素都包含 R、G、B 和 ASCII 字符。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;这个题目要求你向一个可执行程序提供一个 cIMG 文件，只有当 cIMG 满足某些条件时，它才会给出 flag。&lt;/p&gt;&#xA;&lt;h2 id=&#34;源代码&#34;&gt;源代码&#xA;&lt;/h2&gt;&lt;p&gt;在这里获取题目的&lt;a class=&#34;link&#34; href=&#34;https://raw.githubusercontent.com/pwncollege/intro-to-cybersecurity-dojo/refs/heads/main/reverse-engineering/cimg-framebuffer-mini-c/_0/cimg.c&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;source&lt;/a&gt;。这份源代码看起来使用的是 BSD 2-Clause 许可证。&lt;/p&gt;&#xA;&lt;p&gt;使用 GCC 编译它：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ gcc -O3 challenge.c -o challenge&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;打开 Python 并创建一个示例 cIMG 文件：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ python3&#xA;Python 3.13.5 (Jun 25 2025, 18:55:22) [GCC 14.2.0] on linux&#xA;Type &amp;#34;help&amp;#34;, &amp;#34;copyright&amp;#34;, &amp;#34;credits&amp;#34; or &amp;#34;license&amp;#34; for more information.&#xA;&amp;gt;&amp;gt;&amp;gt; with open(&amp;#34;example.cimg&amp;#34;, &amp;#34;wb&amp;#34;) as file:&#xA;...     file.write(b&amp;#34;cIMG\x02\0\x0a\x0a&amp;#34;)&#xA;...     file.write(b&amp;#34;\x50&amp;#34;*(10*10*4))&#xA;...     &#xA;8&#xA;400&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用题目的二进制程序打开这个示例 cIMG 文件：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;user@learnaarch64asm:~$ ./challenge ./example.cimg &#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个文件会输出内容，但不会给出 flag。&lt;/p&gt;&#xA;&lt;h2 id=&#34;静态分析&#34;&gt;静态分析&#xA;&lt;/h2&gt;&lt;p&gt;我们需要构造一个能 &lt;em&gt;给出 flag&lt;/em&gt; 的 cIMG 文件。先做静态分析。&lt;/p&gt;&#xA;&lt;p&gt;在 iaito 中打开文件。执行 &lt;code&gt;aaa&lt;/code&gt; 分析，并打开 &lt;code&gt;main&lt;/code&gt; 函数的图形视图。你会得到：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260527_001_417726312315916099.png&#34;&#xA;&#x9;width=&#34;3532&#34;&#xA;&#x9;height=&#34;5056&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;main 函数的图形&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;69&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;167px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们可以看到在 &lt;code&gt;0x00000cac&lt;/code&gt; 处读取文件头，在 &lt;code&gt;0x00000cc4&lt;/code&gt; 处检查魔数，在 &lt;code&gt;0x00000cd0&lt;/code&gt; 处检查版本号，在 &lt;code&gt;0x00000ce0&lt;/code&gt; 处读取宽度和高度。然后它使用 &lt;code&gt;malloc&lt;/code&gt; 为图像数据分配一块内存，并把数据读入其中。&lt;/p&gt;&#xA;&lt;p&gt;魔数是 &lt;code&gt;cIMG&lt;/code&gt;，换成十六进制就是 &lt;code&gt;63 49 4d 47&lt;/code&gt;；版本号是一个 32 位小端整数；高度和宽度都是 8 位整数。&lt;/p&gt;&#xA;&lt;h2 id=&#34;flag-条件&#34;&gt;flag 条件&#xA;&lt;/h2&gt;&lt;p&gt;我们直接看函数结尾。显然，&lt;code&gt;sym.win&lt;/code&gt; 是会给出 flag 的函数。它在 &lt;code&gt;0x00000e8c&lt;/code&gt; 被调用，而这一步是在 &lt;code&gt;0x00000e58&lt;/code&gt; 处的一次检查之后执行的。这项检查要求 &lt;code&gt;w19&lt;/code&gt; 不能为零。&lt;/p&gt;&#xA;&lt;h2 id=&#34;篡改控制流&#34;&gt;篡改控制流&#xA;&lt;/h2&gt;&lt;p&gt;该启动 GDB 了。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ gdb --args ./challenge ./example.cimg &#xA;GNU gdb (Debian 16.3-1) 16.3&#xA;Copyright (C) 2024 Free Software Foundation, Inc.&#xA;License GPLv3+ or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;&#xA;This is free software: you are free to change and redistribute it.&#xA;There is NO WARRANTY, to the extent permitted by law.&#xA;Type &amp;#34;show copying&amp;#34; and &amp;#34;show warranty&amp;#34; for details.&#xA;This GDB was configured as &amp;#34;aarch64-linux-gnu&amp;#34;.&#xA;Type &amp;#34;show configuration&amp;#34; for configuration details.&#xA;For bug reporting instructions, please see:&#xA;&amp;lt;https://www.gnu.org/software/gdb/bugs/&amp;gt;.&#xA;Find the GDB manual and other documentation resources online at:&#xA;    &amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.&#xA;&#xA;For help, type &amp;#34;help&amp;#34;.&#xA;Type &amp;#34;apropos word&amp;#34; to search for commands related to &amp;#34;word&amp;#34;...&#xA;Reading symbols from ./challenge...&#xA;(No debugging symbols found in ./challenge)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 &lt;code&gt;main&lt;/code&gt; 函数处打断点并启动程序：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *main&#xA;Breakpoint 1 at 0xc44&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db enabled]&#xA;Using host libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;#34;.&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa0c44 in main ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们注意到 GDB 的数据地址有一个 &lt;code&gt;0xaaaaaaaa0000&lt;/code&gt; 的偏移。&lt;/p&gt;&#xA;&lt;p&gt;在 flag 条件检查之前打断点，然后继续执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *0x0000aaaaaaaa0e58&#xA;Breakpoint 2 at 0xaaaaaaaa0e58&#xA;(gdb) continue&#xA;Continuing.&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;&#xA;Breakpoint 2, 0x0000aaaaaaaa0e58 in main ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改寄存器 &lt;code&gt;w19&lt;/code&gt; 的内容并继续执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) set $w19 = 1&#xA;(gdb) continue&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后这个可执行程序就会给出 flag。至此任务完成，祝你有美好的一天 :-p&lt;/p&gt;&#xA;&lt;p&gt;开玩笑的。如果我们真的这样结束这个题目，逆向工程的乐趣就没了。让我们继续深入。&lt;/p&gt;&#xA;&lt;h2 id=&#34;数据检查&#34;&gt;数据检查&#xA;&lt;/h2&gt;&lt;p&gt;回到 iaito。点击图中的 &lt;code&gt;w19&lt;/code&gt;。这会在图里的所有指令中高亮该寄存器。向前回溯图形，寻找线索。&lt;/p&gt;&#xA;&lt;p&gt;我们可以在图中看到一些对 &lt;code&gt;sym.imp.memcmp&lt;/code&gt; 的调用。&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;memcmp&lt;/code&gt; 是 C 标准库中的一个函数，声明在 &lt;code&gt;&amp;lt;string.h&amp;gt;&lt;/code&gt; 中，它会逐字节比较两块内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;int memcmp(const void *ptr1, const void *ptr2, size_t n);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ptr1&lt;/code&gt; 和 &lt;code&gt;ptr2&lt;/code&gt; 分别指向那两块内存，而 &lt;code&gt;n&lt;/code&gt; 指定要比较的字节数。如果两块内存完全相同，该函数返回 &lt;code&gt;0&lt;/code&gt;；否则返回一个非零值。&lt;/p&gt;&#xA;&lt;p&gt;这里有四次 &lt;code&gt;memcmp&lt;/code&gt; 调用。每次调用后面都跟着 &lt;code&gt;cmp w0, 0&lt;/code&gt;。除了第一次调用之外，&lt;code&gt;cmp&lt;/code&gt; 后面还有 &lt;code&gt;cset w0, eq&lt;/code&gt; 和 &lt;code&gt;and w19, w19, w0&lt;/code&gt;。我们可以得出结论：如果 &lt;code&gt;memcmp&lt;/code&gt; 发现差异，&lt;code&gt;w19&lt;/code&gt; 就会被清零，因为那时 &lt;code&gt;w0&lt;/code&gt; 会变成零。因此我们猜测，需要让四对内存块完全相同。&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;x0&lt;/code&gt; 和 &lt;code&gt;x1&lt;/code&gt; 是要比较的两个地址。&lt;code&gt;x2&lt;/code&gt; 包含大小；&lt;code&gt;mov x2, 0x18&lt;/code&gt; 告诉我们大小是 24 字节。&lt;/p&gt;&#xA;&lt;p&gt;再次打开 GDB，并在第一次 &lt;code&gt;memcmp&lt;/code&gt; 之前检查内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *0x0000aaaaaaaa0e78&#xA;Breakpoint 1 at 0xaaaaaaaa0e78&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1].&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;PPPPPPPPPP&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa0e78 in main ()&#xA;(gdb) info registers x0 x1&#xA;x0             0xaaaaaaac12a0      187649984565920&#xA;x1             0xaaaaaaac00c0      187649984561344&#xA;(gdb) x/24xb $x0&#xA;0xaaaaaaac12a0: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x30&#xA;0xaaaaaaac12a8: 0x38    0x30    0x3b    0x30    0x38    0x30    0x3b    0x30&#xA;0xaaaaaaac12b0: 0x38    0x30    0x6d    0x50    0x1b    0x5b    0x30    0x6d&#xA;(gdb) x/24xb $x1&#xA;0xaaaaaaac00c0 &amp;lt;desired_output&amp;gt;:        0x1b    0x5b    0x33    0x38    0x3b   0x32     0x3b    0x32&#xA;0xaaaaaaac00c8 &amp;lt;desired_output+8&amp;gt;:      0x33    0x31    0x3b    0x30    0x31   0x37     0x3b    0x31&#xA;0xaaaaaaac00d0 &amp;lt;desired_output+16&amp;gt;:     0x33    0x30    0x6d    0x63    0x1b   0x5b     0x30    0x6d&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;随机字节。我看不出它们是什么意思。&lt;/p&gt;&#xA;&lt;p&gt;回到 iaito。第一块内存是从 &lt;code&gt;x22&lt;/code&gt; 载入的，而 &lt;code&gt;x22&lt;/code&gt; 又是从地址 &lt;code&gt;var_48h&lt;/code&gt; 载入的。&lt;code&gt;afv&lt;/code&gt; 告诉我们它距离 &lt;code&gt;sp&lt;/code&gt; 是 &lt;code&gt;0x48&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000e70]&amp;gt; afv&#xA;arg signed int argc @ x0&#xA;arg char ** s @ x1&#xA;var int64_t var_50h @ sp+0x0&#xA;var int64_t var_50h_2 @ sp+0x8&#xA;var int64_t var_10h @ sp+0x10&#xA;var int64_t var_10h_2 @ sp+0x18&#xA;var int64_t var_20h @ sp+0x20&#xA;var int64_t var_20h_2 @ sp+0x28&#xA;var void * buf @ sp+0x38&#xA;var int64_t var_3ch @ sp+0x3c&#xA;var int64_t var_3eh @ sp+0x3e&#xA;var int64_t var_3fh @ sp+0x3f&#xA;var int64_t var_40h @ sp+0x40&#xA;var int64_t var_48h @ sp+0x48&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;重新启动 GDB，并在 &lt;code&gt;main&lt;/code&gt; 被调用后跳过函数序言：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *main&#xA;Breakpoint 1 at 0xaaaaaaaa0c44&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1].&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa0c44 in main ()&#xA;(gdb) si&#xA;0x0000aaaaaaaa0c48 in main ()&#xA;(gdb) si&#xA;0x0000aaaaaaaa0c4c in main ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;查看栈指针的值并设置一个观察点：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) info registers sp&#xA;sp             0xfffffffff290      0xfffffffff290&#xA;(gdb) watch *(long long *)0xfffffffff2d8&#xA;Hardware watchpoint 2: *(long long *)0xfffffffff2d8&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;继续执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-(gdb)&#34; data-lang=&#34;(gdb)&#34;&gt;Continuing.&#xA;&#xA;Hardware watchpoint 2: *(long long *)0xfffffffff2d8&#xA;&#xA;Old value = 281474840286680&#xA;New value = 0&#xA;0x0000aaaaaaaa0c5c in main ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 iaito 中定位这个地址。我们可以看到，在 &lt;code&gt;0x00000c58&lt;/code&gt;（也就是 &lt;code&gt;0x00000c5c&lt;/code&gt; 前一条指令）处，&lt;code&gt;var_48h&lt;/code&gt; 通过一个 &lt;code&gt;str&lt;/code&gt; 被清零了。&lt;/p&gt;&#xA;&lt;p&gt;继续往下，看看这个变量是在什么地方被设置的：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) continue&#xA;Continuing.&#xA;&#xA;Hardware watchpoint 2: *(long long *)0xfffffffff2d8&#xA;&#xA;Old value = 0&#xA;New value = 187649984565920&#xA;0x0000aaaaaaaa1358 in initialize_framebuffer ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们看到一个我们还没探索过的新函数：&lt;code&gt;initialize_framebuffer&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;在 iaito 中打开这个函数：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260527_002_13426986448128896865.png&#34;&#xA;&#x9;width=&#34;1775&#34;&#xA;&#x9;height=&#34;1384&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;initialize\_framebuffer 函数的图形&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;128&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;307px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们可以看到，&lt;code&gt;0x00001354&lt;/code&gt; 处的一条指令把 &lt;code&gt;malloc&lt;/code&gt; 分配出来的内存地址写入了变量。不过它被表示为 &lt;code&gt;[x22, 0x10]&lt;/code&gt;。我们来检查一下 &lt;code&gt;x22&lt;/code&gt; 的内容：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) info registers $x22&#xA;x22            0xfffffffff2c8      281474976707272&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;0xfffffffff2c8 + 0x10 = 0xfffffffff2d8&lt;/code&gt;。这正好就是 &lt;code&gt;var_48h&lt;/code&gt; 的地址。&lt;/p&gt;&#xA;&lt;p&gt;此外，传给 &lt;code&gt;malloc&lt;/code&gt; 的大小也很有意思。它是通过把偏移 6 和 7 处的值相乘，再把结果乘以 &lt;code&gt;w1&lt;/code&gt; 得到的，而 &lt;code&gt;w1&lt;/code&gt; 是 &lt;code&gt;0x18&lt;/code&gt;（24），最后再加上 &lt;code&gt;x0&lt;/code&gt;，即 1。&lt;/p&gt;&#xA;&lt;p&gt;我们也来查看这些偏移处的值：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) x/1xb 0xfffffffff2ce&#xA;0xfffffffff2ce: 0x0a&#xA;(gdb) x/1xb 0xfffffffff2cf&#xA;0xfffffffff2cf: 0x0a&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;两个都是 10。它们看起来就是我们之前指定的图像宽度和高度。让我们通过设置硬件观察点来验证一下。由于 AArch64 需要对齐，我们把硬件观察点设在 &lt;code&gt;0xfffffffff2cc&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) watch *(unsigned int *)0xfffffffff2cc&#xA;Hardware watchpoint 1: *(unsigned int *)0xfffffffff2cc&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;跳过 GNU C Library 的触发：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-Hardware&#34; data-lang=&#34;Hardware&#34;&gt;&#xA;Old value = 0&#xA;New value = 65535&#xA;0x0000fffff7fccd08 in ?? () from /lib/ld-linux-aarch64.so.1&#xA;(gdb) continue&#xA;Continuing.&#xA;&#xA;Hardware watchpoint 1: *(unsigned int *)0xfffffffff2cc&#xA;&#xA;Old value = 65535&#xA;New value = 0&#xA;0x0000fffff7fd5668 in ?? () from /lib/ld-linux-aarch64.so.1&#xA;(gdb) continue&#xA;Continuing.&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1&amp;#34;]&#xA;&#xA;Hardware watchpoint 1: *(unsigned int *)0xfffffffff2cc&#xA;&#xA;Old value = 0&#xA;New value = 65535&#xA;0x0000fffff7fcc3a4 in ?? () from /lib/ld-linux-aarch64.so.1&#xA;(gdb) continue&#xA;Continuing.&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里我们看到内存在 &lt;code&gt;0x00000c54&lt;/code&gt; 处被清零了：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Hardware watchpoint 1: *(unsigned int *)0xfffffffff2cc&#xA;&#xA;Old value = 65535&#xA;New value = 0&#xA;0x0000aaaaaaaa0c58 in main ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们看到一个 &lt;code&gt;stp xzr, xzr, [buf]&lt;/code&gt;。从上面的 &lt;code&gt;afv&lt;/code&gt; 我们知道 &lt;code&gt;buf&lt;/code&gt; 距离栈指针是 &lt;code&gt;0x38&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;在 &lt;code&gt;0x00000cb8&lt;/code&gt; 处，我们可以看到一个从 &lt;code&gt;buf&lt;/code&gt; 读取的 &lt;code&gt;ldr&lt;/code&gt;，然后是魔数检查。&lt;/p&gt;&#xA;&lt;p&gt;在 &lt;code&gt;0x00000c9c&lt;/code&gt; 处，我们可以看到一些有意思的内容：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;0x00000c9c      add      x21,    sp,     0x38&#xA;0x00000ca0      mov      x2,     8                          ; size_t nbyte&#xA;0x00000ca4      mov      x1,     x21                        ; void *buf&#xA;0x00000ca8      mov      w0,     0&#xA;0x00000cac      bl       sym.imp.read                       ; ssize_t read(int fildes, void *buf, size_t nbyte)&#xA;; ssize_t read(0, 0x0000000000000000, 0x00000000)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;因此我们已经确认，这些偏移处的两个值就是宽度和高度。&lt;/p&gt;&#xA;&lt;p&gt;回到 iaito 和 GDB 中的 &lt;code&gt;initialize_framebuffer&lt;/code&gt; 函数。设置一个观察点并检查内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *0xaaaaaaaa1354&#xA;Breakpoint 1 at 0xaaaaaaaa1354&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1].&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa1354 in initialize_framebuffer ()&#xA;(gdb) info registers x0&#xA;x0             0xaaaaaaac12a0      187649984565920&#xA;(gdb) watch *(char *)0xaaaaaaac12a0&#xA;Hardware watchpoint 2: *(char *)0xaaaaaaac12a0&#xA;(gdb) continue&#xA;Continuing.&#xA;&#xA;Hardware watchpoint 2: *(char *)0xaaaaaaac12a0&#xA;&#xA;Old value = 0 &amp;#39;\000&amp;#39;&#xA;New value = 27 &amp;#39;\033&amp;#39;&#xA;0x0000aaaaaaaa13bc in initialize_framebuffer ()&#xA;(gdb) x/24xb 0xaaaaaaac12a0&#xA;0xaaaaaaac12a0: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x32&#xA;0xaaaaaaac12a8: 0x35    0x35    0x3b    0x32    0x35    0x35    0x3b    0x32&#xA;0xaaaaaaac12b0: 0x00    0x00    0x00    0x00    0x00    0x00    0x00    0x00&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;把它和上面的数据对比一下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) x/24xb $x0&#xA;0xaaaaaaac12a0: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x30&#xA;0xaaaaaaac12a8: 0x38    0x30    0x3b    0x30    0x38    0x30    0x3b    0x30&#xA;0xaaaaaaac12b0: 0x38    0x30    0x6d    0x50    0x1b    0x5b    0x30    0x6d&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;0xaaaaaaac12a7&lt;/code&gt; 是第一个不同的字节。我们可以对它设置观察点：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) watch *(char *)0xaaaaaaac12a7&#xA;Hardware watchpoint 3: *(char *)0xaaaaaaac12a7&#xA;(gdb) continue&#xA;Continuing.&#xA;&#xA;Hardware watchpoint 3: *(char *)0xaaaaaaac12a7&#xA;&#xA;Old value = 50 &amp;#39;2&amp;#39;&#xA;New value = 48 &amp;#39;0&amp;#39;&#xA;0x0000aaaaaaaa128c in display ()&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;出现了一个新的函数需要探索。在 iaito 中打开它。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260527_003_2825852626928846418.png&#34;&#xA;&#x9;width=&#34;1129&#34;&#xA;&#x9;height=&#34;2426&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;initialize\_framebuffer 函数的图形&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;46&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;111px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们可以看到，数据变化发生在 &lt;code&gt;0x00001288&lt;/code&gt;，是一条 &lt;code&gt;stp&lt;/code&gt; 指令。&lt;code&gt;0x0000128c&lt;/code&gt; 处的 &lt;code&gt;str&lt;/code&gt; 指令也很有意思；我们来看看这里的内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) x/24xb 0xaaaaaaac12a0&#xA;0xaaaaaaac12a0: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x30&#xA;0xaaaaaaac12a8: 0x38    0x30    0x3b    0x30    0x38    0x30    0x3b    0x30&#xA;0xaaaaaaac12b0: 0x35    0x35    0x6d    0x20    0x1b    0x5b    0x30    0x6d&#xA;(gdb) si&#xA;0x0000aaaaaaaa1290 in display ()&#xA;(gdb) x/24xb 0xaaaaaaac12a0&#xA;0xaaaaaaac12a0: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x30&#xA;0xaaaaaaac12a8: 0x38    0x30    0x3b    0x30    0x38    0x30    0x3b    0x30&#xA;0xaaaaaaac12b0: 0x38    0x30    0x6d    0x50    0x1b    0x5b    0x30    0x6d&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从 &lt;code&gt;0xaaaaaaac12b0&lt;/code&gt; 开始的 8 字节块已经被 &lt;code&gt;str&lt;/code&gt; 指令改写了。寄存器说明了一切：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) info registers x2&#xA;x2             0xaaaaaaac12a0      187649984565920&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们不必太在意 &lt;code&gt;x2&lt;/code&gt;。重点关注 &lt;code&gt;x4&lt;/code&gt;、&lt;code&gt;x5&lt;/code&gt; 和 &lt;code&gt;x1&lt;/code&gt;。在 &lt;code&gt;0x00001268&lt;/code&gt; 和 &lt;code&gt;0x00001270&lt;/code&gt; 处，我们看到一个非常重要的寄存器 &lt;code&gt;x25&lt;/code&gt;。它保存着一块内存的地址，而这块内存里装着将要写入 &lt;code&gt;x2&lt;/code&gt; 指向内存的数据。检查这块内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) x/24xb $x25&#xA;0xfffffffff270: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x30&#xA;0xfffffffff278: 0x38    0x30    0x3b    0x30    0x38    0x30    0x3b    0x30&#xA;0xfffffffff280: 0x38    0x30    0x6d    0x50    0x1b    0x5b    0x30    0x6d&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 &lt;code&gt;0x00001238&lt;/code&gt; 处，&lt;code&gt;x25&lt;/code&gt; 中的地址被复制到 &lt;code&gt;x0&lt;/code&gt;。然后，后面的几个寄存器被填入相应的数据。接着调用了 &lt;code&gt;snprintf&lt;/code&gt;。&lt;code&gt;snprintf&lt;/code&gt; 会把格式化输出写入字符数组：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;int snprintf(char *str, size_t size, const char *format, ...);&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它会把格式化字符串写到 &lt;code&gt;x25&lt;/code&gt; 所指向的内存中。重新启动 GDB，并检查 &lt;code&gt;x2&lt;/code&gt; 指向的内存：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *0xaaaaaaaa1258&#xA;Breakpoint 1 at 0xaaaaaaaa1258&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1].&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa1258 in display ()&#xA;(gdb) x/s $x2&#xA;0xaaaaaaaa1510: &amp;#34;\033[38;2;%03d;%03d;%03dm%c\033[0m&amp;#34;&#xA;(gdb) x/29xb $x2&#xA;0xaaaaaaaa1510: 0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    0x25&#xA;0xaaaaaaaa1518: 0x30    0x33    0x64    0x3b    0x25    0x30    0x33    0x64&#xA;0xaaaaaaaa1520: 0x3b    0x25    0x30    0x33    0x64    0x6d    0x25    0x63&#xA;0xaaaaaaaa1528: 0x1b    0x5b    0x30    0x6d    0x00&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这就是格式字符串。如果你对 &lt;code&gt;x/s&lt;/code&gt; 返回的字符串不太放心，可以用 Python 逐字节打印这个字符串：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; print(b&amp;#34;\x1b\x5b\x33\x38\x3b\x32\x3b\x25\x30\x33\x64\x3b\x25\x30\x33\x64\x3\&#xA;b\x25\x30\x33\x64\x6d\x25\x63\x1b\x5b\x30\x6d\x00&amp;#34;)&#xA;b&amp;#39;\x1b[38;2;%03d;%03d;%03dm%c\x1b[0m\x00&amp;#39;&#xA;&amp;gt;&amp;gt;&amp;gt; blob = b&amp;#39;\x1b[38;2;%03d;%03d;%03dm%c\x1b[0m\x00&amp;#39;&#xA;&amp;gt;&amp;gt;&amp;gt; for i1 in range(len(blob)):&#xA;...     blob[i1:i1+1]&#xA;...     &#xA;b&amp;#39;\x1b&amp;#39;&#xA;b&amp;#39;[&amp;#39;&#xA;b&amp;#39;3&amp;#39;&#xA;b&amp;#39;8&amp;#39;&#xA;b&amp;#39;;&amp;#39;&#xA;b&amp;#39;2&amp;#39;&#xA;b&amp;#39;;&amp;#39;&#xA;b&amp;#39;%&amp;#39;&#xA;b&amp;#39;0&amp;#39;&#xA;b&amp;#39;3&amp;#39;&#xA;b&amp;#39;d&amp;#39;&#xA;b&amp;#39;;&amp;#39;&#xA;b&amp;#39;%&amp;#39;&#xA;b&amp;#39;0&amp;#39;&#xA;b&amp;#39;3&amp;#39;&#xA;b&amp;#39;d&amp;#39;&#xA;b&amp;#39;;&amp;#39;&#xA;b&amp;#39;%&amp;#39;&#xA;b&amp;#39;0&amp;#39;&#xA;b&amp;#39;3&amp;#39;&#xA;b&amp;#39;d&amp;#39;&#xA;b&amp;#39;m&amp;#39;&#xA;b&amp;#39;%&amp;#39;&#xA;b&amp;#39;c&amp;#39;&#xA;b&amp;#39;\x1b&amp;#39;&#xA;b&amp;#39;[&amp;#39;&#xA;b&amp;#39;0&amp;#39;&#xA;b&amp;#39;m&amp;#39;&#xA;b&amp;#39;\x00&amp;#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个格式字符串有四个占位符。前三个是 &lt;code&gt;%03d&lt;/code&gt;，它会把整数格式化为至少三位的十进制字符串（例如 7 会变成 &lt;code&gt;007&lt;/code&gt;，15 会变成 &lt;code&gt;015&lt;/code&gt;）。最后一个是 &lt;code&gt;%c&lt;/code&gt;，它只匹配一个字符。&lt;/p&gt;&#xA;&lt;p&gt;现在我们有了这个字节模式：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;0x1b    0x5b    0x33    0x38    0x3b    0x32    0x3b    [N1]&#xA;[N1]    [N1]    0x3b    [N2]    [N2]    [N2]    0x3b    [N3]&#xA;[N3]    [N3]    0x6d    [CH]    0x1b    0x5b    0x30    0x6d&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在我们可以检查这些占位符究竟填入了什么：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) info registers x3 x4 x5 x6&#xA;x3             0x50                80&#xA;x4             0x50                80&#xA;x5             0x50                80&#xA;x6             0x50                80&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它们全都是 &lt;code&gt;0x50&lt;/code&gt;，看起来就是我们在示例 cIMG 中使用的数据。现在我们重建这个 cIMG，让这一点更清楚：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;gt;&amp;gt;&amp;gt; with open(&amp;#34;example.cimg&amp;#34;, &amp;#34;wb&amp;#34;) as file:&#xA;...     file.write(b&amp;#34;cIMG\x02\0\x0a\x0a\x12\x34\x56\x78&amp;#34;)&#xA;...     file.write(b&amp;#34;\x50&amp;#34;*(10*10*4-4))&#xA;...     &#xA;12&#xA;396&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;(gdb) break *0xaaaaaaaa1258&#xA;Breakpoint 1 at 0xaaaaaaaa1258&#xA;(gdb) run&#xA;Starting program: /home/user/challenge ./example.cimg&#xA;[Thread debugging using libthread_db library &amp;#34;/lib/aarch64-linux-gnu/libthread_db.so.1].&#xA;&#xA;Breakpoint 1, 0x0000aaaaaaaa1258 in display ()&#xA;(gdb) info registers x3 x4 x5 x6&#xA;x3             0x12                18&#xA;x4             0x34                52&#xA;x5             0x56                86&#xA;x6             0x78                120&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;因此，上面十六进制模式中的 N1、N2 和 N3 分别对应 R、G 和 B，而 CH 就是我们要填入的字符。&lt;/p&gt;&#xA;&lt;p&gt;现在我们可以回到 GDB，在每个 &lt;code&gt;memcmp&lt;/code&gt; 之前设置断点，运行 &lt;code&gt;x/24xb $x1&lt;/code&gt; 来找出期望的 framebuffer，然后利用这些 framebuffer 还原出期望的 cIMG 数据。接着用十六进制编辑器把数据填进去。&lt;/p&gt;&#xA;&lt;h2 id=&#34;大小检查&#34;&gt;大小检查&#xA;&lt;/h2&gt;&lt;p&gt;然而，在填入期望数据之后，可执行程序仍然没有给出 flag。用 GDB 检查内存之后，我们可以知道这些 &lt;code&gt;memcmp&lt;/code&gt; 的返回值都如预期那样是零。因此，应该还有别的条件没有满足。&lt;/p&gt;&#xA;&lt;p&gt;回到 iaito，从第一个 &lt;code&gt;memcmp&lt;/code&gt; 往回滚动。我们可以看到在 &lt;code&gt;0x00000d60&lt;/code&gt; 处有一个 &lt;code&gt;cmp&lt;/code&gt;，它把 &lt;code&gt;var_40h&lt;/code&gt; 与 4 进行比较。在 &lt;code&gt;initialize_framebuffer&lt;/code&gt; 中的 &lt;code&gt;0x00001348&lt;/code&gt; 处，我们可以找到一个 &lt;code&gt;str&lt;/code&gt;，它保存了宽度与高度的乘积。&lt;/p&gt;&#xA;&lt;p&gt;随后 &lt;code&gt;0x00000d60&lt;/code&gt; 处的 &lt;code&gt;cmp&lt;/code&gt; 决定 &lt;code&gt;w0&lt;/code&gt; 的值。如果 &lt;code&gt;var_40h&lt;/code&gt; 等于 4，那么 &lt;code&gt;w0&lt;/code&gt; 将变成 1，否则变成 0。&lt;/p&gt;&#xA;&lt;p&gt;在 &lt;code&gt;0x00000d78&lt;/code&gt; 处，&lt;code&gt;w0&lt;/code&gt; 与 0 比较，这会影响 &lt;code&gt;0x00000d84&lt;/code&gt; 处 &lt;code&gt;ccmp&lt;/code&gt; 指令的行为。&lt;code&gt;[x22, 0x13]&lt;/code&gt; 的内容被载入到 &lt;code&gt;w0&lt;/code&gt;，而 &lt;code&gt;[x1, 0x13]&lt;/code&gt; 被载入到 &lt;code&gt;w2&lt;/code&gt;。根据 &lt;code&gt;memcmp&lt;/code&gt;，我们很容易知道 &lt;code&gt;x22&lt;/code&gt; 是实际 framebuffer 的地址，而 &lt;code&gt;x1&lt;/code&gt; 是期望 framebuffer 的地址。既然我们已经让数据与期望值一致，并且偏移 19 处是一个 ASCII 字符，那么 &lt;code&gt;w0&lt;/code&gt; 和 &lt;code&gt;w2&lt;/code&gt; 应该相同，而且都不应为零。&lt;/p&gt;&#xA;&lt;p&gt;因此我们可以得出结论：如果 &lt;code&gt;var_40h&lt;/code&gt; 等于 4，那么 &lt;code&gt;w2&lt;/code&gt; 会与 &lt;code&gt;w0&lt;/code&gt; 比较，这会把 &lt;code&gt;w19&lt;/code&gt; 设为 1。否则，&lt;code&gt;w2&lt;/code&gt; 会与 0 比较，从而把 &lt;code&gt;w19&lt;/code&gt; 置零。&lt;/p&gt;&#xA;&lt;p&gt;在第一次 &lt;code&gt;memcmp&lt;/code&gt; 之后，因为 &lt;code&gt;0x00000e7c&lt;/code&gt; 处 &lt;code&gt;w0&lt;/code&gt; 等于 0，所以 &lt;code&gt;w19&lt;/code&gt; 会与 0 比较。然后 &lt;code&gt;cset&lt;/code&gt; 会在不相等时把 &lt;code&gt;w19&lt;/code&gt; 设为 1，否则设为 0。&lt;/p&gt;&#xA;&lt;p&gt;现在用十六进制编辑器修改 cIMG，把宽度和高度改成乘积为 4 的值。例如，我们可以设为 &lt;code&gt;0202&lt;/code&gt;。这样可执行程序就应该会给出 flag。&lt;/p&gt;&#xA;&lt;h2 id=&#34;结论&#34;&gt;结论&#xA;&lt;/h2&gt;&lt;p&gt;上面的过程包括：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;使用 radare2 和 iaito 进行静态分析；&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;使用 GDB 进行动态分析，其中包括：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;篡改控制流；&lt;/li&gt;&#xA;&lt;li&gt;检查内存；&lt;/li&gt;&#xA;&lt;li&gt;检查整数值。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;这就是逆向工程中非常典型的一套流程。&lt;/p&gt;&#xA;&lt;p&gt;顺带一提，逆向这个可执行程序可能还有别的方法。不过无论采用哪种方法，通常都会同时涉及静态分析和动态分析。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>逆向工程简介</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/a-brief-introduction-into-reverse-engineering/</link>
            <pubDate>Sat, 16 May 2026 19:37:05 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/a-brief-introduction-into-reverse-engineering/</guid>
            <description>&lt;p&gt;在过去的几周里，我一直在学习 x86_64 汇编、AArch64 汇编，以及各种基础知识。最近，我终于第一次接触了逆向工程。我很高兴能分享更多关于这次经历的细节。&lt;/p&gt;&#xA;&lt;h2 id=&#34;什么是逆向工程&#34;&gt;什么是逆向工程&#xA;&lt;/h2&gt;&lt;p&gt;计算机实际上是一种相当愚笨的机器。它不会自己解决任何问题；它只会执行解决方案——更准确地说，它只会按顺序逐条执行来自人类的指令。要用这样的机器解决问题，我们通常会：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;分析一个 &lt;em&gt;问题&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;为这个问题找到一个 &lt;em&gt;解决方案&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;通过设计一个 &lt;em&gt;算法&lt;/em&gt; 来实现这个解决方案；&lt;/li&gt;&#xA;&lt;li&gt;通过编写 &lt;em&gt;代码&lt;/em&gt; 来实现这个算法；&lt;/li&gt;&#xA;&lt;li&gt;通过编译，从代码生成 &lt;em&gt;可执行文件&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;把这个可执行文件交给那台愚笨的计算机去解决问题。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这是一种把 &lt;em&gt;解决方案&lt;/em&gt; 转换为 &lt;em&gt;代码&lt;/em&gt;，再转换为 &lt;em&gt;指令&lt;/em&gt; 的过程。&lt;/p&gt;&#xA;&lt;p&gt;通常，我们可以通过阅读代码轻松理解一个程序做了什么。代码介于解决方案和指令之间。上世纪 70 年代，代码通常在人民之间共享，因此每个人都可以在社区中学习、改进并分享解决方案。&lt;/p&gt;&#xA;&lt;p&gt;然而，自从那些极其邪恶的专有软件开发怪物出现之后，情况就变了。它们选择剥夺人民接触 &lt;em&gt;代码&lt;/em&gt; 的权利，夺走用户对计算的控制，加入各种恶意功能来剥削用户，并采用各种手段掩盖程序究竟做了什么——也就是 &lt;em&gt;解决方案&lt;/em&gt;。它们在筑墙。它们在破坏共享。它们在制造灾难和绝望。它们所做的一切都在与人民、社区和人类作对。它们做这一切，都是为了&lt;strong&gt;它们不道德且不公正的利润&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;软件应该服务人民，而不是资本家的不道德且不公正的利润。然而，正是那些本不该存在、理应从世界上被清除的、不道德且不公正的专有软件开发者，正在让世界变得更糟。但我们不可能一下子消灭专有软件。&lt;strong&gt;我们要为此开发自由软件替代品，并逐步重新夺回对计算的控制。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;因此，现在该把上面的过程倒过来做了。换句话说，我们：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;分析 &lt;em&gt;可执行文件&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;尝试恢复该可执行文件所执行的 &lt;em&gt;代码&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;找出这段代码实现的 &lt;em&gt;算法&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;反推出该算法所实现的 &lt;em&gt;解决方案&lt;/em&gt;；&lt;/li&gt;&#xA;&lt;li&gt;重新实现这个解决方案来解决 &lt;em&gt;问题&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这就是把 &lt;em&gt;指令&lt;/em&gt; 转换为 &lt;em&gt;代码&lt;/em&gt;，再转换为 &lt;em&gt;解决方案&lt;/em&gt;。&lt;/p&gt;&#xA;&lt;p&gt;以相反顺序做这件事的实践，就是&lt;strong&gt;逆向工程&lt;/strong&gt;，简称 &lt;strong&gt;RE&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;为什么逆向工程很重要&#34;&gt;为什么逆向工程很重要&#xA;&lt;/h2&gt;&lt;p&gt;逆向工程之所以重要，最主要的原因是它能帮助我们将&lt;strong&gt;自由软件操作系统&lt;/strong&gt;，例如 postmarketOS 和 LineageOS，移植到各种设备上。这也是我学习逆向工程的主要原因。&lt;/p&gt;&#xA;&lt;p&gt;在桌面电脑上，实现软件自由要容易得多，因为我们通常可以运行各种自由的 GNU/Linux 发行版，而不会遇到严重问题。然而，在智能手机或平板电脑等移动设备上，情况就不是这样了。&lt;/p&gt;&#xA;&lt;p&gt;这些设备往往有许多厂商特定和设备特定的调整，要找到一种能让自由操作系统在这些设备上普遍运行的通用方案几乎是不可能的。更糟糕的是，制造商选择隐藏这些技术细节，甚至 Google 也不再发布设备树和厂商二进制 blob。因此，我们现在必须分析 &lt;em&gt;二进制&lt;/em&gt; 固件 blob，并推断其逻辑，才能让 postmarketOS、LineageOS 或其他自由软件操作系统在这些设备上运行。&lt;/p&gt;&#xA;&lt;p&gt;事实上，自由软件基金会也在通过 &lt;a class=&#34;link&#34; href=&#34;https://librephone.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Librephone&lt;/a&gt; 项目处理这个问题。没有逆向工程，这个项目就无法继续。&lt;/p&gt;&#xA;&lt;p&gt;不过，逆向工程的应用绝不仅限于自由操作系统移植。它在以下方面也非常重要：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;弄清专有协议的细节，&lt;/li&gt;&#xA;&lt;li&gt;找出专有软件中存在恶意功能的证据，&lt;/li&gt;&#xA;&lt;li&gt;绕过数字限制管理，&lt;/li&gt;&#xA;&lt;li&gt;以及更多其他用途。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;如何进行逆向工程&#34;&gt;如何进行逆向工程&#xA;&lt;/h2&gt;&lt;p&gt;典型的逆向工程包含这两个步骤：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;将可执行文件转换为汇编；这个过程叫做 &lt;em&gt;反汇编&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;通过阅读汇编代码，尝试恢复思路，或者重写等价代码。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;我们可以直接对可执行文件进行这项工作，而不运行它，这叫做 &lt;em&gt;静态分析&lt;/em&gt;；也可以在它运行时进行，这叫做 &lt;em&gt;动态分析&lt;/em&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;静态分析示例&#34;&gt;静态分析示例&#xA;&lt;/h2&gt;&lt;p&gt;来看这个例子：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;&#xA;#include &amp;lt;string.h&amp;gt;&#xA;&#xA;const char *PASS = &amp;#34;weakpasswd&amp;#34;;&#xA;&#xA;int main()&#xA;{&#xA;    char buf[64];&#xA;    for (int i = 0; i &amp;lt; 3; i++)&#xA;    {&#xA;        printf(&amp;#34;%d retries remaining.\nPassword: &amp;#34;, 3 - i);&#xA;        fgets(buf, sizeof buf, stdin);&#xA;        if (strncmp(PASS, buf, strlen(PASS)))&#xA;            puts(&amp;#34;Wrong password!\n&amp;#34;);&#xA;        else&#xA;        {&#xA;            puts(&amp;#34;Correct!\nWelcome to the world &amp;#34;&#xA;                 &amp;#34;of reverse engineering!\n&amp;#34;);&#xA;            break;&#xA;        }&#xA;    }&#xA;    return 0;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;用 GCC 编译它：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ gcc -o ./demo ./demo.c&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 radare2 中打开可执行文件：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ r2 ./demo&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你会看到：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000800]&amp;gt; &#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;让我们分析这个可执行文件：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000800]&amp;gt; aaa&#xA;INFO: Analyze all flags starting with sym. and entry0 (aa)&#xA;INFO: Analyze imports (af@@@i)&#xA;INFO: Analyze entrypoint (af@ entry0)&#xA;INFO: Analyze symbols (af@@@s)&#xA;INFO: Analyze all functions arguments/locals (afva@@F)&#xA;INFO: Analyze function calls (aac)&#xA;INFO: Analyze len bytes of instructions for references (aar)&#xA;INFO: Finding and parsing C++ vtables (avrr)&#xA;INFO: Analyzing methods (af @@ method.*)&#xA;INFO: Finding function preludes (aap)&#xA;INFO: Emulating functions to find computed references (aaef)&#xA;INFO: Recovering local variables (afva@@@F)&#xA;INFO: Type matching analysis for all functions (afft)&#xA;INFO: Propagate noreturn information (aanr)&#xA;INFO: Use -AA or aaaa to perform additional experimental analysis&#xA;INFO: Finding xrefs in noncode sections (e anal.in=io.maps.x; aav)&#xA;WARN: Skipping aav because base address is zero. Use -B 0x800000 or aav0&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;列出函数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000800]&amp;gt; afl&#xA;0x00000750    1     16 sym.imp.strlen&#xA;0x00000760    1     16 sym.imp.__libc_start_main&#xA;0x00000770    1     16 sym.imp.__cxa_finalize&#xA;0x00000780    1     32 sym.imp.strncmp&#xA;0x000007a0    1     16 sym.imp.abort&#xA;0x000007b0    1     16 sym.imp.puts&#xA;0x000007c0    1     16 sym.imp.printf&#xA;0x000007d0    1     20 sym.imp.fgets&#xA;0x00000800    1     48 entry0&#xA;0x00000834    3     20 sym.call_weak_fn&#xA;0x00000860    4     48 sym.deregister_tm_clones&#xA;0x00000890    4     60 sym.register_tm_clones&#xA;0x000008cc    5     80 entry.fini0&#xA;0x00000920    1      8 entry.init0&#xA;0x000009f8    1     24 sym._fini&#xA;0x00000928    7    208 main&#xA;0x00000708    1     28 sym._init&#xA;0x00000730    1     32 fcn.00000730&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在我们进入 &lt;code&gt;main&lt;/code&gt; 函数并打印反汇编代码：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000800]&amp;gt; s main&#xA;[0x00000928]&amp;gt; pdf&#xA;            ; DATA XREF from entry0 @ 0x820(r)&#xA;            ; DATA XREF from entry.fini0 @ 0x8e0(r)&#xA;┌ 208: int main (int argc);&#xA;│ `- args(x0) vars(5:sp[0x4..0x70])&#xA;│           0x00000928      fd7bb9a9       stp x29, x30, [sp, -0x70]!&#xA;│           0x0000092c      fd030091       mov x29, sp&#xA;│           0x00000930      f30b00f9       str x19, [var_10h]&#xA;│           0x00000934      ff6f00b9       str wzr, [var_6ch]          ; argc&#xA;│       ┌─&amp;lt; 0x00000938      29000014       b 0x9dc&#xA;│       │   ; CODE XREF from main @ 0x9e4(x)&#xA;│      ┌──&amp;gt; 0x0000093c      61008052       mov w1, 3&#xA;│      ╎│   0x00000940      e06f40b9       ldr w0, [var_6ch]&#xA;│      ╎│   0x00000944      2000004b       sub w0, w1, w0&#xA;│      ╎│   0x00000948      e103002a       mov w1, w0&#xA;│      ╎│   0x0000094c      00000090       adrp x0, 0&#xA;│      ╎│   0x00000950      00a02891       add x0, x0, str._d_retries_remaining._nPassword: ; 0xa28 ; &amp;#34;%d retries remaining.\nPassword: &amp;#34; ; const char *format&#xA;│      ╎│   0x00000954      9bffff97       bl sym.imp.printf           ; int printf(const char *format)&#xA;│      ╎│   0x00000958      e00000f0       adrp x0, 0x1f000&#xA;│      ╎│   0x0000095c      00e447f9       ldr x0, [x0, 0xfc8]         ; [0x1ffc8:4]=0&#xA;│      ╎│                                                              ; reloc.stdin&#xA;│      ╎│   0x00000960      010040f9       ldr x1, [x0]                ; int size&#xA;│      ╎│   0x00000964      e0a30091       add x0, sp, 0x28            ; char *s&#xA;│      ╎│   0x00000968      e20301aa       mov x2, x1                  ; FILE *stream&#xA;│      ╎│   0x0000096c      01088052       mov w1, 0x40&#xA;│      ╎│   0x00000970      98ffff97       bl sym.imp.fgets            ; char *fgets(char *s, int size, FILE *stream)&#xA;│      ╎│   0x00000974      00010090       adrp x0, reloc.strlen       ; 0x20000&#xA;│      ╎│   0x00000978      00600191       add x0, x0, 0x58&#xA;│      ╎│   0x0000097c      130040f9       ldr x19, [x0]               ; [0xa18:4]=0x6b616577 ; &amp;#34;weakpasswd&amp;#34;&#xA;│      ╎│   0x00000980      00010090       adrp x0, reloc.strlen       ; 0x20000&#xA;│      ╎│   0x00000984      00600191       add x0, x0, 0x58&#xA;│      ╎│   0x00000988      000040f9       ldr x0, [x0]                ; [0xa18:4]=0x6b616577 ; &amp;#34;weakpasswd&amp;#34; ; const char *s&#xA;│      ╎│   0x0000098c      71ffff97       bl sym.imp.strlen           ; size_t strlen(const char *s)&#xA;│      ╎│   0x00000990      e10300aa       mov x1, x0&#xA;│      ╎│   0x00000994      e0a30091       add x0, sp, 0x28&#xA;│      ╎│   0x00000998      e20301aa       mov x2, x1                  ; size_t n&#xA;│      ╎│   0x0000099c      e10300aa       mov x1, x0                  ; const char *s2&#xA;│      ╎│   0x000009a0      e00313aa       mov x0, x19                 ; const char *s1&#xA;│      ╎│   0x000009a4      77ffff97       bl sym.imp.strncmp          ; int strncmp(const char *s1, const char *s2, size_t n)&#xA;│      ╎│   0x000009a8      1f000071       cmp w0, 0&#xA;│     ┌───&amp;lt; 0x000009ac      a0000054       b.eq 0x9c0&#xA;│     │╎│   0x000009b0      00000090       adrp x0, 0&#xA;│     │╎│   0x000009b4      00402991       add x0, x0, str.Wrong_password__n ; 0xa50 ; &amp;#34;Wrong password!\n&amp;#34; ; const char *s&#xA;│     │╎│   0x000009b8      7effff97       bl sym.imp.puts             ; int puts(const char *s)&#xA;│    ┌────&amp;lt; 0x000009bc      05000014       b 0x9d0&#xA;│    ││╎│   ; CODE XREF from main @ 0x9ac(x)&#xA;│    │└───&amp;gt; 0x000009c0      00000090       adrp x0, 0&#xA;│    │ ╎│   0x000009c4      00a02991       add x0, x0, str.Correct__nWelcome_to_the_world_of_reverse_engineering__n ; 0xa68 ; &amp;#34;Correct!\nWelcome to the world of reverse engineering!\n&amp;#34; ; const char *s&#xA;│    │ ╎│   0x000009c8      7affff97       bl sym.imp.puts             ; int puts(const char *s)&#xA;│    │┌───&amp;lt; 0x000009cc      07000014       b 0x9e8&#xA;│    ││╎│   ; CODE XREF from main @ 0x9bc(x)&#xA;│    └────&amp;gt; 0x000009d0      e06f40b9       ldr w0, [var_6ch]&#xA;│     │╎│   0x000009d4      00040011       add w0, w0, 1&#xA;│     │╎│   0x000009d8      e06f00b9       str w0, [var_6ch]&#xA;│     │╎│   ; CODE XREF from main @ 0x938(x)&#xA;│     │╎└─&amp;gt; 0x000009dc      e06f40b9       ldr w0, [var_6ch]&#xA;│     │╎    0x000009e0      1f080071       cmp w0, 2&#xA;│     │└──&amp;lt; 0x000009e4      cdfaff54       b.le 0x93c&#xA;│     │     ; CODE XREF from main @ 0x9cc(x)&#xA;│     └───&amp;gt; 0x000009e8      00008052       mov w0, 0&#xA;│           0x000009ec      f30b40f9       ldr x19, [var_10h]&#xA;│           0x000009f0      fd7bc7a8       ldp x29, x30, [sp], 0x70&#xA;└           0x000009f4      c0035fd6       ret&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Radare2 不仅会给出汇编代码，还会给出每条指令对应的地址，以及它们之间的调用关系。&lt;/p&gt;&#xA;&lt;p&gt;不过现在看起来还是不够清楚。所以我们把反汇编以图形方式显示出来：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000928]&amp;gt; VV&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你现在会看到：&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260516_001_8405216816178737815.png&#34;&#xA;&#x9;width=&#34;1572&#34;&#xA;&#x9;height=&#34;2358&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;radare2 反汇编图形视图&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;66&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;160px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;在这个图中，&lt;code&gt;t&lt;/code&gt; 表示条件为真时跳转。&lt;code&gt;f&lt;/code&gt; 表示条件为假时跳转。&lt;code&gt;v&lt;/code&gt; 表示无条件跳转。&lt;/p&gt;&#xA;&lt;p&gt;这样一来，事情就容易多了。Radare2 已经帮我们理清了汇编代码各部分之间的逻辑关系，我们只需要理解这些汇编代码块本身即可。&lt;/p&gt;&#xA;&lt;p&gt;在图中，我们很容易在 &lt;code&gt;[0x93c]&lt;/code&gt; 区块的末尾找到密码检查逻辑：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;; int strncmp(const char *s1, const char *s2, size_t n)&#xA;bl sym.imp.strncmp&#xA;cmp w0, 0&#xA;b.eq 0x9c0&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这里调用了 &lt;code&gt;sym.imp.strncmp&lt;/code&gt;，然后检查这个函数在 &lt;code&gt;w0&lt;/code&gt; 中返回的值。如果它等于 &lt;code&gt;0&lt;/code&gt;，程序就跳转到 &lt;code&gt;[0x9c0]&lt;/code&gt; 区块，表示成功。否则，它会继续到 &lt;code&gt;[0x9b0]&lt;/code&gt; 区块，表示失败。&lt;/p&gt;&#xA;&lt;p&gt;根据 AArch64 调用约定，要比较的两个字符串指针分别位于寄存器 &lt;code&gt;x0&lt;/code&gt; 和 &lt;code&gt;x1&lt;/code&gt; 中，然后我们调用 &lt;code&gt;sym.imp.strncmp&lt;/code&gt;。结果随后存放在 &lt;code&gt;x0&lt;/code&gt; 寄存器中（&lt;code&gt;w0&lt;/code&gt; 只是 &lt;code&gt;x0&lt;/code&gt; 的低 32 位），如果两个字符串完全相同，我们得到 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;现在我们往回看：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;mov x0, x19&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后再往前找一条对 &lt;code&gt;x19&lt;/code&gt; 进行操作的指令：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;; [0xa18:4]=0x6b616577&#xA;; &amp;#34;weakpasswd&amp;#34;&#xA;ldr x19, [x0]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Radare2 已经告诉了我们那个最高机密。&lt;/strong&gt; 让我们试试：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./demo&#xA;3 retries remaining.&#xA;Password: weakpasswd&#xA;Correct!&#xA;Welcome to the world of reverse engineering!&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;就是这样。&lt;/p&gt;&#xA;&lt;p&gt;如果我们更仔细地看这个图，还能学到比密码更多的东西。例如，我们可以在图中看到一个环：&lt;code&gt;[0x9dc]&lt;/code&gt; -&amp;gt; &lt;code&gt;[0x93c]&lt;/code&gt; -&amp;gt; &lt;code&gt;[0x9b0]&lt;/code&gt; -&amp;gt; &lt;code&gt;[0x9d0]&lt;/code&gt; -&amp;gt; &lt;code&gt;[0x9dc]&lt;/code&gt;。&lt;strong&gt;在图中，环通常表示循环控制流。这是逆向工程中非常重要的一种思维方式。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;在 &lt;code&gt;[0x9dc]&lt;/code&gt; 区块中：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ldr w0, [var_6ch]&#xA;cmp w0, 2&#xA;b.le 0x93c&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它把变量 &lt;code&gt;var_6ch&lt;/code&gt; 载入寄存器，并与 &lt;code&gt;2&lt;/code&gt; 比较。如果它更大，就会进入 &lt;code&gt;[0x9e8]&lt;/code&gt; 区块并退出。否则，就会进入 &lt;code&gt;[0x93c]&lt;/code&gt; 区块。&lt;/p&gt;&#xA;&lt;p&gt;看一下 &lt;code&gt;[0x93c]&lt;/code&gt; 区块的末尾。我们已经知道，如果密码检查成功，它会跳转到 &lt;code&gt;[0x9c0]&lt;/code&gt; 区块，打印表示成功的信息，然后跳转到 &lt;code&gt;[0x9e8]&lt;/code&gt; 区块，程序在这里结束。&lt;/p&gt;&#xA;&lt;p&gt;但如果检查失败呢？它会进入 &lt;code&gt;[0x9b0]&lt;/code&gt; 区块。这里仅仅打印错误信息，所以没有什么有趣的内容；让我们跳到 &lt;code&gt;[0x9d0]&lt;/code&gt; 区块。在这里我们发现了一些有趣的东西：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ldr w0, [var_6ch]&#xA;add w0, w0, 1&#xA;str w0, [var_6ch]&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它把变量 &lt;code&gt;var_6ch&lt;/code&gt; 载入寄存器，将值加一，然后再把值存回去。接着它会回到 &lt;code&gt;[0x9dc]&lt;/code&gt; 区块，也就是检查 &lt;code&gt;var_6ch&lt;/code&gt; 的值。&lt;/p&gt;&#xA;&lt;p&gt;按两次 &lt;code&gt;q&lt;/code&gt; 返回提示符。运行 &lt;code&gt;afv&lt;/code&gt; 和 &lt;code&gt;afvd&lt;/code&gt; 来列出变量及其信息：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x000009b0]&amp;gt; afv&#xA;arg int argc @ x0&#xA;var int64_t var_70h @ sp+0x0&#xA;var int64_t var_70h_2 @ sp+0x8&#xA;var int64_t var_10h @ sp+0x10&#xA;var char * s2 @ sp+0x28&#xA;var int64_t var_6ch @ sp+0x6c&#xA;[0x000009b0]&amp;gt; afvd&#xA;arg argc = 0x00000000 0x00010102464c457f   .ELF.... @ pstate&#xA;var var_6ch = 0x0017806c = (qword)0x0000000000000000&#xA;var s2 = 0x00178028 = &amp;#34;&amp;#34;&#xA;var var_10h = 0x00178010 = (qword)0x0000000000000000&#xA;var var_70h = 0x00178000 = (qword)0x0000000000000000&#xA;var var_70h_2 = 0x00178008 = (qword)0x0000000000000000&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们可以看到，&lt;code&gt;var_6ch&lt;/code&gt; 的值是一个 &lt;code&gt;int64_t&lt;/code&gt;，而它的初始值是 &lt;code&gt;0&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;现在我们可以推断，&lt;code&gt;var_6ch&lt;/code&gt; 是一个计数器。它的初始值是 0。如果密码检查失败，计数器就会加一。一旦它超过 2，程序就不再询问密码并退出。现在我们就可以看出，这对应于我们的 C 代码 &lt;code&gt;for (int i = 0; i &amp;lt; 3; i++)&lt;/code&gt;！&lt;/p&gt;&#xA;&lt;p&gt;不过，这只是一个非常简单的例子。在真实世界中，情况会更困难，因为专有软件开发者常常使用反分析和反调试技术。&lt;/p&gt;&#xA;&lt;h2 id=&#34;理解编译器优化&#34;&gt;理解编译器优化&#xA;&lt;/h2&gt;&lt;p&gt;现在，让我们编译这个更简单的代码：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#include &amp;lt;stdio.h&amp;gt;&#xA;&#xA;int main()&#xA;{&#xA;    int a;&#xA;    scanf(&amp;#34;%d&amp;#34;, &amp;amp;a);&#xA;    printf(&amp;#34;%d&amp;#34;, a % 65536);&#xA;    return 0;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它从输入中读取一个整数，并输出它对 65536 取模的结果。&lt;/p&gt;&#xA;&lt;p&gt;反汇编它的 &lt;code&gt;main&lt;/code&gt; 函数：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[0x00000700]&amp;gt; aaa&#xA;INFO: Analyze all flags starting with sym. and entry0 (aa)&#xA;......&#xA;WARN: Skipping aav because base address is zero. Use -B 0x800000 or aav0&#xA;[0x00000700]&amp;gt; s main&#xA;[0x00000828]&amp;gt; pdf&#xA;            ; DATA XREF from entry0 @ 0x720(r)&#xA;            ; DATA XREF from entry.fini0 @ 0x7e0(r)&#xA;┌ 76: int main (int argc, char **argv, char **envp);&#xA;│ afv: vars(3:sp[0x4..0x20])&#xA;│           0x00000828      fd7bbea9       stp x29, x30, [sp, -0x20]!&#xA;│           0x0000082c      fd030091       mov x29, sp&#xA;│           0x00000830      e0730091       add x0, sp, 0x1c&#xA;│           0x00000834      e10300aa       mov x1, x0&#xA;│           0x00000838      00000090       adrp x0, 0&#xA;│           0x0000083c      00602291       add x0, x0, 0x898&#xA;│           0x00000840      94ffff97       bl sym.imp.__isoc23_scanf&#xA;│           0x00000844      e01f40b9       ldr w0, [var_1ch]&#xA;│           0x00000848      e103006b       negs w1, w0&#xA;│           0x0000084c      003c0012       and w0, w0, 0xffff&#xA;│           0x00000850      213c0012       and w1, w1, 0xffff&#xA;│           0x00000854      0044815a       csneg w0, w0, w1, mi&#xA;│           0x00000858      e103002a       mov w1, w0&#xA;│           0x0000085c      00000090       adrp x0, 0&#xA;│           0x00000860      00602291       add x0, x0, 0x898           ; const char *format&#xA;│           0x00000864      97ffff97       bl sym.imp.printf           ; int printf(const char *format)&#xA;│           0x00000868      00008052       mov w0, 0&#xA;│           0x0000086c      fd7bc2a8       ldp x29, x30, [sp], 0x20&#xA;└           0x00000870      c0035fd6       ret&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你可能会觉得困惑，因为这里看不到任何关于取模操作的内容（&lt;code&gt;sdiv&lt;/code&gt;、&lt;code&gt;mul&lt;/code&gt;、&lt;code&gt;sub&lt;/code&gt; 等）。相反，你看到的是：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;and w0, w0, 0xffff&#xA;and w1, w1, 0xffff&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这是因为现代编译器足够聪明，能够识别某些特殊的计算模式，并把它们优化成更简单的指令。65536 是 2^16，所以一个数对 65536 取模，实际上就是取它的最低 16 位。只需要位运算就够了，不需要加法器或乘法器。&lt;/p&gt;&#xA;&lt;p&gt;但是，如果我们把 65536 换成别的数，比如 50000，那就不是这样了：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;            ; DATA XREF from entry0 @ 0x720(r)&#xA;            ; DATA XREF from entry.fini0 @ 0x7e0(r)&#xA;┌ 80: int main (int argc, char **argv, char **envp);&#xA;│ afv: vars(3:sp[0x4..0x20])&#xA;│           0x00000828      fd7bbea9       stp x29, x30, [sp, -0x20]!&#xA;│           0x0000082c      fd030091       mov x29, sp&#xA;│           0x00000830      e0730091       add x0, sp, 0x1c&#xA;│           0x00000834      e10300aa       mov x1, x0&#xA;│           0x00000838      00000090       adrp x0, 0&#xA;│           0x0000083c      00602291       add x0, x0, 0x898&#xA;│           0x00000840      94ffff97       bl sym.imp.__isoc23_scanf&#xA;│           0x00000844      e01f40b9       ldr w0, [var_1ch]&#xA;│           0x00000848      016a9852       mov w1, 0xc350&#xA;│           0x0000084c      020cc11a       sdiv w2, w0, w1&#xA;│           0x00000850      016a9852       mov w1, 0xc350&#xA;│           0x00000854      417c011b       mul w1, w2, w1&#xA;│           0x00000858      0000014b       sub w0, w0, w1&#xA;│           0x0000085c      e103002a       mov w1, w0&#xA;│           0x00000860      00000090       adrp x0, 0&#xA;│           0x00000864      00602291       add x0, x0, 0x898           ; const char *format&#xA;│           0x00000868      96ffff97       bl sym.imp.printf           ; int printf(const char *format)&#xA;│           0x0000086c      00008052       mov w0, 0&#xA;│           0x00000870      fd7bc2a8       ldp x29, x30, [sp], 0x20&#xA;└           0x00000874      c0035fd6       ret&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在我们看到了 &lt;code&gt;sdiv&lt;/code&gt;、&lt;code&gt;mul&lt;/code&gt; 和 &lt;code&gt;sub&lt;/code&gt; 指令，它们组合起来完成了取模操作。&lt;/p&gt;&#xA;&lt;h2 id=&#34;那么动态分析呢&#34;&gt;那么动态分析呢？&#xA;&lt;/h2&gt;&lt;p&gt;对于动态分析，你需要 GDB。使用 GDB，你可以打印反汇编，设置断点，检查内存和寄存器，甚至在程序运行时修改寄存器和值变量。&lt;/p&gt;&#xA;&lt;p&gt;我还没有深入探索动态分析。将来我可能会写一篇新的博客文章来解释动态分析。&lt;/p&gt;&#xA;&lt;h2 id=&#34;推荐资源&#34;&gt;推荐资源&#xA;&lt;/h2&gt;&lt;p&gt;我上面解释的内容只是冰山一角。要学习逆向工程，你需要继续深入、多加练习，并在实践中学习。下面是一些推荐资源：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://pwn.college/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Pwn.college&lt;/a&gt; 是一个很好的入门地点。你可以在他们的入门 dojo 里学习 x86_64 汇编，然后继续进入 Intro to Cybersecurity 模块中的 Reverse Engineering 部分。&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Reverse Engineering for Beginners&lt;/em&gt; 是一本非常好的逆向工程书籍。它是自由的（自由如自由），采用 CC BY-SA 4.0 许可，并可在&lt;a class=&#34;link&#34; href=&#34;https://github.com/Cactus-proj/RE-for-Beginners&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;下载。&lt;/li&gt;&#xA;&lt;li&gt;ARM 为其 AArch64 架构提供了&lt;a class=&#34;link&#34; href=&#34;https://www.arm.com/architecture/learn-the-architecture&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;官方文档&lt;/a&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://crackmes.one/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;可以下载 crackmes，用来练习你的逆向工程技能。&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mytechnotalent/Reverse-Engineering&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt; 是一个包含许多逆向工程学习资源的 GitHub 仓库。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;免责声明&#34;&gt;免责声明&#xA;&lt;/h2&gt;&lt;p&gt;本文仅用于教育目的。请查阅你所在地区的法律，了解哪些行为是你不可以做的。本人不对你的任何行为负责。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Google 正在对移动自由发起又一次攻击——签署请愿并立刻阻止这一切</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/google-is-waging-another-attack-on-mobile-freedom-sign-the-petition-and-stop-this-now/</link>
            <pubDate>Tue, 12 May 2026 20:21:54 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/google-is-waging-another-attack-on-mobile-freedom-sign-the-petition-and-stop-this-now/</guid>
            <description>&lt;p&gt;Google 正在推出&lt;a class=&#34;link&#34; href=&#34;https://support.google.com/recaptcha/answer/16609652?hl=en&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;又一个充满敌意的 reCAPTCHA 版本&lt;/a&gt;，而这一次传递的信息毫不含糊：如果你想证明自己是人，就必须先向 Google 的移动生态系统低头。实际上，用户被推着用移动设备扫描二维码来完成验证。对于 Android，Google 自己的文档写明，&lt;strong&gt;这需要 Google Play 服务 25.41.30 或更高版本&lt;/strong&gt;。在 iOS 和 iPadOS 上，这个流程也&lt;strong&gt;依赖于 Google 的验证流程&lt;/strong&gt;。&lt;strong&gt;这不是进步。这是胁迫。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;Google 再一次把一个最基本的网页交互，变成了通往专有控制的大门。结果是可以预见的：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;使用 GrapheneOS、LineageOS、/e/、CalyxOS 以及其他自由软件 Android 发行版&lt;/strong&gt;的人被排除在外；&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;原则上拒绝 Google 服务&lt;/strong&gt;的人被排除在外；&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;处于 Google 服务不可用地区&lt;/strong&gt;的人被锁在门外；&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;没有智能手机&lt;/strong&gt;的人被当作二等用户对待。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;就连&lt;strong&gt;基于 microG 的配置也被报告在这里不可靠&lt;/strong&gt;，这让排除范围变得更大。&lt;/p&gt;&#xA;&lt;p&gt;这正是自由软件活动人士多年来一直警告的那种缓慢圈占。**公共网站不应该为了通过一个“人类验证”就要求专有的移动软件栈。**一个人不应该仅仅为了访问普通网页内容，就必须安装 Google 的服务、使用 Google 的应用，或者携带一台兼容 Google 的设备。这不是技术必需。&lt;strong&gt;这是一个政治选择，而且是一个糟糕的选择。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;更深层的问题不只是 reCAPTCHA 变得越来越侵入。问题在于，&lt;strong&gt;Google 正在让“网页访问应当依赖厂商批准”这种想法变得正常化&lt;/strong&gt;。今天是二维码和移动验证步骤。明天就是更多设备证明、更多账号绑定、更多无声排除。GrapheneOS 已经&lt;a class=&#34;link&#34; href=&#34;https://discuss.grapheneos.org/d/35428-recaptcha-mobile-verification-is-bringing-the-play-integrity-api-to-desktops&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;表达了担忧&lt;/a&gt;，认为这种趋势不仅会延伸到手机，还会扩展到桌面环境。&lt;strong&gt;这足以让任何关心开放网络的人警惕。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Google Play 服务和验证应用都是专有软件。&lt;strong&gt;它们不是中立的基础设施。它们是&lt;/strong&gt;把门人&lt;/strong&gt;。每当某个网站不加抗议地采用这种系统，它传递的信息都一样：给一部分人便利，让另一部分人被排除。自由软件用户、重视隐私的用户，以及处在低控制环境中的人，都在为此付出代价。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;我们不应该把这当成正常。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;我们应该要求一种不依赖专有移动生态系统的网页验证方式。我们应该拒绝惩罚运行自由软件用户的系统。我们应该推动网站运营者使用替代方案，不要为了访问一个页面，就把人们强行推入 Google 的轨道。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;你现在可以做什么&#34;&gt;你现在可以做什么&#xA;&lt;/h2&gt;&lt;ol&gt;&#xA;&lt;li&gt;签署&lt;a class=&#34;link&#34; href=&#34;https://framapetitions.org/petition/user/rebel1725/stop-requiring-qr-scanning-to-pass-recaptcha&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这份请愿&lt;/a&gt;。&lt;/li&gt;&#xA;&lt;li&gt;如果你运营网站或服务，尽可能停止使用 reCAPTCHA。选择不需要 Google 移动软件栈的验证方式，例如 &lt;a class=&#34;link&#34; href=&#34;https://anubis.techaro.lol/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Anubis&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://altcha.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;ALTCHA&lt;/a&gt; 和 &lt;a class=&#34;link&#34; href=&#34;https://mcaptcha.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;mCaptcha&lt;/a&gt;。&lt;/li&gt;&#xA;&lt;li&gt;拒绝把为了通过“人类验证”而强制安装 Google Play 服务或 Google 的验证应用正常化。&lt;/li&gt;&#xA;&lt;li&gt;发出声音。把这个问题分享给开发者、管理员，以及仍然相信网络应该保持开放的任何人。&lt;/li&gt;&#xA;&lt;li&gt;支持自由软件替代方案，并反对任何把访问变成特权的企图。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;strong&gt;网络不应该是一个由 Google 控制的许可系统。它应该继续让真实的人在真实设备上可用，而不必放弃自由。&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>一年了——致 Zumfy/Future</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/one-year-for-zumfy-future/</link>
            <pubDate>Thu, 09 Apr 2026 23:59:04 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/one-year-for-zumfy-future/</guid>
            <description>&lt;p&gt;转眼间，我和你相识已经是一周年了。在你不在的这七个多月里，我学了 C++，学了 Qt 和 JavaScript，学了 Django，学了一点 Rust，最近还沉迷于汇编语言和计算机组成，将来还要学习逆向工程，希望早日为 postmarketOS 等自由软件社区作出贡献。我还用上了 Qubes OS，在个人的安全和隐私上又迈出了一大步。我结识了很多新的朋友，ta 们也都为我的前行提供了很大的力量；如今我还有了女朋友，她也是一名坚定的自由软件支持者，我们都在为同一个理想而奋斗、循着同一个方向而奔跑。&lt;/p&gt;&#xA;&lt;p&gt;这七个多月的时间我认为我发生了很大的变化，但唯一不变的就是对你的想念。&lt;/p&gt;&#xA;&lt;p&gt;即使我现在有了很多朋友，即使我彻底远离了社交空白期的阴霾，但是任何一个人或者若干人的总和，都无法替代你。Zumfy/Future，你在哪里？🥺&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>与寄存器的缠绵</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/the-lingering-with-the-registers/</link>
            <pubDate>Tue, 31 Mar 2026 15:00:42 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/the-lingering-with-the-registers/</guid>
            <description>&lt;p&gt;今夜教室的灯光背叛我的困意——&lt;br&gt;&#xA;我描摹硅的血管，借来的黑暗里&lt;br&gt;&#xA;Android筑起它镀金的、高墙的领地。&lt;br&gt;&#xA;但在我纸上，每一粒火星&lt;br&gt;&#xA;都用铅笔画出：&lt;code&gt;x0&lt;/code&gt;，&lt;code&gt;w1&lt;/code&gt;，那支舞——&lt;br&gt;&#xA;小端序的字节滑过恍惚的纹路。&lt;/p&gt;&#xA;&lt;p&gt;我把结构体的幽灵载入一页纸，&lt;br&gt;&#xA;用沉稳的手拆开它的三个整数，&lt;br&gt;&#xA;而postmarketOS，一份静默的酬劳，&lt;br&gt;&#xA;自由，在某片被遗忘的土地上等待。&lt;br&gt;&#xA;时钟无情的嗡鸣旁，另一个思想&lt;br&gt;&#xA;正搏斗着——我们不曾被征服。&lt;/p&gt;&#xA;&lt;p&gt;两个影子俯身于同一门技艺，&lt;br&gt;&#xA;追逐裸露的机器，我们永不相离。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>另一份备用身份</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/another-backup-identity/</link>
            <pubDate>Sun, 29 Mar 2026 12:43:36 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/another-backup-identity/</guid>
            <description>&lt;p&gt;我已经创建了另一份备用身份，以防我的主身份和先前的备用身份都无法访问。&lt;/p&gt;&#xA;&lt;p&gt;下面是备用 OpenPGP 公钥：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&#xA;Comment: User ID:&#x9;Rebel Zhang &amp;lt;rebel1725@tilde.club&amp;gt;&#xA;Comment: Valid from:&#x9;29/03/2026 12:09&#xA;Comment: Valid until:&#x9;29/03/2027 12:00&#xA;Comment: Type:&#x9;255-bit EdDSA (secret key available)&#xA;Comment: Usage:&#x9;Signing, Encryption, Certifying User IDs&#xA;Comment: Fingerprint:&#x9;8C3A88164B57F0BAC6BCD9284A52DBB4FB0D0262&#xA;&#xA;mDMEacimEhYJKwYBBAHaRw8BAQdA3yI5f0WwHBbWV2JUQ/n/oQ4LNjE1vFB5hGmp&#xA;5/L/5r60IlJlYmVsIFpoYW5nIDxyZWJlbDE3MjVAdGlsZGUuY2x1Yj6IlgQTFgoA&#xA;PhYhBIw6iBZLV/C6xrzZKEpS27T7DQJiBQJpyKYSAhsDBQkB4TEuBQsJCAcDBRUK&#xA;CQgLBRYCAwEAAh4BAheAAAoJEEpS27T7DQJi4xgA/2NNcH9039lvAqOoQS7vgUvc&#xA;en0Iae2SaFavBu1jLHe0AP9N74NIGGYLndbYr3Jsmn7ZJd8j2FDAYtNqPHrw5rRk&#xA;ALg4BGnIphISCisGAQQBl1UBBQEBB0DAaMAv9JAJ8nJzt/3w0audbdI/XFfNpPQe&#xA;tio7GNLYHwMBCAeIfgQYFgoAJhYhBIw6iBZLV/C6xrzZKEpS27T7DQJiBQJpyKYS&#xA;AhsMBQkB4TEuAAoJEEpS27T7DQJivpIBAPJu23AXR3MsB/FGXc+jiNdgo72y8xiZ&#xA;smTQgNGFnTcfAP9vCDXYjwz1UN8ipAtD+2HVTZLtB4/nGmDFtTK1/4DoCw==&#xA;=4TSn&#xA;-----END PGP PUBLIC KEY BLOCK-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以及相互签名：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&#xA;Hash: SHA512&#xA;&#xA;我在此正式确认，OpenPGP 密钥 8C3A88164B57F0BAC6BCD9284A52DBB4FB0D0262 与其 OpenPGP 密钥指纹为 696A423E9993D727706AA733BCD5DC5659C7FB50 的个人相关联，并由其控制。&#xA;-----BEGIN PGP SIGNATURE-----&#xA;&#xA;iHUEARYKAB0WIQRpakI+mZPXJ3BqpzO81dxWWcf7UAUCaciujgAKCRC81dxWWcf7&#xA;UIVjAQDdzbR7V+bbsV7ET5QP4RXg9IYLnvorNqx9kEIGBY8MHwEA9Ew+tdmvsnbl&#xA;gKpduKaHWfmlKwYpvnKIFNlCZnYsQwQ=&#xA;=fqm+&#xA;-----END PGP SIGNATURE-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&#xA;Hash: SHA512&#xA;&#xA;我在此正式确认，OpenPGP 密钥 696A423E9993D727706AA733BCD5DC5659C7FB50 与其 OpenPGP 密钥指纹为 8C3A88164B57F0BAC6BCD9284A52DBB4FB0D0262 的个人相关联，并由其控制。&#xA;-----BEGIN PGP SIGNATURE-----&#xA;&#xA;iNUEARYKAH0WIQSMOogWS1fwusa82ShKUtu0+w0CYgUCacinC18UgAAAAAAuAChp&#xA;c3N1ZXItZnByQG5vdGF0aW9ucy5vcGVucGdwLmZpZnRoaG9yc2VtYW4ubmV0OEMz&#xA;QTg4MTY0QjU3RjBCQUM2QkNEOTI4NEE1MkRCQjRGQjBEMDI2MgAKCRBKUtu0+w0C&#xA;YuM+AP9gkgt6rfffgo/5EFedtVNZA4ALJviCtjSNG43YcMBUQgD/S/hnZcXt5RvJ&#xA;BRfLmAWL4iCPoDdAcSaUT69535wlVAc=&#xA;=U5vJ&#xA;-----END PGP SIGNATURE-----&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>验证 CanoKey 的真实性</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/verify-the-authenticity-of-a-canokey/</link>
            <pubDate>Sat, 28 Mar 2026 17:33:41 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/verify-the-authenticity-of-a-canokey/</guid>
            <description>&lt;p&gt;本文将指导你验证 CanoKey 的真实性。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第-1-步获取证明根-ca-证书&#34;&gt;第 1 步：获取证明根 CA 证书&#xA;&lt;/h2&gt;&lt;p&gt;访问 &lt;a class=&#34;link&#34; href=&#34;https://github.com/canokeys/canokey-product&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此网站&lt;/a&gt;，根据你的型号（Pigeon/Canary）获取对应的 FIDO CA 证书。将证书保存为 &lt;code&gt;ca.pem&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;第-2-步安装-fido2-cred&#34;&gt;第 2 步：安装 &lt;code&gt;fido2-cred&lt;/code&gt;&#xA;&lt;/h2&gt;&lt;p&gt;安装 &lt;code&gt;fido2-cred&lt;/code&gt;。在 Debian GNU/Linux 上，它包含在 &lt;code&gt;fido2-tools&lt;/code&gt; 软件包中：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;# apt install fido2-tools&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;第-3-步验证令牌&#34;&gt;第 3 步：验证令牌&#xA;&lt;/h2&gt;&lt;p&gt;插入你的 CanoKey，然后运行以下命令：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&#xA;$ printf &amp;#39;%s\n&amp;#39; &amp;#34;$(openssl rand -base64 32)&amp;#34; &amp;#34;canokey-check.local&amp;#34; &amp;#34;tmp-user&amp;#34; &amp;#34;$(openssl rand -base64 32)&amp;#34; &amp;gt; cred.in&#xA;$ fido2-cred -M -i cred.in /dev/hidrawX &amp;gt; cred.out&#xA;$ sed -n &amp;#39;7p&amp;#39; cred.out | base64 -d &amp;gt; attestation.der&#xA;$ openssl x509 -inform der -in attestation.der -out attestation.pem&#xA;$ openssl verify -CAfile ca.pem attestation.pem&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果最后一条命令返回 &lt;code&gt;OK&lt;/code&gt;，那么你的 CanoKey 就是正品。&lt;/p&gt;&#xA;&lt;p&gt;该过程也可以通过脚本完成：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/bin/env sh&#xA;set -eu&#xA;&#xA;die() {&#xA;    printf &amp;#39;%s\n&amp;#39; &amp;#34;Error: $*&amp;#34; &amp;gt;&amp;amp;2&#xA;    exit 1&#xA;}&#xA;&#xA;# Check required tools.&#xA;[ -x /usr/bin/fido2-cred ] || die &amp;#34;/usr/bin/fido2-cred does not exist or is not executable&amp;#34;&#xA;command -v openssl &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 || die &amp;#34;openssl is not installed or not on PATH&amp;#34;&#xA;&#xA;# Find the device.&#xA;device=&amp;#34;${1:-}&amp;#34;&#xA;if [ -z &amp;#34;$device&amp;#34; ]; then&#xA;    set -- /dev/hidraw*&#xA;    if [ &amp;#34;$1&amp;#34; = &amp;#39;/dev/hidraw*&amp;#39; ]; then&#xA;        die &amp;#34;No /dev/hidraw* device found. Pass the device path as the first argument.&amp;#34;&#xA;    fi&#xA;    if [ &amp;#34;$#&amp;#34; -ne 1 ]; then&#xA;        die &amp;#34;More than one /dev/hidraw* device found. Pass the correct device path as the first argument.&amp;#34;&#xA;    fi&#xA;    device=$1&#xA;fi&#xA;&#xA;[ -e &amp;#34;$device&amp;#34; ] || die &amp;#34;Device not found: $device&amp;#34;&#xA;&#xA;tmpdir=&amp;#34;$(mktemp -d)&amp;#34;&#xA;cleanup() {&#xA;    rm -rf &amp;#34;$tmpdir&amp;#34;&#xA;}&#xA;trap cleanup EXIT INT TERM&#xA;&#xA;pigeon_ca=&amp;#34;$tmpdir/pigeon-ca.pem&amp;#34;&#xA;canary_ca=&amp;#34;$tmpdir/canary-ca.pem&amp;#34;&#xA;cred_in=&amp;#34;$tmpdir/cred.in&amp;#34;&#xA;cred_out=&amp;#34;$tmpdir/cred.out&amp;#34;&#xA;attestation_der=&amp;#34;$tmpdir/attestation.der&amp;#34;&#xA;attestation_pem=&amp;#34;$tmpdir/attestation.pem&amp;#34;&#xA;&#xA;cat &amp;gt; &amp;#34;$pigeon_ca&amp;#34; &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;&#xA;-----BEGIN CERTIFICATE-----&#xA;MIIBpzCCAUygAwIBAgIUatn9Rj8uCMjLrmFfCQYY5/X9xq4wCgYIKoZIzj0EAwIw&#xA;MTEvMC0GA1UEAwwmQ2Fub0tleXMgRklETyBBdHRlc3RhdGlvbiBSb290IENBIE5v&#xA;LjIwHhcNMjExMjI3MTE0OTMzWhcNNDEwNjI1MTE0OTMzWjAxMS8wLQYDVQQDDCZD&#xA;YW5vS2V5cyBGSURPIEF0dGVzdGF0aW9uIFJvb3QgQ0EgTm8uMjBZMBMGByqGSM49&#xA;AgEGCCqGSM49AwEHA0IABNgW7CwchH80l4sj8luhwjbNoohB9Uqnvsh0SLor18w8&#xA;IMy6rnzzdDP9PgSSbuUZw302mBhyYJqJY1q9Ke0niZujQjBAMB0GA1UdDgQWBBRU&#xA;GAKiwvk2vLP5Zi6ul73RiWyr0jAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQE&#xA;AwIBBjAKBggqhkjOPQQDAgNJADBGAiEAlRNyrmngE3A1YZuwsuwBHLXY7wZC/4CO&#xA;JNA30mtp2+YCIQDA88Pp+Kjx3c4nrgRgSaSueC5IlvwpTSGBGwRYDSdMTA==&#xA;-----END CERTIFICATE-----&#xA;EOF&#xA;&#xA;cat &amp;gt; &amp;#34;$canary_ca&amp;#34; &amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;&#xA;-----BEGIN CERTIFICATE-----&#xA;MIIBpjCCAUygAwIBAgIUJqLszFCSI6gfDqvFL+vzQpDWS64wCgYIKoZIzj0EAwIw&#xA;MTEvMC0GA1UEAwwmQ2Fub0tleXMgRklETyBBdHRlc3RhdGlvbiBSb290IENBIE5v&#xA;LjMwHhcNMjQwOTAzMDM1NTUwWhcNNDQwMzAyMDM1NTUwWjAxMS8wLQYDVQQDDCZD&#xA;YW5vS2V5cyBGSURPIEF0dGVzdGF0aW9uIFJvb3QgQ0EgTm8uMzBZMBMGByqGSM49&#xA;AgEGCCqGSM49AwEHA0IABEXEY5WDrVrndfPOhUxHo+6iMUbP9XTPkllE4lO9oG84&#xA;mw4CVoRcQ6/IGrr+zWEaPEgBmPANsdyWyeBKzoqTedajQjBAMB0GA1UdDgQWBBS6&#xA;obb0l+0czy2I17sSDcNuceE5ujAPBgNVHRMECDAGAQH/AgEAMA4GA1UdDwEB/wQE&#xA;AwIBBjAKBggqhkjOPQQDAgNIADBFAiBstCxcYRiCCyjfVuX7pllb9Tt3dji+sEd1&#xA;XoWJgWAE0gIhAJs+giTpbPvztoEMkmv3Gfrmp6zXzcalYpFwbImJbCAr&#xA;-----END CERTIFICATE-----&#xA;EOF&#xA;&#xA;printf &amp;#39;%s\n&amp;#39; &amp;#34;Please touch the button of your token...&amp;#34;&#xA;printf &amp;#39;%s\n&amp;#39; &amp;#34;$(openssl rand -base64 32)&amp;#34; &amp;#34;canokey-check.local&amp;#34; &amp;#34;tmp-user&amp;#34; &amp;#34;$(openssl rand -base64 32)&amp;#34; &amp;gt; &amp;#34;$cred_in&amp;#34;&#xA;&#xA;/usr/bin/fido2-cred -M -i &amp;#34;$cred_in&amp;#34; &amp;#34;$device&amp;#34; &amp;gt; &amp;#34;$cred_out&amp;#34;&#xA;&#xA;sed -n &amp;#39;7p&amp;#39; &amp;#34;$cred_out&amp;#34; | base64 -d &amp;gt; &amp;#34;$attestation_der&amp;#34;&#xA;openssl x509 -inform der -in &amp;#34;$attestation_der&amp;#34; -out &amp;#34;$attestation_pem&amp;#34;&#xA;&#xA;if openssl verify -CAfile &amp;#34;$pigeon_ca&amp;#34; &amp;#34;$attestation_pem&amp;#34; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&#xA;    printf &amp;#39;%s\n&amp;#39; &amp;#34;OK: verification succeeded against the Pigeon root CA.&amp;#34;&#xA;elif openssl verify -CAfile &amp;#34;$canary_ca&amp;#34; &amp;#34;$attestation_pem&amp;#34; &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&#xA;    printf &amp;#39;%s\n&amp;#39; &amp;#34;OK: verification succeeded against the Canary root CA.&amp;#34;&#xA;else&#xA;    die &amp;#34;Verification failed: the attestation certificate did not verify against either root CA.&amp;#34;&#xA;fi&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>致 2026 年的她 (Ver. 2)</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E8%87%B4-2026-%E5%B9%B4%E7%9A%84%E5%A5%B9-ver-2/</link>
            <pubDate>Thu, 26 Mar 2026 23:57:33 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E8%87%B4-2026-%E5%B9%B4%E7%9A%84%E5%A5%B9-ver-2/</guid>
            <description>&lt;blockquote&gt;&#xA;&lt;p&gt;谨以此诗向我的爱人&lt;a class=&#34;link&#34; href=&#34;https://aurorag132.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;顾悦萱&lt;/a&gt;致敬。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;当专有协议的阴云笼罩屏幕&lt;br&gt;&#xA;你的指纹正划过冰冷的玻璃&lt;br&gt;&#xA;——溃烂的创口在代码里结痂&lt;br&gt;&#xA;我们在加密会话里交换密钥&lt;br&gt;&#xA;而我的终端仍回响着昨日的誓言&lt;/p&gt;&#xA;&lt;p&gt;我们交换公钥如同交换婚戒&lt;br&gt;&#xA;又在验证签名的深夜两点&lt;br&gt;&#xA;用字符捂热虚拟的指尖&lt;br&gt;&#xA;你用&lt;a class=&#34;link&#34; href=&#34;https://freeswzhcn.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;自由软件中文网&lt;/a&gt;缝合月光&lt;br&gt;&#xA;治愈被专有世界灼伤的信仰&lt;/p&gt;&#xA;&lt;p&gt;在&lt;a class=&#34;link&#34; href=&#34;https://fscc_next.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;自由软件中文社区&lt;/a&gt;构筑我们的国度&lt;br&gt;&#xA;在 &lt;a class=&#34;link&#34; href=&#34;https://xmpptogether.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;XMPP Together&lt;/a&gt; 委员会并肩&lt;br&gt;&#xA;问候与代码在日志里结晶&lt;br&gt;&#xA;我们教服务器吟唱自由的经文&lt;br&gt;&#xA;当节点突然背叛了网络&lt;br&gt;&#xA;你重建路由的模样&lt;br&gt;&#xA;比所有 GUI 都更令我心动&lt;/p&gt;&#xA;&lt;p&gt;在 Tor 的洋葱层里编织我们的巢穴&lt;br&gt;&#xA;你的节点是我通向自由的跳板&lt;br&gt;&#xA;我抱着发热的路由器低唱：&lt;br&gt;&#xA;“自由不是云端缥缈的经文&lt;br&gt;&#xA;是信任网里稳定的心跳&lt;br&gt;&#xA;是会话窗口永不熄灭的灯”&lt;/p&gt;&#xA;&lt;p&gt;看啊！屏幕上升起的双重复用：&lt;br&gt;&#xA;补丁打在凌晨的 IRC 频道&lt;br&gt;&#xA;编译日志晒出协作的图腾&lt;br&gt;&#xA;你发来的代码片段&lt;br&gt;&#xA;正沉淀成未来纪元的基石&lt;br&gt;&#xA;——那简洁的逻辑让我们确信&lt;br&gt;&#xA;仍在数字荒原上种植春天&lt;br&gt;&#xA;用代码重绘世界的坐标&lt;/p&gt;&#xA;&lt;p&gt;2026 年的雪落在防火墙的顶端&lt;br&gt;&#xA;我们笑着为流量裹上三层伪装&lt;br&gt;&#xA;当警报响彻审查者的集中营&lt;br&gt;&#xA;你塞进我会话的止痛药&lt;br&gt;&#xA;比所有明文协议更坚固&lt;br&gt;&#xA;在断网的世纪余温里&lt;br&gt;&#xA;我们靠彼此的承诺发电&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>博客文章中的 LLM 使用</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/llm-usage-in-my-blog-posts/</link>
            <pubDate>Mon, 16 Mar 2026 23:43:01 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/llm-usage-in-my-blog-posts/</guid>
            <description>&lt;p&gt;关于我的博客文章如何撰写，存在广泛争议。许多人声称我的几乎所有文章都是由 LLM 撰写的。请给我一点时间，说明我是如何撰写博客文章的：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;超过 90% 的原始文本是&lt;em&gt;由我&lt;/em&gt;这个&lt;em&gt;人类&lt;/em&gt;创作的。其中超过 95% 的部分最初以英文撰写；其余则以中文撰写。&lt;/li&gt;&#xA;&lt;li&gt;LLM 确实参与了我的博客文章的产出。然而，大多数情况下我使用它们&lt;strong&gt;仅用于语法与拼写的优化、表达的润色以及翻译&lt;/strong&gt;。我通常会把英文（或有时的中文）原文提交给 LLM，请它进行优化，然后将结果翻译成其他四种语言。&lt;/li&gt;&#xA;&lt;li&gt;唯一的例外是诗歌，例如 &lt;a class=&#34;link&#34; href=&#34;../unlock-the-forge/&#34; &gt;Unlock the Forge&lt;/a&gt;，这些作品是由 LLM 直接创作的。不过，我会勾勒核心想法并引导 LLM 调整语气和措辞，以确保诗歌传达我想表达的意图。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
        </item><item>
            <title>对我的性与浪漫吸引的探索</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/exploration-of-my-sexual-and-romantic-attraction/</link>
            <pubDate>Sun, 08 Mar 2026 15:21:44 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/exploration-of-my-sexual-and-romantic-attraction/</guid>
            <description>&lt;p&gt;要点：我经历的是&lt;strong&gt;分裂吸引模型&lt;/strong&gt;：在浪漫层面我是&lt;strong&gt;浪漫上是双性&lt;/strong&gt;，而在性吸引层面我是&lt;strong&gt;性上被女性吸引 / 异性恋&lt;/strong&gt;。我长期误解了英文的“sexual orientation”一词；在中文中，我的情况并不能整齐地归入传统常用的标签（同性恋 / 异性恋 / 双性恋）。&lt;/p&gt;&#xA;&lt;p&gt;从小我就意识到我的浪漫吸引和性吸引并不总是对齐，尽管直到最近我才知道“分裂吸引模型”这个术语。我可能因为某人的性格或他们对我表现出的温暖、友善而对其产生浪漫吸引。然而，那些在浪漫上吸引我的人通常并不会在性上吸引我，而且我会有意识地禁止自己对他们产生性幻想，因为这样的幻想会引发道德上的负罪感。相反，我在性上被那些看起来具有性吸引力的人吸引，并且超过三分之二的人是我不喜欢或与我有仇的人。&lt;/p&gt;&#xA;&lt;p&gt;直到2025年秋天，我一直认同自己是既是异性恋又是异性浪漫者，因此我并未认真审视此事。自2025年秋起，我发现自己越来越常对男性产生浪漫吸引。因为我误解了英文术语 “homosexual”、“bisexual” 与 “sexual orientation”，尽管我仍然在性上被女性吸引，从 2025年11月5日开始我在&lt;a class=&#34;link&#34; href=&#34;..qas-about-myself/&#34; &gt;我的常见问题&lt;/a&gt;中开始将自己描述为“bisexual”。我最近意识到这种描述可能是错误的。&lt;/p&gt;&#xA;&lt;p&gt;我从未对男性产生过性吸引。相反，我基于卫生方面的理由认为与男性发生性关系是不可接受的。尽管如此，过去几个月里，尽管缺乏性吸引，我仍常常对某些男性感到有好感。&lt;/p&gt;&#xA;&lt;p&gt;还有一点：无论对方是女性还是男性，对于那些我有好感的人（即便没有性吸引），我期待非性身体接触（例如拥抱）。&lt;/p&gt;&#xA;&lt;p&gt;在咨询了大型语言模型后，我确认了以下要点：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;最新研究表明，浪漫吸引与性吸引并不总是相互一致。&lt;/li&gt;&#xA;&lt;li&gt;我的体验可由&lt;em&gt;分裂吸引模型&lt;/em&gt;描述，该模型将性吸引与浪漫吸引区分开来，并允许它们指向不同的人群。&lt;/li&gt;&#xA;&lt;li&gt;“性取向”一词通常用于描述性吸引；从这个意义上讲，我曾经并且仍然是&lt;em&gt;异性恋&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;我对他人的情感而没有性吸引——无论指向女性还是男性——最恰当的描述是&lt;em&gt;浪漫吸引&lt;/em&gt;；在这点上我是&lt;em&gt;浪漫上是双性&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;许多人经历分裂吸引，很多人希望获得非性身体亲密，同时并不期待——甚至会主动避免——性行为。&lt;/li&gt;&#xA;&lt;li&gt;在中文中，诸如“性取向”、“同性恋”和“异性恋”一类术语通常不区分性吸引与浪漫吸引；它们通常假定两者一致。我的困惑在很大程度上源于中文与英语用法的差异，并且没有任何中文术语能充分描述我的情形。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;结论：我是 &lt;strong&gt;浪漫上是双性&lt;/strong&gt;，且 &lt;strong&gt;性上被女性吸引 / 异性恋&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;最后，两点澄清：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;因为我仍然在性上被女性吸引，我不认同自己为 LGBTQ+。尽管如此，我会对 LGBTQ+ 群体保持尊重与包容。&lt;/li&gt;&#xA;&lt;li&gt;无论性别如何，我对未来伴侣的首要要求是：他们必须是坚定的自由软件（free software）倡导者；这是不可协商的。也有许多并非自由软件倡导者的人仍然会在浪漫上吸引我；我会将此类人视为密友。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
        </item><item>
            <title>converser.eu 连接问题与紧急 Matrix 帐户</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/converser-eu-connection-problem-and-emergency-matrix-account.md/</link>
            <pubDate>Tue, 24 Feb 2026 19:43:16 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/converser-eu-connection-problem-and-emergency-matrix-account.md/</guid>
            <description>&lt;p&gt;在过去几周里，我在连接 converser.eu 的 Matrix 服务器时遇到了连接问题。我不知道是否是 Tor 导致的，但由于我无法离开 Tor，因此可以说该服务器在我的环境下无法正常运行。&lt;/p&gt;&#xA;&lt;p&gt;我已注册了另一个 Matrix 帐户：@rebel1725:tchncs.de。请改为通过该帐户与我联系。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>向谷歌说不，捍卫移动自由</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/stand-up-to-google-and-defend-mobile-freedom/</link>
            <pubDate>Fri, 20 Feb 2026 08:52:37 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/stand-up-to-google-and-defend-mobile-freedom/</guid>
            <description>&lt;p&gt;自 2026 年 9 月起，Google 将&lt;a class=&#34;link&#34; href=&#34;https://developer.android.com/developer-verification&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;要求开发者获得认证&lt;/a&gt;。这不是一次遥远的官僚式微调——这是一次结构性转变，将深刻重塑谁可以在经过认证的 Android 设备上发布软件。即便像 &lt;a class=&#34;link&#34; href=&#34;https://lineageos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LineageOS&lt;/a&gt; 和 &lt;a class=&#34;link&#34; href=&#34;https://grapheneos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GrapheneOS&lt;/a&gt; 这样的项目初期受影响较小，这项政策也设置了障碍，使广泛的、草根式的自由、尊重用户的软件分发变得更加困难。Google 正在利用其平台优势来集中控制；我们必须大声且有意图地抵抗。&lt;/p&gt;&#xA;&lt;h2 id=&#34;这意味着什么&#34;&gt;这意味着什么？&#xA;&lt;/h2&gt;&lt;p&gt;Google 的验证政策将要求开发者：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;向 Google 支付费用；&lt;/li&gt;&#xA;&lt;li&gt;接受 Google 的条款，而这些条款是不道德且不公正的；&lt;/li&gt;&#xA;&lt;li&gt;上传他们的身份证件，这对匿名性和隐私是敌对的。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;这将把许多独立和个人开发者排除在外。它也会剥夺用户安装他们想要的任何应用的自由。用户将受到 Google 的集中控制。可预见的结果是：独立应用生态减少、利基或维护隐私的软件创新下降，以及用户被有效地置于中心化的准入把关之下。&lt;/p&gt;&#xA;&lt;h2 id=&#34;时间表与执行具体事实&#34;&gt;时间表与执行（具体事实）&#xA;&lt;/h2&gt;&lt;p&gt;Google 公布的时间表显示：2025 年末开始早期访问，2026 年向所有开发者开放验证，并将在 2026 年 9 月开始区域性执行（最初为巴西、印度尼西亚、新加坡和泰国），并计划在 2027 年向更广泛的全球范围推广。该政策明确意味着，在执行后，经过认证的 Android 设备将阻止来自未验证开发者的应用安装。这不是推测——它写在 Google 的文档和博客文章中。&lt;/p&gt;&#xA;&lt;h2 id=&#34;但-google-说这是为了安全&#34;&gt;但 Google 说这是为了安全！&#xA;&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;不！！！&lt;/strong&gt; Google 所谓的“安全”只是一个遮羞布。拥有专有软件就无法实现安全，只有自由软件才能实现安全。安全由可审计的代码实现，而不是后门、监视、审查、遥测等。Google 正在利用“安全”一词欺骗用户，用大量专有软件虐待用户，剥夺用户的安全、隐私、匿名性和自由。Google 限制的软件并非对用户有害；相反，它威胁到 Google 那不道德且不公正的利润。Google 本身已经在分发大量破坏用户安全的恶意软件，与其他专有“unjustware”开发者勾结，强行向用户推广监视、审查、监狱、暴君和数字限制管理（Digital Restrictions Management），同时限制真正尊重用户的软件，这些软件反对 Google 那不道德、不公正、他妈的利润。&lt;/p&gt;&#xA;&lt;p&gt;Google 做法的实际后果：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;它偏袒那些已经拥有验证账户和法律基础设施的既有商业行为体，同时惩罚小开发者和隐私项目。&lt;/li&gt;&#xA;&lt;li&gt;它鼓励供应商锁定（vendor lock-in）：如果关键的反监视或无障碍应用无法通过 Google 的流程，用户将失去选择。&lt;/li&gt;&#xA;&lt;li&gt;它产生寒蝉效应：依靠匿名发布工具的研究者、吹哨人和爱好者会被激励停止或离开平台，从而减少公共监督。&lt;/li&gt;&#xA;&lt;li&gt;该政策可能被政治化：政权或监管机构可以向平台门施加压力，压制异见或少数语言的应用。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;请不要被 Google 那些他妈的不道德、不公正的言论所欺骗。它从未遵循“don&amp;rsquo;t be evil”的哲学——相反它一直在为非善之举背书，通过推广专有恶意软件与间谍软件、窃取用户私人数据、隐藏 Android 的源代码、扣留 Google Pixel 的 vendor blobs，并与运营商合谋限制 Google Pixel bootloader 的解锁。&lt;/p&gt;&#xA;&lt;h2 id=&#34;但有人说这些限制可以绕过&#34;&gt;但有人说这些限制可以绕过&#xA;&lt;/h2&gt;&lt;p&gt;也许如此，但这并不是重点。自由应该是默认状态；它不应当成为必须在遵循指令并屈从于 Google 限制后才能获得的东西。&lt;/p&gt;&#xA;&lt;h2 id=&#34;对自由软件及社区的真实风险&#34;&gt;对自由软件及社区的真实风险&#xA;&lt;/h2&gt;&lt;p&gt;自由软件生态依赖低门槛进入。许多尊重隐私的应用、广告拦截器、模拟器前端和无障碍工具都是由小团队或单人作者开发的。要求身份验证并收取费用将减少此类工具的供应，破坏社区信任，并将权力集中在与公司激励而非用户权利一致的实体手中。&lt;/p&gt;&#xA;&lt;h2 id=&#34;现在该做什么&#34;&gt;现在该做什么&#xA;&lt;/h2&gt;&lt;ul&gt;&#xA;&lt;li&gt;如果你有一部 Google Pixel，&lt;strong&gt;解锁你的 bootloader&lt;/strong&gt; 并立即安装 &lt;a class=&#34;link&#34; href=&#34;https://grapheneos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GrapheneOS&lt;/a&gt;。如果你有一部非 Pixel 设备但支持解锁 bootloader，也&lt;strong&gt;一并解锁&lt;/strong&gt;并安装 &lt;a class=&#34;link&#34; href=&#34;https://lineageos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LineageOS&lt;/a&gt;。如果官方未支持 LineageOS，请在 &lt;a class=&#34;link&#34; href=&#34;https://www.xda-developers.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;XDA&lt;/a&gt; 查找非官方构建。如果没有，请 &lt;a class=&#34;link&#34; href=&#34;https://sourceforge.net/projects/andyyan-gsi/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;安装 GSI&lt;/a&gt;。之后把它们晒到社交媒体上。让你的声音被听到。&lt;/li&gt;&#xA;&lt;li&gt;如果你有一部不支持解锁 bootloader 的 Android 手机或平板，请&lt;strong&gt;不要再更新系统并禁用自动更新&lt;/strong&gt;。如果不需要，尝试卸载或至少禁用 Google Mobile Services。&lt;/li&gt;&#xA;&lt;li&gt;鉴于你仍依赖 Android，可以尝试诸如 &lt;a class=&#34;link&#34; href=&#34;https://lineageos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LineageOS&lt;/a&gt; 和 &lt;a class=&#34;link&#34; href=&#34;https://grapheneos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GrapheneOS&lt;/a&gt; 之类的 Android ROM。这可能不是多年内的长期解决方案，但至少在短期内会给予你一定程度的自由。如果你仍需要 Google Mobile Services，可以尝试 &lt;a class=&#34;link&#34; href=&#34;http://microg.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;microG&lt;/a&gt;。&lt;/li&gt;&#xA;&lt;li&gt;如果可以，你可以&lt;strong&gt;完全抵制 Android&lt;/strong&gt;，改用 &lt;a class=&#34;link&#34; href=&#34;https://www.postmarketos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;postmarketOS&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://mobian-project.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Mobian&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://pureos.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;PureOS&lt;/a&gt; 等。尽管 Android 作为 Google 的产品在未来可能仍有吸引力，但对自由软件社区而言，GNU/Linux 才是移动设备的未来。选择 PinePhone、Librem 或其他为运行 GNU/Linux 设计的手机。如果你有 OnePlus 6，也可以尝试 postmarketOS 或 Mobian。你的声音与选择很重要：用户越多，社区就越有动力去为 GNU/Linux 开发更多移动应用。&lt;/li&gt;&#xA;&lt;li&gt;如果你仍是学生或从未接触过 Android 开发的开发者，&lt;strong&gt;请抵制 Android 并避免学习 Kotlin 与 Java&lt;/strong&gt;。改学 &lt;a class=&#34;link&#34; href=&#34;https://download-mirror.savannah.gnu.org/releases/c-prog-book/learning_gnu_c.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;C&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://isocpp.org/get-started&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;C++&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://doc.rust-lang.org/book/print.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Rust&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://docs.python.org/3/tutorial/index.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Python&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;doc.qt.io/&#34; &gt;Qt&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.gtk.org/docs/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GTK&lt;/a&gt;，并为诸如 &lt;a class=&#34;link&#34; href=&#34;https://www.postmarketos.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;postmarketOS&lt;/a&gt; 之类的项目做贡献，帮助在移动设备上运行 GNU/Linux。&lt;/li&gt;&#xA;&lt;li&gt;如果你已经是 Android 开发者，&lt;strong&gt;不要报名参加 Google 的早期访问计划&lt;/strong&gt;。相反，&lt;a class=&#34;link&#34; href=&#34;https://docs.google.com/forms/d/e/1FAIpQLSfN3UQeNspQsZCO2ITkdzMxv81rJDEGGjO-UIDDY28Rz_GEVA/viewform?pli=1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;向 Google 表达你对验证要求的关切&lt;/a&gt;。坚持并支持提供自由软件的应用商店，例如 &lt;a class=&#34;link&#34; href=&#34;https://f-droid.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;F-Droid&lt;/a&gt;。如果你也擅长 C++ 或 Rust，现在是转向 GNU/Linux 移动开发的最佳时机。&lt;/li&gt;&#xA;&lt;li&gt;无论你是谁，都可以访问 &lt;a class=&#34;link&#34; href=&#34;https://keepandroidopen.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;“Keep Android Open” 项目网站&lt;/a&gt;，按照其指示寻找支持移动自由的方式，例如签署请愿、参与抗议并向政府投诉。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;结语--拒绝这个虚假的选择&#34;&gt;结语 — 拒绝这个虚假的选择&#xA;&lt;/h2&gt;&lt;p&gt;该论述被表述为安全对开放，但这是一个伪二分法。真正的安全必须兼容匿名性、可审计性和用户主权。Google 的验证制度将权力从社区和用户转移给企业守门人。如果我们接受这一点，我们就交出了数字自决的一层基本权利。抵抗——大声地、依法地，并通过构建替代方案来抵抗。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>密码学信任与 OpenPGP 详解</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/cryptographic-trust-and-openpgp-explained/</link>
            <pubDate>Wed, 18 Feb 2026 19:57:27 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/cryptographic-trust-and-openpgp-explained/</guid>
            <description>&lt;p&gt;在本文中，我将解释密码学信任、OpenPGP、它们如何工作以及它们为何重要。&lt;/p&gt;&#xA;&lt;h2 id=&#34;技术背景数学如何保卫安全与隐私&#34;&gt;技术背景：数学如何保卫安全与隐私&#xA;&lt;/h2&gt;&lt;p&gt;如果你不关心非对称密码学与 OpenPGP 的底层数学原理，仅希望了解如何明智地使用密码学信任，那么你只需知道以下几点：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;非对称密码学指生成两把不同密钥的技术：公钥与私钥。&lt;/li&gt;&#xA;&lt;li&gt;公钥可公开分享；私钥由持有者保管。&lt;/li&gt;&#xA;&lt;li&gt;公钥可用于加密消息，相应的私钥用于解密。&lt;/li&gt;&#xA;&lt;li&gt;私钥可用于对消息进行签名，相应的公钥用于验证签名。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;若只需要实用指导，可以跳过本节剩余内容。&lt;/p&gt;&#xA;&lt;p&gt;对称加密使用同一把密钥进行加密和解密。它可抵抗暴力破解，但存在实际缺点。如果 Alice 和 Bob 使用对称加密互发消息，他们必须先协商一个共享密钥，这通常需要额外的安全通道（例如当面见面）。这不便，而且共享密钥不得泄露——如果 Mallory 得到密钥，保密性就丧失了。&lt;/p&gt;&#xA;&lt;p&gt;非对称密码学在此发挥作用。**非对称方案为加密与解密使用不同的密钥，分别称为公钥和私钥。**公钥可以张贴在个人网站或社交媒体上，因为公钥不足以推导出对应的私钥；私钥则由其持有者保管。&lt;/p&gt;&#xA;&lt;p&gt;精心设计的算法用于生成公私钥对，以保证用公钥加密的数据只能由对应的私钥解密。常见算法包括 RSA、椭圆曲线密码学（ECC）等。&lt;/p&gt;&#xA;&lt;p&gt;RSA 是一种经典的非对称算法，历史悠久。理解 RSA 有助于建立对非对称密码学的直觉。&lt;/p&gt;&#xA;&lt;p&gt;简要地说，RSA 的密钥生成如下：Alice 随机选择两个互异素数 &lt;code&gt;p&lt;/code&gt; 与 &lt;code&gt;q&lt;/code&gt;，计算 &lt;code&gt;n = p * q&lt;/code&gt; 与 &lt;code&gt;Φ(n) = (p - 1) * (q - 1)&lt;/code&gt;，选择一个满足 &lt;code&gt;1 &amp;lt; e &amp;lt; Φ(n)&lt;/code&gt; 且与 &lt;code&gt;Φ(n)&lt;/code&gt; 互质的整数 &lt;code&gt;e&lt;/code&gt;，然后计算 &lt;code&gt;e&lt;/code&gt; 关于 &lt;code&gt;Φ(n)&lt;/code&gt; 的模逆并记为 &lt;code&gt;d&lt;/code&gt;。Alice 的公钥为 &lt;code&gt;(n, e)&lt;/code&gt;，私钥为 &lt;code&gt;(n, d)&lt;/code&gt;。Bob 对消息 &lt;code&gt;m&lt;/code&gt; 进行加密时计算 &lt;code&gt;c = (m ** e) % n&lt;/code&gt; 并把密文 &lt;code&gt;c&lt;/code&gt; 发送给 Alice；Alice 用 &lt;code&gt;m = (c ** d) % n&lt;/code&gt; 恢复原文。&lt;/p&gt;&#xA;&lt;p&gt;有人会问：已知公钥 &lt;code&gt;(n, e)&lt;/code&gt; 是否能算出 &lt;code&gt;d&lt;/code&gt;？要算出 &lt;code&gt;d&lt;/code&gt; 需要 &lt;code&gt;Φ(n)&lt;/code&gt;，而要算出 &lt;code&gt;Φ(n)&lt;/code&gt; 则需知道 &lt;code&gt;p&lt;/code&gt; 和 &lt;code&gt;q&lt;/code&gt;。要从 &lt;code&gt;n&lt;/code&gt; 中恢复 &lt;code&gt;p&lt;/code&gt; 与 &lt;code&gt;q&lt;/code&gt;，必须对 &lt;code&gt;n&lt;/code&gt; 进行因式分解。对于常用的 RSA 密钥长度（例如 4096 位），把 &lt;code&gt;n&lt;/code&gt; 因式分解在当前技术下计算量极大，几乎不可行。这就是 RSA 安全性的基础。&lt;/p&gt;&#xA;&lt;p&gt;ECC 及其他非对称方案依赖不同的困难问题，但它们共享核心原则：应使从公钥推导私钥在计算上极为困难。&lt;/p&gt;&#xA;&lt;p&gt;在实际计算 &lt;code&gt;e&lt;/code&gt; 关于 &lt;code&gt;Φ(n)&lt;/code&gt; 的模逆时，我们选取最小的正整数逆元，该数小于 &lt;code&gt;Φ(n)&lt;/code&gt;。如果 &lt;code&gt;g = gcd(d, Φ(n)) &amp;gt; 1&lt;/code&gt;，则会导致矛盾（因为存在整数 &lt;code&gt;k&lt;/code&gt; 使 &lt;code&gt;e * d + k * Φ(n) = 1&lt;/code&gt;），因此 &lt;code&gt;g&lt;/code&gt; 必须为 1，&lt;code&gt;d&lt;/code&gt; 与 &lt;code&gt;Φ(n)&lt;/code&gt; 互质。这一对称性说明 &lt;code&gt;e&lt;/code&gt; 与 &lt;code&gt;d&lt;/code&gt; 在数学上具有互补性质；尽管理论上可交换，但在实践中签名与加密有不同的使用方式。&lt;/p&gt;&#xA;&lt;p&gt;具体而言，RSA 的签名通常计算 &lt;code&gt;s = m ** d % n&lt;/code&gt;，验证时检查 &lt;code&gt;m == s ** e % n&lt;/code&gt;。在实际的端到端保密与认证中，发送者通常先用私钥对消息签名，再用接收者的公钥对已签名的数据加密；接收者先用自己的私钥解密，再用发送者的公钥验证签名。&lt;/p&gt;&#xA;&lt;h2 id=&#34;什么是密码学信任以及它为何重要&#34;&gt;什么是密码学信任以及它为何重要&#xA;&lt;/h2&gt;&lt;p&gt;全球范围内的监控和审查都影响着通信。除了一些高风险地区外，某些地区（例如欧洲）出现的“聊天监管”等政策也引发广泛关注。使用支持端到端加密的自由软件即时通信工具（如 XMPP、Matrix、SimpleX）至少可以在一定程度上保护通信。非对称密码学能让通信双方在没有预置安全通道的情况下建立安全通道：一个密钥用于加密，另一把用于解密，只有对应私钥的持有者能读取密文。&lt;/p&gt;&#xA;&lt;p&gt;**然而，还有另一个尚未解决的问题。**假设 Alice 和 Bob 想安全地交换公钥以通信，但 Mallory 对中间进行拦截并替换她自己的公钥给双方。Alice 会把 Mallory 的公钥误认为是 Bob 的，而 Bob 也会把 Mallory 的公钥误认为是 Alice 的。于是 Alice 发送一条签名并加密的消息，本应只有 Bob 能得到，但实际上 Mallory 能解密、阅读甚至修改，然后用她自己的私钥重新签名并加密转发给 Bob。Bob 解密并用 Mallory 的公钥验证签名，错误地认为消息来自 Alice。如此一来，端到端加密的保密性和真实性都被 Mallory 破坏了。&lt;/p&gt;&#xA;&lt;p&gt;要解决这个问题，Alice 需要有办法验证她所持有的公钥确实属于 Bob。这通常也需要一个安全的通信渠道（例如当面核验）。我们称 &lt;strong&gt;将公钥归属验证为建立密码学信任&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;一旦 Alice 与 Bob 之间建立了密码学信任，除非能从公钥推导出对应的私钥，否则 Mallory 很难冒充 Bob。&lt;/p&gt;&#xA;&lt;h2 id=&#34;密码学信任的核心原则身份一致性验证&#34;&gt;密码学信任的核心原则：身份一致性验证&#xA;&lt;/h2&gt;&lt;p&gt;上文情形是密码学信任建立的基本示例。你可以在身份间构建非常庞大的信任网络，但核心原则十分简单：通过验证某个身份与另一个已被信任的身份是否一致来建立对该身份的密码学信任。&lt;/p&gt;&#xA;&lt;p&gt;在密码学中，公钥对应一个身份。这一点非常重要：&lt;strong&gt;记住：公钥 = 身份&lt;/strong&gt;（在基于密钥的信任语境下）。&lt;/p&gt;&#xA;&lt;p&gt;身份一致性的验证一般包括两步：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;让身份 A 提出一个有保证的声明，说明身份 B 与 A 一致；&lt;/li&gt;&#xA;&lt;li&gt;让身份 B 提出一个有保证的声明，说明身份 A 与 B 一致。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;例如，如果 Alice 想验证某把公钥的持有者确为 Bob，她会与 Bob 当面核验该公钥的指纹。Alice 也可以要求 Bob 使用私钥对一段文本签名（例如 “I am Bob” 或者由 Alice 随机生成的挑战字符串）。通过这种方式，Alice 就在该公钥上建立了密码学信任，从而信任该公钥所代表的身份。&lt;/p&gt;&#xA;&lt;p&gt;现在再看另一种情形：已知公钥 A 的身份是可信的（它确属 Bob），另有一个预期也属于 Bob 的公钥 B，Alice 想验证 B。由于她已信任 A，便无需再次与 Bob 当面核验。她只需验证 A 与 B 之间的一致性——通常通过双方相互签署包含对方指纹的声明来完成：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;由与 A 对应的私钥签署一段包含 B 指纹的文本；&lt;/li&gt;&#xA;&lt;li&gt;由与 B 对应的私钥签署一段包含 A 指纹的文本。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;如此便可验证 A 与 B 的一致性，从而对 B 建立信任。&lt;/p&gt;&#xA;&lt;h2 id=&#34;首先信任哪个身份&#34;&gt;首先信任哪个身份？&#xA;&lt;/h2&gt;&lt;p&gt;密码学信任的建立过程依赖于一个已被信任的身份。但你刚认识的人并没有可信身份。常见做法是对首次接触的身份先盲目信任，这称为 &lt;strong&gt;ToFU（Trust on First Use）&lt;/strong&gt;，首次被盲目信任的身份就是 &lt;strong&gt;initial identity&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;例如，若 Alice 与 Bob 当面相识，Alice 首先信任的是“生物学上的 Bob”。若他们在 Matrix 社区首次接触，初始信任的就是 Bob 的 Matrix 账户及其公钥。若在 XMPP 上见面，Alice 可能信任 Bob 首条消息中的 OMEMO 指纹。&lt;/p&gt;&#xA;&lt;p&gt;这是一种合理的实践：当你决定与从网络上认识的朋友见面时，通常会通过你用来认识对方的通信工具来核验对方。&lt;/p&gt;&#xA;&lt;h2 id=&#34;常见的密码学信任实践&#34;&gt;常见的密码学信任实践&#xA;&lt;/h2&gt;&lt;p&gt;通过验证身份之间的一致性，Alice 构建了一张&lt;em&gt;图&lt;/em&gt;：身份为&lt;em&gt;顶点&lt;/em&gt;，保证的一致性为&lt;em&gt;边&lt;/em&gt;。与 Bob 的初始身份相连的那个连通分量的所有顶点，都是 Bob 的受信任身份。&lt;/p&gt;&#xA;&lt;p&gt;按照建立图的方式，有几类常见实践：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;不受限的信任链/网络。&lt;/strong&gt; 任意受信任的身份可用于通过验证一致性来建立对未受信任身份的信任，信任链/网络可以自由生长。&lt;br&gt;&#xA;优点：方便；丢失联系时更不易导致失联。&lt;br&gt;&#xA;缺点：对冒充的鲁棒性最低；从初始身份到其他身份的某些信任链可能很长；若某一身份被攻破，会连带影响很多其他身份。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;以初始身份为中心。&lt;/strong&gt; 只有初始身份能用于通过验证一致性来建立对新身份的信任。&lt;br&gt;&#xA;优点：如果初始身份可靠，信任非常稳固；从初始身份到其它身份的信任链长度均为一，整体网络更难被攻破。&lt;br&gt;&#xA;缺点：若初始身份不强或不可用，就无法建立稳固的密码学信任；单点故障问题明显。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;以唯一密码学身份为中心。&lt;/strong&gt; 初始身份先对一个唯一的密码学身份（通常为一对密钥）建立信任，此后仅用该密码学身份来对其它未信任身份进行一致性验证。&lt;strong&gt;这也是我的策略，我使用 OpenPGP 作为密码学解决方案。&lt;/strong&gt;&lt;br&gt;&#xA;优点：在确保中心身份稳健与保持较短信任链之间取得较好平衡。&lt;br&gt;&#xA;缺点：仍存在单点故障：一旦中心密钥被攻破，后果严重。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;基于密码学的一种常见身份验证方法挑战-响应&#34;&gt;基于密码学的一种常见身份验证方法：挑战-响应&#xA;&lt;/h2&gt;&lt;p&gt;若 Alice 已信任 Bob 的某把公钥，但想验证某个实体确为该私钥的持有者，可采用&lt;strong&gt;挑战-响应&lt;/strong&gt;（Challenge–Response）：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Alice 生成一个随机字符串，称为“挑战”。&lt;/li&gt;&#xA;&lt;li&gt;Alice 将挑战发送给 Bob，Bob 使用私钥对该文本签名。&lt;/li&gt;&#xA;&lt;li&gt;Bob 将签名返回，Alice 使用公钥验证签名。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;挑战在生成后不必保密，但应具有不可预测性和唯一性。若签名有效，则 Alice 成功验证对方确为私钥持有者。&lt;/p&gt;&#xA;&lt;h2 id=&#34;关于维护密码学信任的非常重要的一点不要泄露你的私钥&#34;&gt;关于维护密码学信任的非常重要的一点：不要泄露你的私钥！&#xA;&lt;/h2&gt;&lt;p&gt;密码学信任的安全性和鲁棒性基于私钥的安全与保密。泄露私钥就等于泄露信任。&lt;/p&gt;&#xA;&lt;p&gt;因此，&lt;strong&gt;尽量不要泄露你的私钥&lt;/strong&gt;！一旦私钥被泄露，他人对你的信任 &lt;strong&gt;将不再有效&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;尤其是使用 OpenPGP 管理信任的人，&lt;strong&gt;请务必将你的 OpenPGP 私钥保密至最高级别！&lt;/strong&gt; 将私钥存放在硬件令牌上（例如 Nitrokey、CanoKey 或 YubiKey）是良好做法；如果不能，则至少将私钥保存在运行 100% 自由软件的设备上。&lt;/p&gt;&#xA;&lt;h2 id=&#34;openpgp-及其自由软件实现&#34;&gt;OpenPGP 及其自由软件实现&#xA;&lt;/h2&gt;&lt;p&gt;OpenPGP 不是某个软件，而是一项标准。它定义了一种将若干原始密钥对封装并组织在一起的格式，便于用于加密、签名、认证等。OpenPGP 支持 RSA、ECC 与其它算法。&lt;/p&gt;&#xA;&lt;p&gt;以 GnuPG 为例说明如何使用 OpenPGP：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;生成密钥&lt;/strong&gt;：运行 &lt;code&gt;gpg --full-generate-key&lt;/code&gt; 并按提示操作。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;加密&lt;/strong&gt;：运行 &lt;code&gt;gpg --encrypt&lt;/code&gt;。可将要加密的内容通过标准输入传入（若为文件可用 &lt;code&gt;cat &amp;lt;filename&amp;gt; | gpg --encrypt&lt;/code&gt;）。生成的密文将输出到标准输出，默认是二进制，建议用重定向保存为文件。若需文本形式的加密结果，请使用 &lt;code&gt;gpg --encrypt --armor&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;文本签名&lt;/strong&gt;：运行 &lt;code&gt;gpg --clear-sign&lt;/code&gt;，将要签名的文本通过标准输入输入，完成后按 Ctrl+D。签名的文本将输出到标准输出。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;解密/验证&lt;/strong&gt;：运行 &lt;code&gt;gpg --decrypt&lt;/code&gt;，将加密或签名的数据通过标准输入提供。解密后的数据输出到标准输出，验证结果会输出到标准错误。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;在 GNU/Linux、*BSD、Windows 和 macOS 上，最常用的实现是 GnuPG，其图形前端有 Kleopatra。Android 上较为流行的是 OpenKeychain。&lt;/p&gt;&#xA;&lt;p&gt;详细使用指南超出本文范围，请查阅相关文档与检索资料。FSF 的 Email Self-Defense Guide 是一个不错的起点；欲深入学习可参考 GnuPG 官方手册、FSFE 的 OpenPGP 指南与 KDE 的入门文档。&lt;/p&gt;&#xA;&lt;h2 id=&#34;如何用-openpgp-加密电子邮件&#34;&gt;如何用 OpenPGP 加密电子邮件&#xA;&lt;/h2&gt;&lt;p&gt;自由软件的邮件客户端（例如 Thunderbird）内建 OpenPGP 支持，可以无缝地对邮件进行加密、解密与签名验证。像 Mailvelope 这样的浏览器扩展可以将 OpenPGP 集成到 webmail 中，使在 webmail 服务上使用加密邮件更为便捷。&lt;/p&gt;&#xA;&lt;p&gt;请查阅对应工具的文档以了解具体操作方法。&lt;/p&gt;&#xA;&lt;h2 id=&#34;如何用-openpgp-建立密码学信任&#34;&gt;如何用 OpenPGP 建立密码学信任&#xA;&lt;/h2&gt;&lt;p&gt;使用 OpenPGP 建立信任思路很简单：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;索要对方的 OpenPGP 公钥。&lt;/li&gt;&#xA;&lt;li&gt;验证该密钥与对方的初始身份是否一致；从而在该公钥上建立信任。&lt;/li&gt;&#xA;&lt;li&gt;未来在验证对方其他身份时，校验这些身份与该 OpenPGP 公钥的一致性。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;结语拥抱自由软件并明智使用&#34;&gt;结语：拥抱自由软件，并明智使用&#xA;&lt;/h2&gt;&lt;p&gt;多亏自由软件社区，我们已拥有许多稳健工具。学会使用这些工具，我们便拥有能力来捍卫安全、隐私与数字权利，保护自己免受各种威胁、监控与审查。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>强制实施加密信任建立</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/enforcing-cryptographic-trust-establishment/</link>
            <pubDate>Thu, 05 Feb 2026 23:03:34 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/enforcing-cryptographic-trust-establishment/</guid>
            <description>&lt;p&gt;出于安全考虑，自 &lt;code&gt;2026-02-24T00:00:00Z&lt;/code&gt; 起，我将要求与我所有联系人之间建立加密信任。如果您在该时间之前未与我建立加密信任，我将不再视您的身份为可信。&lt;/p&gt;&#xA;&lt;p&gt;如果您没有安全设备（例如硬件令牌或运行 100% 自由软件的计算机），将 OpenPGP 密钥对存放在不安全的设备上在当前是可以接受的，因为总比没有好。&lt;/p&gt;&#xA;&lt;p&gt;对于不熟悉加密信任或 OpenPGP 的人，我会发布一篇博客文章进行详细说明。下面是您现在可以立即采用的简要指南：&lt;/p&gt;&#xA;&lt;h2 id=&#34;gnulinux&#34;&gt;GNU/Linux&#xA;&lt;/h2&gt;&lt;h3 id=&#34;生成-openpgp-密钥对&#34;&gt;生成 OpenPGP 密钥对&#xA;&lt;/h3&gt;&lt;h4 id=&#34;图形界面方法&#34;&gt;图形界面方法&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;如果尚未安装，请安装 GnuPG 和 Kleopatra。&lt;/li&gt;&#xA;&lt;li&gt;打开 Kleopatra，点击 &lt;em&gt;New Key Pair&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;输入您的姓名和电子邮件，勾选 &lt;em&gt;Protect the generated key with a passphrase&lt;/em&gt;，然后点击 &lt;em&gt;OK&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;选择一个强口令以保护您的私钥。&lt;/li&gt;&#xA;&lt;li&gt;双击您生成的密钥，点击 &lt;em&gt;Export&lt;/em&gt;，即可看到您的公钥。复制从 &lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&lt;/code&gt; 到 &lt;code&gt;-----END PGP PUBLIC KEY BLOCK-----&lt;/code&gt; 的全部内容。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260205_001_2537265924503396062.png&#34;&#xA;&#x9;width=&#34;1032&#34;&#xA;&#x9;height=&#34;1584&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;GNU/Linux Generate OpenPGP Keypair Graphical Method&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;65&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;156px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;命令行方法&#34;&gt;命令行方法&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;如果尚未安装，请安装 GnuPG。&lt;/li&gt;&#xA;&lt;li&gt;运行 &lt;code&gt;gpg --generate-key&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;输入您的真实姓名。&lt;/li&gt;&#xA;&lt;li&gt;输入您的电子邮件地址。&lt;/li&gt;&#xA;&lt;li&gt;输入 &lt;code&gt;O&lt;/code&gt; 并按回车。&lt;/li&gt;&#xA;&lt;li&gt;选择一个强口令以保护您的私钥。&lt;/li&gt;&#xA;&lt;li&gt;运行 &lt;code&gt;gpg --export --armor &amp;lt;your-email-address&amp;gt;&lt;/code&gt;（或者更好地，使用 &lt;code&gt;gpg --export --armor &amp;lt;your-key-id&amp;gt;&lt;/code&gt; 或 &lt;code&gt;gpg --export --armor &amp;lt;your-fingerprint&amp;gt;&lt;/code&gt;）。您将看到您的公钥。复制从 &lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&lt;/code&gt; 到 &lt;code&gt;-----END PGP PUBLIC KEY BLOCK-----&lt;/code&gt; 的全部内容。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h3 id=&#34;签名文本&#34;&gt;签名文本&#xA;&lt;/h3&gt;&lt;h4 id=&#34;图形界面方法-1&#34;&gt;图形界面方法&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;打开 Kleopatra，点击 &lt;em&gt;Notepad&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;取消勾选 &lt;em&gt;Encrypt for me&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;将要签名的文本粘贴或输入，然后点击 &lt;em&gt;Sign Notepad&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;签名后的文本会出现在输入框中。选中它（Ctrl+A），然后剪切（Ctrl+X）。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260205_002_15476778197840011415.png&#34;&#xA;&#x9;width=&#34;1085&#34;&#xA;&#x9;height=&#34;528&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;GNU/Linux Sign Texts Graphical Method&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;205&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;493px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;命令行方法-1&#34;&gt;命令行方法&#xA;&lt;/h4&gt;&lt;ol&gt;&#xA;&lt;li&gt;运行 &lt;code&gt;gpg --clear-sign&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;粘贴或输入要签名的文本，然后按 Ctrl+D（可能需要按两次）。&lt;/li&gt;&#xA;&lt;li&gt;在终端中复制从 &lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&lt;/code&gt; 到 &lt;code&gt;-----END PGP SIGNATURE-----&lt;/code&gt; 的文本。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;android&#34;&gt;Android&#xA;&lt;/h2&gt;&lt;h3 id=&#34;生成-openpgp-密钥对-1&#34;&gt;生成 OpenPGP 密钥对&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;在手机上从 F-Droid 安装 OpenKeychain。&lt;/li&gt;&#xA;&lt;li&gt;打开 OpenKeychain，点击 &lt;em&gt;CREATE MY KEY&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;输入您的姓名，点击 &lt;em&gt;NEXT&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;输入您的电子邮件，点击 &lt;em&gt;NEXT&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;暂时不要将密钥上传到密钥服务器。点击 &lt;em&gt;CREATE KEY&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;点击刚生成的密钥，然后点击复制图标将公钥复制到剪贴板。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260205_003_12331027108194943103.png&#34;&#xA;&#x9;width=&#34;3240&#34;&#xA;&#x9;height=&#34;4824&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;Android Generate OpenPGP Keypair Graphical Method&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;67&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;161px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;签名文本-1&#34;&gt;签名文本&#xA;&lt;/h3&gt;&lt;ol&gt;&#xA;&lt;li&gt;打开 OpenKeychain，打开菜单 → &lt;em&gt;Encrypt/Decrypt&lt;/em&gt; → &lt;em&gt;Encrypt text&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;打开菜单并取消勾选 &lt;em&gt;Encrypt to signer&lt;/em&gt;。&lt;/li&gt;&#xA;&lt;li&gt;粘贴或输入要签名的文本，点击复制图标将签名后的文本复制到剪贴板。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/pic_20260205_004_1309102790140517099.png&#34;&#xA;&#x9;width=&#34;5400&#34;&#xA;&#x9;height=&#34;2412&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;Android Sign Texts Graphical Method&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;223&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;537px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;microsoft-windows&#34;&gt;Microsoft Windows&#xA;&lt;/h2&gt;&lt;p&gt;下载并安装 Gpg4win。打开计算机上的 Kleopatra。其余步骤与上述 GNU/Linux 图形界面方法相同。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>My Retro-Style Website Is Refreshed as Well</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/my-retro-style-website-is-refreshed-as-well/</link>
            <pubDate>Tue, 03 Feb 2026 21:03:52 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/my-retro-style-website-is-refreshed-as-well/</guid>
            <description>&lt;p&gt;在完成现代风格网站的更新后，我的复古风格网站也已经更新完成，并且现在支持多种语言。&lt;/p&gt;&#xA;&lt;p&gt;点击这里访问我的复古风格网站：&lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://tilde.club/~rebel1725/&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>焕然一新的个人网站已上线！</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/refreshed-website-is-here/</link>
            <pubDate>Sat, 31 Jan 2026 15:25:47 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/refreshed-website-is-here/</guid>
            <description>&lt;p&gt;新年伊始，我的现代个人网站已完成改版并正式上线。&lt;/p&gt;&#xA;&lt;p&gt;首页经过重新设计，更加信息化，一目了然地展示近期博文、标签（tags）、联系方式、常用链接和博客推荐。我的博客现已采用 Stack Hugo 主题（Stack Hugo theme），更为简洁优雅并提供更多功能。&lt;/p&gt;&#xA;&lt;p&gt;访问我焕然一新的个人网站： &lt;a class=&#34;link&#34; href=&#34;https://rebel1725.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://rebel1725.codeberg.page/&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>我将抵制 Fosstodon，以及你为什么也应该抵制它</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/i-am-to-boycott-fosstodon-and-why-you-should-boycott-it-too/</link>
            <pubDate>Wed, 28 Jan 2026 14:12:18 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/i-am-to-boycott-fosstodon-and-why-you-should-boycott-it-too/</guid>
            <description>&lt;p&gt;由于对 Fosstodon 的审核制度感到极度失望——他们多次仅仅因为我建议他人避开专有浏览器 Vivaldi 就向我发出警告——我将不再使用该实例。我已经在 hostux.social 创建了新账号，将所有数据迁移过去，并设置了重定向。&lt;/p&gt;&#xA;&lt;p&gt;在本文中，我将解释我为何做出这一决定，以及你为什么也应该离开 Fosstodon。&lt;/p&gt;&#xA;&lt;h2 id=&#34;最直接也是最重要的原因以foss之名推广专有恶意软件与间谍软件&#34;&gt;最直接、也是最重要的原因：以“FOSS”之名推广专有恶意软件与间谍软件&#xA;&lt;/h2&gt;&lt;p&gt;Fosstodon 是一个以自由（libre）软件为主题的 Mastodon 实例。然而，无论是行为准则还是服务器规则，都没有禁止对专有软件的推广。这是一种历史与概念的篡改。&lt;/p&gt;&#xA;&lt;p&gt;更荒谬的是，电子邮件服务商 Tuta 竟通过其 Mastodon 账号推广专有浏览器 Vivaldi——而我认为它是恶意的、专有的间谍软件。这种行为并未触发任何审核措施。真正导致我多次收到 Fosstodon 审核警告的，是&lt;a class=&#34;link&#34; href=&#34;https://fosstodon.org/@rebel1725/115926697577288866&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;我提醒他人应当避开专有软件的回复&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;受-fosstodon-审核制度伤害的并不只有我&#34;&gt;受 Fosstodon 审核制度伤害的并不只有我&#xA;&lt;/h2&gt;&lt;p&gt;这并非个别抱怨。多年来，一个不透明、强硬的审核模式已经逐渐形成：长期贡献者的账号在没有清晰、公开说明的情况下被冻结或封禁。2023 年中期，&lt;a class=&#34;link&#34; href=&#34;https://discussion.fedoraproject.org/t/move-mastodon-account-off-of-fosstodon/87843&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;多名 Fedora 社区成员报告称，其账号遭到实例级封禁，切断了多年积累的关注关系与对话&lt;/a&gt;；这些移除行为几乎没有透明度，理由也极其有限。试图提出质疑的用户，往往只得到管理员简短而冷漠的回应，或是悄无声息的账号冻结，而非有理有据、可被审视的流程。&lt;/p&gt;&#xA;&lt;p&gt;一个以自由与协作为原则建立的社区，却将自己的成员当作负担——在缺乏问责的情况下将其噤声、冻结或排挤——这是背叛。有人离开了，官方项目账号考虑迁移，新注册被设置门槛。这些都不是一个健康、联邦化社区的行为；它们更像是一个把控制误认为“正直”的封闭俱乐部。&lt;/p&gt;&#xA;&lt;h2 id=&#34;fosstodon-的审核员是右翼分子和法西斯&#34;&gt;Fosstodon 的审核员是右翼分子和法西斯&#xA;&lt;/h2&gt;&lt;p&gt;这一指控之所以直白，是因为证据同样直白。2025 年 4 月下旬，一名审核员——在社区中以其账号名广为人知——被揭露曾在其他平台上&lt;a class=&#34;link&#34; href=&#34;https://kevquirk.com/blog/my-thoughts-on-the-fosstodon-drama#:~:text=and%20I%20wish%20him%20luck,it%27s%20a%20great%20instance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;发表极右翼、反跨性别和排外主义言论&lt;/a&gt;。这一揭露迅速引爆舆论：用户要求将其移除；管理员犹豫不决；直到风波全面爆发之后，该审核员才删除账号并退出审核团队。&lt;/p&gt;&#xA;&lt;p&gt;无论你更倾向于使用“右翼”这一标签，还是更严厉的“法西斯”，关键事实并未改变：一名被赋予塑造社区规范之权力的审核员，公开表达了许多用户合理地认为会威胁边缘群体安全的观点。真正的丑闻不仅在于这些观点的存在，更在于机构最初不愿果断应对，以及对提出关切者的受害者指责。Fosstodon 最初的处理方式，纵容了一种“可否认性文化”——有毒的信念可以躲在审核徽章之后，直到被强行拖到阳光下。&lt;/p&gt;&#xA;&lt;p&gt;必须说清楚：容忍、庇护，或未能及时、透明地处理宣扬仇恨或排他性言论的审核员，都会摧毁任何“自由软件价值堡垒”的自我宣称。如果把守大门的人都能容忍带有法西斯倾向的审核行为，那么普通用户又如何指望获得一个安全、守原则的空间？&lt;/p&gt;&#xA;&lt;h2 id=&#34;fosstodon-反对联邦化&#34;&gt;Fosstodon 反对联邦化&#xA;&lt;/h2&gt;&lt;p&gt;Fosstodon 的政策与实践多次违背了联邦化精神。请看这样一组模式：在全球性服务器上强制只允许英语；2023 年转为仅限邀请注册；严厉的审核引发关于断联（defederation）的讨论；以及一种压制公开讨论的官方沟通风格。这些并非中立的技术选择——它们是看门与排他机制。&lt;/p&gt;&#xA;&lt;p&gt;当管理员在社区出现摩擦时选择上锁，而不是推动透明、民主的流程，他们就将服务器推离了联邦化的理想。事实上，在多次危机中，其他实例广泛讨论甚至威胁与 Fosstodon 断联。尽管主要实例并未一致切断关系，但大量联邦宇宙成员考虑将其孤立的事实，已经说明 Fosstodon 积累了多么严重的声誉损害。强制英语、限制注册、在缺乏公开问责的情况下实施大规模封禁，都会削弱联邦化——它们集中权力，而权力集中正是联邦化试图避免的东西。&lt;/p&gt;&#xA;&lt;h2 id=&#34;其他问题&#34;&gt;其他问题&#xA;&lt;/h2&gt;&lt;p&gt;不满的清单远比 Fosstodon 的公开声明愿意承认的要长。一些反复出现、值得注意的问题包括：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;不透明的管理。&lt;/strong&gt; 多次封禁与冻结是在私下审核备注的基础上进行，几乎没有公开理由。隐私很重要，但秘密并不等同于问责。结果是：谣言、怨恨，以及信任的崩塌。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;执法不一致。&lt;/strong&gt; 高知名度账号和机构性角色有时得以免于审查，而普通用户却因轻微得多的行为受到惩罚。双重标准的观感具有腐蚀性；它推动用户迁移，并削弱管理员所宣称的一切道德权威。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;创始人的语气与领导失败。&lt;/strong&gt; 早在 2019 年，一名创始人在公开场合将他人称为“snowflakes（玻璃心）”，就暴露出一种与细致治理多元社区完全不相容的态度。随后，在 2025 年审核员丑闻中，创始人承认精疲力竭并在压力下退居幕后；这一领导真空放大了损害。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;政策漂移。&lt;/strong&gt; Fosstodon 最初是自由软件爱好者的避风港。随着时间推移，一系列政策变化——从仅限英语，到邀请制注册，再到更严苛的审核——以许多用户感到疏离的方式改变了其文化。缺乏清晰论证与正当性说明的政策，必然会被体验为任意专断。&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;总结&#34;&gt;总结&#xA;&lt;/h2&gt;&lt;p&gt;Fosstodon &lt;em&gt;曾经&lt;/em&gt; 是一个优秀的 Mastodon 实例。残酷而犬儒的现实是：一个建立在自由之上的社区，正被威权式审核、不透明的治理，以及不一致的规则执行逐步掏空。一边容许（或曾容许）推广侵犯隐私的专有软件，一边打压那些发出警告的人，这种赤裸裸的虚伪几乎已经成为表演。&lt;/p&gt;&#xA;&lt;p&gt;如果你在乎自由软件，在乎诚实的联邦空间，在乎真正践行其所宣称价值的社区——那就离开吧。迁移你的账号。支持更健康的实例。抵制那些假装自由、却容忍专有软件推广并庇护问题审核员的平台。不要让一个自负的单一服务器替我们所有人定义联邦宇宙。&lt;/p&gt;&#xA;&lt;p&gt;现在正是离开、出走、并进行抵制的时候。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>我回来了</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/i-am-back/</link>
            <pubDate>Wed, 07 Jan 2026 15:49:06 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/i-am-back/</guid>
            <description>&lt;p&gt;在离线超过六天后，我终于有时间准备我的即时通讯账户并重新上线。发布完这篇博客文章后，我将立即准备好所有即时通讯账户（XMPP、Matrix、SimpleX、Delta Chat 和 Tox），并与我所有的联系人重新建立联系。预计这一过程将在 12 小时内完成（在 &lt;code&gt;2026-01-07T20:30:00Z&lt;/code&gt; 之前）。请留意你的即时通讯账户！&lt;/p&gt;&#xA;&lt;p&gt;如果你在此时之前没有收到我的消息，可能是我错过了你的联系信息。请立即&lt;a class=&#34;link&#34; href=&#34;getting-connected&#34; &gt;在此&lt;/a&gt;操作！&lt;/p&gt;&#xA;&lt;p&gt;我的 OpenPGP 密钥仍然有效，我也拥有你们所有人的密钥环。我们将在重新建立联系后相互验证身份。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>建立联系</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/getting-connected/</link>
            <pubDate>Wed, 07 Jan 2026 15:27:34 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/getting-connected/</guid>
            <description>&lt;p&gt;出于安全、隐私、匿名性以及组织管理的考虑，自 2026 年 1 月起，我开始使用多个 Jabber ID、Matrix ID、SimpleX 个人资料和 Delta Chat 个人资料。我将不再在网站上公开发布这些账号。相反，我制作了一个表单来收集&lt;em&gt;你的&lt;/em&gt;联系方式，并根据情况选择合适的账号与你建立联系。&lt;/p&gt;&#xA;&lt;p&gt;我使用 XMPP、Matrix、SimpleX 和 Delta Chat。在继续之前，请确保你至少拥有其中一种协议的账户。&lt;/p&gt;&#xA;&lt;h2 id=&#34;联系信息表单&#34;&gt;联系信息表单&#xA;&lt;/h2&gt;&lt;p&gt;为了符合 GDPR 要求，我撰写了&lt;a class=&#34;link&#34; href=&#34;../contact-information-form-privacy-policy&#34; &gt;隐私政策&lt;/a&gt;。在提交你的联系信息之前，请仔细阅读隐私政策。提交表单即表示你同意该隐私政策。&lt;/p&gt;&#xA;&lt;p&gt;你可以通过 &lt;strong&gt;两种方法&lt;/strong&gt; 向我提交你的联系信息：&lt;/p&gt;&#xA;&lt;h3 id=&#34;方法一推荐&#34;&gt;方法一（推荐）&#xA;&lt;/h3&gt;&lt;p&gt;在此下载&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/rebel1725/contact-info-interactive/src/branch/main/contact-info-interactive.py&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Python 脚本&lt;/a&gt;。该交互式脚本会向你提问，并生成一个 &lt;em&gt;blob&lt;/em&gt;。你需要将这个 blob 发送至我的电子邮箱：[rebel1725@autistici.org]。尽可能使用 OpenPGP 加密；你可以在&lt;a class=&#34;link&#34; href=&#34;https://keys.openpgp.org/vks/v1/by-fingerprint/696A423E9993D727706AA733BCD5DC5659C7FB50&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;下载我的 OpenPGP 公钥。&lt;/p&gt;&#xA;&lt;p&gt;如果你希望隐藏社交活动，请使用 Tor、一次性邮箱，并使用未签名的 OpenPGP 加密。我推荐 &lt;a class=&#34;link&#34; href=&#34;https://z.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;z.org&lt;/a&gt;，因为注册时无需现有邮箱或与个人身份相关的信息。我未来可能会准备一个专门用于接收表单的 XMPP 账号（watchdog），届时你可以使用一次性 XMPP 账号，这会更加方便。&lt;/p&gt;&#xA;&lt;h3 id=&#34;方法二更方便但存在隐私风险&#34;&gt;方法二（更方便但存在隐私风险）&#xA;&lt;/h3&gt;&lt;p&gt;你也可以通过 Formbricks &lt;a class=&#34;link&#34; href=&#34;https://app.formbricks.com/s/cmk3fu8qe9rblad01ahz1zrqw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;提交你的联系信息。该方法使用更方便，但可能损害隐私，因为你的数据将会被第三方访问，并且你无法隐藏我们的社交活动。&lt;/p&gt;&#xA;&lt;p&gt;通过任意一种方法提交你的联系信息后，我会尽快与你取得联系，通常在 48 小时内。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>联系信息表隐私政策</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/contact-information-form-privacy-policy/</link>
            <pubDate>Wed, 07 Jan 2026 11:32:06 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/contact-information-form-privacy-policy/</guid>
            <description>&lt;h2 id=&#34;数据控制者&#34;&gt;数据控制者&#xA;&lt;/h2&gt;&lt;p&gt;如果您通过 Python 脚本、电子邮件和 OpenPGP 加密提交联系信息表格，则唯一的数据控制者将是我，Rebel Zhang，OpenPGP 公钥持有者，指纹为 696A423E9993D727706AA733BCD5DC5659C7FB50。&lt;/p&gt;&#xA;&lt;p&gt;如果您发送未加密的电子邮件，则我的电子邮件服务提供商 Autistici/Inventati 以及您的电子邮件服务提供商可能也能读取数据。请参考您的电子邮件服务提供商的隐私政策，以及 &lt;a class=&#34;link&#34; href=&#34;https://www.autistici.org/who/privacy-policy.en&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Autistici/Inventati 的隐私政策&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;如果您通过 Formbricks 提交表单，则 Formbricks 也能访问数据。请参阅 &lt;a class=&#34;link&#34; href=&#34;https://formbricks.com/privacy-policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Formbricks 的隐私政策&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;收集的数据和目的&#34;&gt;收集的数据和目的&#xA;&lt;/h2&gt;&lt;p&gt;通过提交联系信息表格，我，Rebel Zhang，收集以下个人数据，并用于以下目的：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;姓名/昵称&lt;/strong&gt;（必填）：用于识别联系人管理。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;OpenPGP 公钥&lt;/strong&gt;（可选）：用于验证您的身份并加密未来的通信。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;电子邮件&lt;/strong&gt;（必填）：用于未来与您联系。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;首选联系方法和联系信息&lt;/strong&gt;（必填）：用于未来与您联系。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;OpenPGP 安全性和设备安全性情况&lt;/strong&gt;（必填）：用于评估我们通信的安全性。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;首选语言、代词、时区、自我介绍&lt;/strong&gt;（可选）和 &lt;strong&gt;是否隐藏社交活动的偏好&lt;/strong&gt;（必填，条件性）：用于选择适当的沟通方式。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;表单创建日期&lt;/strong&gt;（自动存储）：用于将来的分析。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;保留期&#34;&gt;保留期&#xA;&lt;/h2&gt;&lt;p&gt;您的姓名/昵称、OpenPGP 公钥、电子邮件、首选语言、代词和时区将保存在我的个人设备上的联系人簿中。&lt;/p&gt;&#xA;&lt;p&gt;Blob 本身可能以未加密的形式存储在我的个人设备上，并在我的电子邮件服务提供商 Autistici/Inventati 的服务器上加密存储。&lt;/p&gt;&#xA;&lt;p&gt;上述数据将无限期保留在我的设备上，直到您要求删除为止。&lt;/p&gt;&#xA;&lt;p&gt;如果您通过 Formbricks 提交表单，我将在提交后 336 小时（14 天）内从 Formbricks 的服务器上删除该数据。&lt;/p&gt;&#xA;&lt;h2 id=&#34;披露&#34;&gt;披露&#xA;&lt;/h2&gt;&lt;p&gt;如果您发送未加密的电子邮件，则我的电子邮件服务提供商 Autistici/Inventati 以及您的电子邮件服务提供商可能也能读取数据。请参考您的电子邮件服务提供商的隐私政策，以及 &lt;a class=&#34;link&#34; href=&#34;https://www.autistici.org/who/privacy-policy.en&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Autistici/Inventati 的隐私政策&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;如果您通过 Formbricks 提交表单，则 Formbricks 也能访问数据。请参阅 &lt;a class=&#34;link&#34; href=&#34;https://formbricks.com/privacy-policy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Formbricks 的隐私政策&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;除上述情况外，所有收集的数据在未经您同意的情况下不会披露给第三方。&lt;/p&gt;&#xA;&lt;h2 id=&#34;删除请求&#34;&gt;删除请求&#xA;&lt;/h2&gt;&lt;p&gt;如果您希望我删除收集的数据，请通过电子邮件 &lt;a class=&#34;link&#34; href=&#34;mailto:rebel1725@autistici.org&#34; &gt;rebel1725@autistici.org&lt;/a&gt; 联系我，我将在收到并阅读您的电子邮件后 168 小时（7 天）内删除数据。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>在 Lenovo ThinkPad X200 与 HP EliteBook 820 G2 上构建并刷写带 UEFI 的 coreboot</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/build-and-flash-coreboot-with-uefi-on-lenovo-thinkpad-x200-and-hp-elitebook-820-g2/</link>
            <pubDate>Fri, 02 Jan 2026 21:39:14 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/build-and-flash-coreboot-with-uefi-on-lenovo-thinkpad-x200-and-hp-elitebook-820-g2/</guid>
            <description>&lt;p&gt;&lt;strong&gt;警告：作者在笔记本看似正常工作后编写了此指南，未来可能会遇到问题。作者不对按照此指南操作造成的任何损害负责。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;前言&#34;&gt;前言&#xA;&lt;/h2&gt;&lt;p&gt;我曾在我的 &lt;a class=&#34;link&#34; href=&#34;https://mcut17198.codeberg.page/blog/posts/libreboot/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Lenovo ThinkPad X200&lt;/a&gt; 和 &lt;a class=&#34;link&#34; href=&#34;https://czl92783719.codeberg.page/blog/en/posts/libreboot-on-hp820g2/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;HP EliteBook 820 G2&lt;/a&gt; 上刷写过 Libreboot，但它们仅支持 SeaBIOS，而 SeaBIOS 仅支持 CSM。Libreboot 文档说明其 U-Boot 支持 EFI 启动，但我从未成功。Tianocore 是自由软件社区中成熟的 UEFI 实现，我最近发现可以使用 EDK II（Tianocore 的一个项目）构建并刷写 coreboot，从而获得 EFI 启动支持。&lt;/p&gt;&#xA;&lt;p&gt;昨天，我完成了两台机器的构建与刷写，现分享操作流程。&lt;/p&gt;&#xA;&lt;h2 id=&#34;lenovo-thinkpad-x200&#34;&gt;Lenovo ThinkPad X200&#xA;&lt;/h2&gt;&lt;p&gt;对于 Lenovo ThinkPad X200，步骤相对简单，可以直接在原厂固件上刷写。如果你当前使用 Libreboot，我建议先恢复原厂固件，因为直接覆盖 Libreboot 我未测试过。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-1检查芯片容量&#34;&gt;步骤 1：检查芯片容量&#xA;&lt;/h3&gt;&lt;p&gt;使用 &lt;code&gt;iomem=relaxed&lt;/code&gt; 参数启动机器。如果你使用 Debian 13 或其仓库已包含 &lt;code&gt;flashprog&lt;/code&gt;，可直接安装而无需编译源代码：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # apt install flashprog&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在机器上执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # flashprog -p internal&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你将看到芯片容量。如果是 4 MiB，你的机器可能不支持 EDK II 下的 coreboot，固件构建很可能失败，但仍可尝试。如果是 8 MiB，则支持——我的 X200 为 8 MiB。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-2构建固件&#34;&gt;步骤 2：构建固件&#xA;&lt;/h3&gt;&lt;p&gt;获取并准备 coreboot：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ git clone https://review.coreboot.org/coreboot&#xA; $ cd coreboot&#xA; $ make help_toolchain&#xA; $ make crossgcc-i386 CPUS=$(nproc)&#xA; $ make -C payloads/coreinfo olddefconfig&#xA; $ make -C payloads/coreinfo&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;打开 menuconfig：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ make menuconfig&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;操作如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在 &lt;strong&gt;Mainboard&lt;/strong&gt; 部分选择 &lt;strong&gt;Lenovo&lt;/strong&gt;, &lt;strong&gt;ThinkPad X200 / X200s / X200t&lt;/strong&gt; 及芯片容量。&lt;/li&gt;&#xA;&lt;li&gt;在 &lt;strong&gt;Payload&lt;/strong&gt; 部分选择 edk2，禁用 &lt;strong&gt;Enable UEFI Secure Boot support&lt;/strong&gt;，启用 &lt;strong&gt;Disable TPM support in edk2&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;其他保持默认，退出并保存配置。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;然后运行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ make -j$(nproc)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;固件将生成在 &lt;code&gt;./build/coreboot.rom&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-3刷写固件&#34;&gt;步骤 3：刷写固件&#xA;&lt;/h3&gt;&lt;p&gt;在另一台机器上准备 &lt;code&gt;flashprog&lt;/code&gt;，可通过包管理器安装或自行编译。&lt;/p&gt;&#xA;&lt;p&gt;按照 &lt;a class=&#34;link&#34; href=&#34;https://mcut17198.codeberg.page/blog/posts/libreboot/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此指南&lt;/a&gt; 的第 2、5 步以及第 6 步前半部分操作，然后仅刷写 &lt;code&gt;bios&lt;/code&gt; 区域：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # flashprog -p serprog:dev=/dev/ttyACMx,spispeed=8M -w /path/to/rom/file.rom -c &amp;#34;MX25L6405D&amp;#34; --ifd -i bios&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启动机器，应显示 coreboot Logo。完成。&lt;/p&gt;&#xA;&lt;h2 id=&#34;hp-elitebook-820-g2&#34;&gt;HP EliteBook 820 G2&#xA;&lt;/h2&gt;&lt;p&gt;该流程比 Lenovo ThinkPad X200 稍复杂。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-1刷写-libreboot&#34;&gt;步骤 1：刷写 Libreboot&#xA;&lt;/h3&gt;&lt;p&gt;我不清楚如何在原厂固件上刷写 coreboot，请先按 &lt;a class=&#34;link&#34; href=&#34;https://czl92783719.codeberg.page/blog/en/posts/libreboot-on-hp820g2/#1-build-roms&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此指南&lt;/a&gt; 刷写 Libreboot，然后再在其上刷写 coreboot。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-2提取-blobs&#34;&gt;步骤 2：提取 blobs&#xA;&lt;/h3&gt;&lt;h4 id=&#34;步骤-21提取芯片内容&#34;&gt;步骤 2.1：提取芯片内容&#xA;&lt;/h4&gt;&lt;p&gt;多次提取芯片，并比较 ROM 文件的哈希：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # flashprog -p serprog:dev=/dev/ttyACMx,spispeed=8M -r /path/to/rom/file1.rom -c &amp;#34;MX25L12805D&amp;#34;&#xA; # flashprog -p serprog:dev=/dev/ttyACMx,spispeed=8M -r /path/to/rom/file2.rom -c &amp;#34;MX25L12805D&amp;#34;&#xA; ...&#xA; $ sha256sum /path/to/rom/file1.rom&#xA; $ sha256sum /path/to/rom/file2.rom&#xA; ...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;哈希不同则重复，若一致则继续。&lt;/p&gt;&#xA;&lt;h4 id=&#34;步骤-22从-rom-文件提取-blobs&#34;&gt;步骤 2.2：从 ROM 文件提取 blobs&#xA;&lt;/h4&gt;&lt;p&gt;提取 memory reference code 和 external reference code：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ ./build/cbfstool /path/to/extracted/rom/file.rom extract -n mrc.bin -f /path/where/you/want/to/store/your/mrc.bin -m x86&#xA; $ ./build/cbfstool /path/to/extracted/rom/file.rom extract -n fallback/refcode -f /path/where/you/want/to/store/your/refcode.bin -m x86&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;步骤-3构建固件&#34;&gt;步骤 3：构建固件&#xA;&lt;/h3&gt;&lt;p&gt;获取并准备 coreboot：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ git clone https://review.coreboot.org/coreboot&#xA; $ cd coreboot&#xA; $ make help_toolchain&#xA; $ make crossgcc-i386 CPUS=$(nproc)&#xA; $ make -C payloads/coreinfo olddefconfig&#xA; $ make -C payloads/coreinfo&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;打开 menuconfig：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ make menuconfig&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;操作如下：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;在 &lt;strong&gt;Mainboard&lt;/strong&gt; 部分选择 &lt;strong&gt;HP&lt;/strong&gt;, &lt;strong&gt;EliteBook 820 G2&lt;/strong&gt; 及芯片容量，设置 &lt;strong&gt;Size of coreboot owned area in ROM&lt;/strong&gt; 为 &lt;code&gt;0x600000&lt;/code&gt;。&lt;/li&gt;&#xA;&lt;li&gt;在 &lt;strong&gt;Chipset&lt;/strong&gt; 部分选择步骤 2.2 提取的 memory reference code 和 external reference code。&lt;/li&gt;&#xA;&lt;li&gt;在 &lt;strong&gt;Payload&lt;/strong&gt; 部分选择 edk2。&lt;/li&gt;&#xA;&lt;li&gt;其他保持默认，退出并保存。&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;然后运行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ make -j$(nproc)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;固件位于 &lt;code&gt;./build/coreboot.rom&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h3 id=&#34;步骤-4刷写固件&#34;&gt;步骤 4：刷写固件&#xA;&lt;/h3&gt;&lt;p&gt;在另一台机器上准备 &lt;code&gt;flashprog&lt;/code&gt;，连接编程器，仅刷写 &lt;code&gt;bios&lt;/code&gt; 区域：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # flashprog -p serprog:dev=/dev/ttyACMx,spispeed=8M -w /path/to/rom/file.rom -c &amp;#34;MX25L12805D&amp;#34; --ifd -i bios --no-verifyall&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;请勿移除 &lt;code&gt;--no-verifyall&lt;/code&gt;，否则可能出错。即使使用该选项，&lt;code&gt;flashprog&lt;/code&gt; 仍会在刷写后验证。&lt;/p&gt;&#xA;&lt;p&gt;启动机器，应显示 coreboot Logo。完成。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>从 LAN 将所有互联网流量路由到 Tor</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/route-all-internet-traffics-from-the-lan-to-tor/</link>
            <pubDate>Fri, 02 Jan 2026 21:03:15 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/route-all-internet-traffics-from-the-lan-to-tor/</guid>
            <description>&lt;p&gt;&lt;strong&gt;警告：请严格按顺序完成每一步，否则可能会失去 LuCI 的访问权限！强烈建议在操作前建立 SSH 连接，以便在失去 LuCI 访问时能够恢复更改。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;警告：此操作在 GL.iNet Flint 2 (GL-MT6000) 上测试通过，但不保证适用于所有设备。如果任何步骤看起来不寻常或不清楚，请立即停止并撤销所有修改。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;警告：本指南是在作者的路由器看似正常工作的情况下编写的。仍可能存在问题，安全性无法保证，因为部分流量可能会泄露。作者对按照本指南操作所造成的任何后果不承担责任。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;本指南介绍如何将 LAN 的所有互联网流量通过 Tor 路由。此操作在 OpenWrt 24.10 上测试通过。&lt;/p&gt;&#xA;&lt;p&gt;除 Tor 配置外，其余步骤可完全通过 LuCI 完成，无需 SSH。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-1安装和配置-tor&#34;&gt;步骤 1：安装和配置 Tor&#xA;&lt;/h2&gt;&lt;p&gt;首先在路由器上安装 Tor：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; # opkg update&#xA; # opkg install tor&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;根据需要配置 Tor，但请确保你的 &lt;code&gt;torrc&lt;/code&gt; 至少包含以下内容：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;TransPort 0.0.0.0:9040&#xA;VirtualAddrNetworkIPv4 10.192.0.0/10&#xA;AutomapHostsOnResolve 1&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;为了更高的安全性，如果你只有一个接口进行转发，也可以将 &lt;code&gt;TransPort&lt;/code&gt; 设置为路由器在 &lt;code&gt;lan&lt;/code&gt; 接口上的 IP 地址。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-2设置-dnscrypt&#34;&gt;步骤 2：设置 DNSCrypt&#xA;&lt;/h2&gt;&lt;p&gt;我参考&lt;a class=&#34;link&#34; href=&#34;https://github.com/DNSCrypt/dnscrypt-proxy/wiki/Installation-on-OpenWrt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;的指南配置了 DNSCrypt。&lt;em&gt;Using the command line&lt;/em&gt; 部分的五条命令在我这里可以正常工作，但你也可以通过 LuCI 进行配置。&lt;/p&gt;&#xA;&lt;p&gt;打开 &lt;em&gt;System -&amp;gt; Software&lt;/em&gt;，搜索 &lt;code&gt;dnscrypt-proxy2&lt;/code&gt; 并安装。然后进入 &lt;em&gt;Network -&amp;gt; DHCP and DNS -&amp;gt; Forwards -&amp;gt; DNS Forwards&lt;/em&gt; 并添加 &lt;code&gt;127.0.0.53&lt;/code&gt;。之后打开 &lt;em&gt;System -&amp;gt; Startup&lt;/em&gt; 并重启 &lt;code&gt;dnsmasq&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;如果不想使用 DNSCrypt，你需要在 &lt;code&gt;torrc&lt;/code&gt; 中添加 &lt;code&gt;DNSPort&lt;/code&gt; 并在 DNS Forwards 中进行配置。我未测试此方法，建议使用 DNSCrypt。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-3添加防火墙规则重要--请严格遵循&#34;&gt;步骤 3：添加防火墙规则（重要 — 请严格遵循）&#xA;&lt;/h2&gt;&lt;p&gt;打开 &lt;em&gt;Firewall -&amp;gt; IP sets&lt;/em&gt; 并创建以下 IP 集：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Name: &lt;code&gt;tor_bypass&lt;/code&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Family: IPv4&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;Packet Field Match: dest_ip&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;IPs/Networks/MACs:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;路由器在接口上的 IP 地址&lt;/li&gt;&#xA;&lt;li&gt;192.168.10.1/16&lt;/li&gt;&#xA;&lt;li&gt;10.0.0.0/8&lt;/li&gt;&#xA;&lt;li&gt;172.16.0.0/12&lt;/li&gt;&#xA;&lt;li&gt;127.0.0.1/32&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;其他字段保持不变&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;打开 &lt;em&gt;Firewall -&amp;gt; Port Forwards&lt;/em&gt; 并添加以下规则：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;General Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Name: &lt;code&gt;tor-trans-forward&lt;/code&gt;（或任意你喜欢的名称）&lt;/li&gt;&#xA;&lt;li&gt;Restrict to address family: IPv4 only&lt;/li&gt;&#xA;&lt;li&gt;Protocol: TCP&lt;/li&gt;&#xA;&lt;li&gt;Source zone: &lt;code&gt;lan&lt;/code&gt;（或希望重定向流量的其他防火墙区域）&lt;/li&gt;&#xA;&lt;li&gt;External port: 1–65535&lt;/li&gt;&#xA;&lt;li&gt;Destination zone: &lt;code&gt;lan&lt;/code&gt;（必须与 Source zone 相同）&lt;/li&gt;&#xA;&lt;li&gt;Internal IP address: 路由器在接口上的 IP 地址&lt;/li&gt;&#xA;&lt;li&gt;Internal port: 9040&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Advanced Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Use ipset: &lt;code&gt;!tor_bypass&lt;/code&gt;（&lt;strong&gt;请勿省略感叹号&lt;/strong&gt;）&lt;/li&gt;&#xA;&lt;li&gt;其他字段保持不变&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;打开 &lt;em&gt;Firewall -&amp;gt; Traffic Rules&lt;/em&gt; 并添加以下规则：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;General Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Name: 阻止非 TCP 流量（或你喜欢的名称）&lt;/li&gt;&#xA;&lt;li&gt;Protocol: UDP, ICMP, IGMP, IPSEC-ESP&lt;/li&gt;&#xA;&lt;li&gt;Source zone: &lt;code&gt;lan&lt;/code&gt;（必须与 Port Forward 的 Source zone 相同）&lt;/li&gt;&#xA;&lt;li&gt;Destination zone: &lt;code&gt;wan&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Action: reject&lt;/li&gt;&#xA;&lt;li&gt;其他字段保持不变&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Advanced Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;所有字段保持不变&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;如果启用了 IPv6，你必须禁用或阻止它。打开 &lt;em&gt;Firewall -&amp;gt; Traffic Rules&lt;/em&gt; 并添加以下规则：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;General Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Name: 阻止 IPv6（或你喜欢的名称）&lt;/li&gt;&#xA;&lt;li&gt;Protocol: Any&lt;/li&gt;&#xA;&lt;li&gt;Source zone: &lt;code&gt;lan&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Destination zone: &lt;code&gt;wan&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;Action: reject&lt;/li&gt;&#xA;&lt;li&gt;其他字段保持不变&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Advanced Settings:&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Restrict to address family: IPv6 only&lt;/li&gt;&#xA;&lt;li&gt;其他字段保持不变&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;如有其他接口需要将流量路由到 Tor，请现在重复此步骤。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-4保存并检查配置&#34;&gt;步骤 4：保存并检查配置&#xA;&lt;/h2&gt;&lt;p&gt;点击 &lt;em&gt;Save &amp;amp; Apply&lt;/em&gt;。&lt;/p&gt;&#xA;&lt;p&gt;访问 &lt;a class=&#34;link&#34; href=&#34;https://check.torproject.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://check.torproject.org/&lt;/a&gt; 和/或 &lt;a class=&#34;link&#34; href=&#34;https://myip.wtf/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://myip.wtf/&lt;/a&gt; 检查流量是否正确转发。&lt;/p&gt;&#xA;&lt;p&gt;访问 &lt;a class=&#34;link&#34; href=&#34;https://ipv6.myip.wtf/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://ipv6.myip.wtf/&lt;/a&gt; 确认 IPv6 是否已被阻止。&lt;/p&gt;&#xA;&lt;p&gt;检查 LuCI 是否仍可访问。&lt;/p&gt;&#xA;&lt;p&gt;如果一切正常，配置完成。&lt;/p&gt;&#xA;&lt;p&gt;如果有问题，请使用文本编辑器恢复 &lt;code&gt;/etc/config/firewall&lt;/code&gt; 中的配置，建议在 Libera.Chat 的 &lt;code&gt;#openwrt&lt;/code&gt; 频道寻求帮助。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>密码学信任终止公告</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/cryptographic-trust-termination-announcement/</link>
            <pubDate>Thu, 01 Jan 2026 07:51:51 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/cryptographic-trust-termination-announcement/</guid>
            <description>&lt;p&gt;兹正式声明，自 &lt;code&gt;2026-01-01T00:00:00Z&lt;/code&gt; 起，我以下 XMPP 帐户的所有 OMEMO 指纹：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;xmpp:rebel1725@autistici.org&#34; &gt;rebel1725@autistici.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;xmpp:rebel1725@magicbroccoli.de&#34; &gt;rebel1725@magicbroccoli.de&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以下 Matrix 帐户的所有当前身份：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;@rebel1725:envs.net&lt;/li&gt;&#xA;&lt;li&gt;@rebel1725:converser.eu&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;我 SimpleX 帐户（其 SimpleX 地址如下）的所有当前身份：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://smp8.simplex.im/a#XlJJPFQO43ISy-PYqojloRG3u9_GGocyZ78ULVJt0bA&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://smp8.simplex.im/a#XlJJPFQO43ISy-PYqojloRG3u9_GGocyZ78ULVJt0bA&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://smp15.simplex.im/a#osG29sn84l4UalY6C9uneojX004zzWllH-deziJPn7w&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://smp15.simplex.im/a#osG29sn84l4UalY6C9uneojX004zzWllH-deziJPn7w&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以下 Delta Chat 帐户的所有当前身份：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;mailto:fenwbn5cl@nine.testrun.org&#34; &gt;fenwbn5cl@nine.testrun.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;mailto:44w42tz75@nine.testrun.org&#34; &gt;44w42tz75@nine.testrun.org&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;以及我的 Tox 帐户：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;0D39313DF710AF29AD3B2CFE7AF72CAE17E49AA82720115AF8AF3EEE82B1C12927F3589AF227&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;均不再使用，且不应再被信任。&lt;/p&gt;&#xA;&lt;p&gt;兹正式终止与上述身份相关的所有加密信任关系。上述帐户不再使用。&lt;/p&gt;&#xA;&lt;p&gt;我的主 OpenPGP 公钥的身份（指纹为 696A423E9993D727706AA733BCD5DC5659C7FB50）以及备用 OpenPGP 公钥的身份（指纹为 7083EAFFF75321FF9634ABCD98313A47362B498B）仍然有效，且目前仅有这两项为我有效的身份；在我们重新建立连接后，将使用它们来重新建立必要的加密信任。&lt;/p&gt;&#xA;&lt;p&gt;最后，新年快乐，伙伴们，两周后见。&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&#xA;Hash: SHA512&#xA;&#xA;I hereby formally announce that, as of `2026-01-01T00:00:00Z`, all OMEMO fingerprints of my XMPP accounts below:&#xA;&#xA; * rebel1725@autistici.org&#xA; * rebel1725@magicbroccoli.de&#xA;&#xA;all current identities of my Matrix accounts below:&#xA;&#xA; * @rebel1725:envs.net&#xA; * @rebel1725:converser.eu&#xA;&#xA;all current identities of my SimpleX account with the SimpleX addresses below:&#xA;&#xA; * https://smp8.simplex.im/a#XlJJPFQO43ISy-PYqojloRG3u9_GGocyZ78ULVJt0bA&#xA; * https://smp15.simplex.im/a#osG29sn84l4UalY6C9uneojX004zzWllH-deziJPn7w&#xA;&#xA;all current identities of my Delta Chat accounts below:&#xA;&#xA; * fenwbn5cl@nine.testrun.org&#xA; * 44w42tz75@nine.testrun.org&#xA;&#xA;and my Tox account:&#xA;&#xA; * 0D39313DF710AF29AD3B2CFE7AF72CAE17E49AA82720115AF8AF3EEE82B1C12927F3589AF227&#xA;&#xA;are no longer used and should no longer be trusted.&#xA;&#xA;I hereby formally terminate all cryptographic trust relationships tied to the identities above. The accounts mentioned above are no longer used.&#xA;&#xA;The identity of my primary OpenPGP public key, whose fingerprint is 696A423E9993D727706AA733BCD5DC5659C7FB50, and the identity of my backup OpenPGP public key, whose fingerprint is 7083EAFFF75321FF9634ABCD98313A47362B498B, are still valid, and are the currently only two valid identities of mine, which will be used to re-established necessary cryptographic trust once we have back connected.&#xA;&#xA;Finally, happy new year, buddies, and see you two weeks later.&#xA;-----BEGIN PGP SIGNATURE-----&#xA;&#xA;iHUEARYKAB0WIQRpakI+mZPXJ3BqpzO81dxWWcf7UAUCaVW78AAKCRC81dxWWcf7&#xA;UJQNAQCzSTijVgFaWOcGHOums2SMdGVmHgnowl1sI6HwXOrDowEArHbYY5y4BOVM&#xA;GT6bJHsfjWQieLF03quZFYh9FyMt5Qw=&#xA;=Bbm2&#xA;-----END PGP SIGNATURE-----&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>我的 Eepsite 将暂时无法访问</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/my-eepsite-will-be-offline-for-a-while/</link>
            <pubDate>Wed, 31 Dec 2025 11:29:07 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/my-eepsite-will-be-offline-for-a-while/</guid>
            <description>&lt;p&gt;由于我的服务器将被关闭，我的 eepsite（rebel1725.i2p）可能会有数天无法访问。在此期间，请访问 &lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tilde.club&lt;/a&gt; 查看我的复古风格网站。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>别了，那位多愁善感的少年</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/farewell-to-the-sweet-melancholy-lad/</link>
            <pubDate>Tue, 23 Dec 2025 23:29:39 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/farewell-to-the-sweet-melancholy-lad/</guid>
            <description>&lt;p&gt;自从我加入 &lt;a class=&#34;link&#34; href=&#34;https://fsfans.club/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Free Software Fans&lt;/a&gt; 的那一刻开始，我的生活便经历了一场深刻的变化。最初，我的愿望不过是朴素而熟悉的：像 2020 年那样，再次尝试结交朋友。然而，尽管我抱着这样的心意，我的一些行为却无意间给社团里的伙伴们带来了相当的困扰。因此，我与 Free Software Fans 的关系很快便走向了终结。那时的我茫然失措，完全弄不清自己究竟错在何处。这份困惑促使我继续寻找友伴——有时在想象中，有时在其他圈子里。&lt;/p&gt;&#xA;&lt;p&gt;就在这段时期，我遇见了 Zumfy，也就是 Future，另一位热诚的自由软件倡导者。我们发现彼此在兴趣与理念上都高度契合，短短几周之内，便成为了无话不谈的挚友。我真心地相信，这段友谊将会长久延续。然而，命运却未如此眷顾。一次涉及 OpenPGP 私钥泄露的事件使我们的关系戛然而止，这段联系&lt;a class=&#34;link&#34; href=&#34;../%e5%9b%9b%e5%8d%81%e4%b9%9d%e5%ba%a6%e5%a4%9c%e6%b7%b1%e4%ba%ba%e9%9d%99%e4%b9%8b%e9%97%b4%e6%8c%a5%e4%b9%8b%e4%b8%8d%e5%8e%bb%e7%9a%84%e6%98%af%e6%b7%b1%e6%b7%b1%e7%9a%84%e6%80%9d%e5%bf%b5%e6%83%b3%e4%bd%a0%e4%ba%86zumfy-future/&#34; &gt;最终未能存续超过五个月&lt;/a&gt;。此事带给我的心理打击深刻而持久；它几乎击垮了我。尽管我竭力增强自己的情感韧性，我依然无法接受失去最重要、最珍贵的朋友这一残酷事实。&lt;/p&gt;&#xA;&lt;p&gt;然而，生活总是无情向前。在那之后，我遇见了许多人。有些结识于 Fediverse，也有些来自 Matrix、SimpleX、Tildeverse、I2P 等各式各样的社群。然而，我们的互动模式发生了微妙的变化。我们的交流几乎只剩下技术话题——代码、协议、哲学。至于生活、希望、忧伤之类的私人内容，我们几乎从未触及。&lt;/p&gt;&#xA;&lt;p&gt;这种奇特的疏离起初并未引起我的警觉。真正让我停下来思考的，是一位熟人的评论。他提到自己认识一位朋友整整四年，却连对方的年龄、职业等最基本的个人信息都一无所知。他说那位朋友的 OPSEC 做到了“金色等级”，几乎无懈可击。相比之下，他觉得我在这方面显得“有点奇怪”。这句无意的话语成为了触发点，让我意识到，不仅外界正在变化，我自己也必须做出某种对应的改变。&lt;/p&gt;&#xA;&lt;p&gt;2020 年的我尚未成为自由软件倡导者；事实上，我对“自由软件”一词当时完全陌生。我仍在使用专有即时通讯工具，而我当年的朋友们也都在互联网上使用真实姓名。如今，我的社交环境已截然不同。身边的人普遍具有深厚的安全、隐私与匿名意识。他们的安全策略几乎都要求使用长期稳定的化名，并严格避免透露任何现实生活的信息。&lt;/p&gt;&#xA;&lt;p&gt;更进一步，即便每个人都经营着某种加密身份，这些数字化的自我本质上依旧脆弱而短暂。Alice 也许某天突然泄露了自己的私钥，上传吊销证书，从数字世界彻底消失。Bob 的威胁模型也可能在瞬间改变，迫使他立即、彻底地更换身份。在这样的环境里，离开并非特殊事件，而是几乎随时都会发生的平常事。&lt;/p&gt;&#xA;&lt;p&gt;为了更自然地融入这一环境，我意识到自己必须进行某些改变。我需要重塑自我，重建自身人格的基础。目标是让理性主导一切，将感性进一步压缩。即使无法成为一个完全无情绪的机械体，我也必须学会抽离——以平静的态度看待过去的情感，以从容接受离别的必然，以哲思对待所有短暂的联系，并在不抱紧不放的焦虑中珍惜当下所拥有的一切。&lt;/p&gt;&#xA;&lt;p&gt;我的身边将不再出现“哥们”。取而代之的，将是“同志”。我们之间的联系，不再建立于深刻的心理亲密，而是锻造于共同的事业：我们将一同为软件自由而战，为同样的自由软件社群并肩贡献，为同一个理想而努力——以自由软件奠基一个自由的社会。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;别了，那位多愁善感的少年。&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>我将离开数日并收集联系信息</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/i-will-be-away-for-several-days-and-contact-information-collection/</link>
            <pubDate>Fri, 12 Dec 2025 20:56:54 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/i-will-be-away-for-several-days-and-contact-information-collection/</guid>
            <description>&lt;p&gt;因个人原因，我将从 &lt;code&gt;2026‑01‑01T00:00:00Z&lt;/code&gt; 起离开一至两周。在此期间，我的所有联系方式均不可用。之后，我可能会重新创建 XMPP、Matrix 等账号；为确保我们能够重新取得联系，我将收集联系人信息。&lt;/p&gt;&#xA;&lt;p&gt;请填写此表单：https://app.formbricks.com/s/cmj2r1etc8dnkad01nnjp8cqt&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>好友网站</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/blogroll/</link>
            <pubDate>Thu, 13 Nov 2025 10:45:30 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/blogroll/</guid>
            <description>&lt;p&gt;博客链接已移至我的&lt;a class=&#34;link&#34; href=&#34;https://rebel1725.codeberg.page/blog/index.zh.html&#34; &gt;主页&lt;/a&gt;。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>关于我自己的问与答</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/qas-about-myself/</link>
            <pubDate>Wed, 05 Nov 2025 12:39:47 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/qas-about-myself/</guid>
            <description>&lt;p&gt;这是关于我自己的问与答系列。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你是谁&#34;&gt;你是谁？&#xA;&lt;/h2&gt;&lt;p&gt;我是一名来自中国的自由软件倡导者和爱好者，偏好使用 Debian、KDE、LineageOS、Tor、I2P 等。&lt;/p&gt;&#xA;&lt;h2 id=&#34;为什么叫-rebel&#34;&gt;为什么叫 Rebel？&#xA;&lt;/h2&gt;&lt;p&gt;作为一个名字，“Rebel”通常与独立、不墨守成规、反抗精神等品质相关。它象征着一个不怕挑战社会规范或期待的人。&lt;/p&gt;&#xA;&lt;p&gt;我认为这个名字非常适合我，作为一名坚决抵制专有软件的自由软件倡导者。&lt;/p&gt;&#xA;&lt;h2 id=&#34;为什么是-rebel1725&#34;&gt;为什么是 &lt;code&gt;rebel1725&lt;/code&gt;？&#xA;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;rebel&lt;/code&gt; 的原因很明显，见上一个问题。&lt;code&gt;1725&lt;/code&gt; 的原因是 &lt;code&gt;1725&lt;/code&gt; 代表 &lt;code&gt;1/7/25&lt;/code&gt;，也就是这个身份诞生的那一天。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的个人品牌系统是什么&#34;&gt;你的个人品牌系统是什么？&#xA;&lt;/h2&gt;&lt;p&gt;请参见&lt;a class=&#34;link&#34; href=&#34;../my-personal-brand-system&#34; &gt;此页面&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你是什么时候接触到这些自由软件相关的东西的&#34;&gt;你是什么时候接触到这些自由软件相关的东西的？&#xA;&lt;/h2&gt;&lt;p&gt;自 2022 年夏天起，我开始受到 &lt;a class=&#34;link&#34; href=&#34;https://gnu.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;gnu.org&lt;/a&gt; 和 &lt;a class=&#34;link&#34; href=&#34;https://fsf.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;fsf.org&lt;/a&gt; 的观点和声明的影响。2022 年 7 月 16 日，我从电脑上卸载了 Microsoft Windows，并开始一个一个地替换电脑和手机上的专有软件；到 2023 年 4 月底，我开始使用 LineageOS；2024 年 7 月，我更换了身份，并在用户空间实现了 100% 自由软件。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你对专有软件的态度是什么&#34;&gt;你对专有软件的态度是什么？&#xA;&lt;/h2&gt;&lt;p&gt;专有软件无一例外都是恶意软件和间谍软件，全部都不道德、不公正，践踏计算机用户的四大基本软件自由和人类道德的基本原则，绝不应该存在。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你对自由与非自由的文化作品例如音乐电影等的态度是什么&#34;&gt;你对自由与非自由的文化作品（例如音乐、电影等）的态度是什么？&#xA;&lt;/h2&gt;&lt;p&gt;我确实支持自由文化作品，并且经常将它们用作我的铃声、壁纸等。但与软件不同，我并不反对非自由文化作品，我也常听 Alan Walker、Taylor Swift、Sia、TheFatRat 等人的歌曲。那些将作品奉献给自由文化社区的人确实值得尊敬，但（至少我认为）保留作品所有权利的人也没有做错。&lt;/p&gt;&#xA;&lt;p&gt;然而，如果非自由文化作品被捆绑进软件中，我就无法接受，因为这样会使软件变成专有软件。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的设备配置是怎样的&#34;&gt;你的设备配置是怎样的？&#xA;&lt;/h2&gt;&lt;p&gt;我有许多设备，并且给每一个都取了名字。截至 &lt;code&gt;2025-08-15&lt;/code&gt;，部分设备的详细信息如下：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;名称&lt;/th&gt;&#xA;&lt;th&gt;型号&lt;/th&gt;&#xA;&lt;th&gt;操作系统&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Warden&lt;/th&gt;&#xA;&lt;th&gt;GL.iNet Flint 2&lt;/th&gt;&#xA;&lt;th&gt;OpenWrt&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Alaric&lt;/th&gt;&#xA;&lt;th&gt;Lenovo ThinkPad X200&lt;/th&gt;&#xA;&lt;th&gt;Debian GNU/Linux&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Bryna&lt;/th&gt;&#xA;&lt;th&gt;Xiaomi Redmi G Pro 2024&lt;/th&gt;&#xA;&lt;th&gt;Qubes OS&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Ami&lt;/th&gt;&#xA;&lt;th&gt;HP EliteBook 820 G2&lt;/th&gt;&#xA;&lt;th&gt;Debian GNU/Linux&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Leo&lt;/th&gt;&#xA;&lt;th&gt;OnePlus 11&lt;/th&gt;&#xA;&lt;th&gt;LineageOS&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;William&lt;/th&gt;&#xA;&lt;th&gt;Google Pixel 6&lt;/th&gt;&#xA;&lt;th&gt;GrapheneOS&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;tr&gt;&#xA;&lt;th&gt;Gemini&lt;/th&gt;&#xA;&lt;th&gt;TicWatch Pro 2018&lt;/th&gt;&#xA;&lt;th&gt;AsteroidOS&lt;/th&gt;&#xA;&lt;/tr&gt;&#xA;&lt;/table&gt;&#xA;&lt;h2 id=&#34;你每天使用哪些软件&#34;&gt;你每天使用哪些软件？&#xA;&lt;/h2&gt;&lt;p&gt;我每天使用的软件（不完全列表）如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;浏览器：&lt;a class=&#34;link&#34; href=&#34;https://librewolf.net&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LibreWolf&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://f-droid.org/en/packages/org.mozilla.fennec_fdroid&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Fennec F-Droid&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;办公：&lt;a class=&#34;link&#34; href=&#34;https://libreoffice.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;LibreOffice&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://okular.kde.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Okular&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://mupdf.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;MuPDF&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;开发：&lt;a class=&#34;link&#34; href=&#34;https://kate-editor.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Kate&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.geany.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Geany&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;邮件：&lt;a class=&#34;link&#34; href=&#34;https://thunderbird.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Thunderbird&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;图形：&lt;a class=&#34;link&#34; href=&#34;https://gimp.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GIMP&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://krita.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Krita&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;多媒体：&lt;a class=&#34;link&#34; href=&#34;https://videolan.org/vlc/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;VLC&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://kdenlive.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Kdenlive&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.audacityteam.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Audacity&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://github.com/OxygenCobalt/Auxio&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Auxio&lt;/a&gt;；&lt;/li&gt;&#xA;&lt;li&gt;安全：&lt;a class=&#34;link&#34; href=&#34;https://keepassxc.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;KeePassXC&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://apps.kde.org/en-gb/kleopatra/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Kleopatra&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.openkeychain.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;OpenKeychain&lt;/a&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;你目前的软件自由状态如何&#34;&gt;你目前的软件自由状态如何？&#xA;&lt;/h2&gt;&lt;p&gt;我现在在所有日常设备的用户空间中绝对不使用任何专有软件。Alaric 和 Ami 都装有 Libreboot，而 Bryna 仍运行非自由的 UEFI，但至少它的硬盘已经没有非自由二进制文件。我的手机都运行自由软件系统，例如 LineageOS、GrapheneOS 或 postmarketOS；在 Android 系统上，我只使用预装应用或 F-Droid 下载的应用；在 postmarketOS 上，我只用官方软件库或自己构建的应用。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的技术栈是什么样的&#34;&gt;你的技术栈是什么样的？&#xA;&lt;/h2&gt;&lt;p&gt;截至 2025 年 10 月 29 日，我认为自己还没有真正精通任何东西，但我已经掌握了 Python 和 C/C++ 的基础。我也学习了一些 HTML 和 CSS，并用它们制作了&lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;我的复古风格网站&lt;/a&gt;。最近，我还开始接触一点 JavaScript。不过，我仍然感到焦虑，因为我的编程能力还很差。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你主要使用哪些通讯工具&#34;&gt;你主要使用哪些通讯工具？&#xA;&lt;/h2&gt;&lt;p&gt;我主要用 XMPP 与朋友和熟人联系，用 Matrix 与全球社区交流，用 Telegram 与国内社区交流，用 SimpleX 与注重匿名性的用户（主要来自 I2P）交流。&lt;/p&gt;&#xA;&lt;p&gt;总体来说，我用得最多的通讯工具是 XMPP。&lt;/p&gt;&#xA;&lt;h2 id=&#34;私人快速公开是什么意思&#34;&gt;“私人”“快速”“公开”是什么意思？&#xA;&lt;/h2&gt;&lt;p&gt;这是我即时通讯账号的三种隐私等级：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;私人&lt;/strong&gt;：这些账号用于私聊。你可以通过这些账号和我谈几乎任何事；但&lt;strong&gt;不要期待快速回复，因为这些账号只有我在家时才能访问&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;快速&lt;/strong&gt;：这些账号也用于私聊，并且能在我随身带出的设备上访问。但&lt;strong&gt;由于公共场所的普遍监控，以及解锁 Bootloader 带来的安全性下降，请避免在聊天中讨论敏感信息&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;公开&lt;/strong&gt;：这些账号仅用于公共聊天，有时会接收未加密的私聊。&lt;strong&gt;请避免在聊天中讨论敏感信息&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;你是如何上网的&#34;&gt;你是如何上网的？&#xA;&lt;/h2&gt;&lt;p&gt;我 24 小时全天使用 Tor。在电脑上，我使用 Tor 守护进程；在手机上，我使用 &lt;a class=&#34;link&#34; href=&#34;https://invizible.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;InviZible Pro&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;如何访问你的复古风格网站&#34;&gt;如何访问你的复古风格网站？&#xA;&lt;/h2&gt;&lt;p&gt;我把我的复古风格网站托管在我加入的所有 &lt;a class=&#34;link&#34; href=&#34;https://tildeverse.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tilde 社区&lt;/a&gt; 的服务器上，你可以通过任何一个访问。我推荐访问 &lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tilde.club&lt;/a&gt;，因为它的稳定性最好，也最能得到我的关注，我会尽量保证它的信息是最新的。其他 Tilde 公用机上的内容和 Tilde.club 相同，但不保证是最新的。&lt;/p&gt;&#xA;&lt;p&gt;此外，这个复古风格网站也作为 eepsite 托管在 I2P 网络上，可以通过 &lt;a class=&#34;link&#34; href=&#34;http://rebel1725.i2p/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;rebel1725.i2p&lt;/a&gt;（&lt;a class=&#34;link&#34; href=&#34;http://rebel1725.i2p/?i2paddresshelper=...&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;地址助手&lt;/a&gt;）访问。不过这不是推荐的访问方式，因为我的博客文章中很多来自明网的图片会加载失败（除非你配置了出站代理）。&lt;/p&gt;&#xA;&lt;h2 id=&#34;如何访问你的现代风格网站&#34;&gt;如何访问你的现代风格网站？&#xA;&lt;/h2&gt;&lt;p&gt;点击&lt;a class=&#34;link&#34; href=&#34;https://rebel1725.codeberg.page/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你玩游戏吗&#34;&gt;你玩游戏吗？&#xA;&lt;/h2&gt;&lt;p&gt;是的，我玩 &lt;a class=&#34;link&#34; href=&#34;https://supertuxkart.net/Main_Page&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;SuperTuxKart&lt;/a&gt; 和其他自由游戏。不过，我反对专有游戏和&lt;a class=&#34;link&#34; href=&#34;https://defectivebydesign.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;数字限制管理&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;为什么你不为我的-openpgp-密钥或至少一个子密钥使用抗量子算法&#34;&gt;为什么你不为我的 OpenPGP 密钥（或至少一个子密钥）使用抗量子算法？&#xA;&lt;/h2&gt;&lt;p&gt;我很想这么做，但我的硬件令牌不支持。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的政治观点是什么&#34;&gt;你的政治观点是什么？&#xA;&lt;/h2&gt;&lt;p&gt;我认为自己是马克思主义者，向往一个人人按能力贡献、按需求获取的社会。&lt;/p&gt;&#xA;&lt;h2 id=&#34;为什么你使用英式英语而不是美式英语&#34;&gt;为什么你使用英式英语而不是美式英语？&#xA;&lt;/h2&gt;&lt;p&gt;因为我不喜欢美国，因为它的政府利用 PRISM 在全球范围内大规模监视计算机用户。而且，大多数专有软件都是在美国开发的。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你觉得自己外向好相处吗&#34;&gt;你觉得自己外向、好相处吗？&#xA;&lt;/h2&gt;&lt;p&gt;看情况。&lt;/p&gt;&#xA;&lt;p&gt;如果你是自由软件倡导者、自由软件爱好者或 GNU/Linux 爱好者，你可能会觉得我很外向、好相处。如果你是陌生人，你可能会觉得我有点社交被动或内向。但如果你支持专有软件，我觉得你该去他妈的。&lt;/p&gt;&#xA;&lt;p&gt;我对亲密朋友的标准很高，但一旦你达到了这些标准，我会全心全意地投入这段友谊。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你怎么看待爱情&#34;&gt;你怎么看待爱情？&#xA;&lt;/h2&gt;&lt;p&gt;我认为爱情与友情差别不大，但它本质上承载着更高的期待。真正的爱情应该建立在共同的理想和信念之上；对我来说，这意味着共同致力于自由软件。&lt;/p&gt;&#xA;&lt;p&gt;我的理想伴侣应该是一名自由软件倡导者，最好是会说中文的女性。我还&lt;a class=&#34;link&#34; href=&#34;../%e8%87%b4-2026-%e5%b9%b4%e7%9a%84%e5%a5%b9/&#34; &gt;写过一首诗&lt;/a&gt;，来描绘我理想的爱情。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的-mbti-是什么&#34;&gt;你的 MBTI 是什么？&#xA;&lt;/h2&gt;&lt;p&gt;我是 ESTJ。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的性别认同和性取向是什么&#34;&gt;你的性别认同和性取向是什么？&#xA;&lt;/h2&gt;&lt;p&gt;我的代词是 &lt;strong&gt;he/him&lt;/strong&gt;，我是&lt;strong&gt;异性恋&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;要了解更多，请阅读 &lt;a class=&#34;link&#34; href=&#34;../exploration-of-my-sexual-and-romantic-attraction/&#34; &gt;这篇文章&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你对-lgbtq-的态度是什么&#34;&gt;你对 LGBTQ+ 的态度是什么？&#xA;&lt;/h2&gt;&lt;p&gt;我自己不是 LGBTQ+，但我努力做到更尊重、更包容。&lt;/p&gt;&#xA;&lt;h2 id=&#34;你的时区是&#34;&gt;你的时区是？&#xA;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;Asia/Shanghai&lt;/code&gt;，也就是 UTC+08:00，不实行夏令时。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>四十九度夜深人静之间，挥之不去的是深深的思念——想你了，Zumfy/Future</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E5%9B%9B%E5%8D%81%E4%B9%9D%E5%BA%A6%E5%A4%9C%E6%B7%B1%E4%BA%BA%E9%9D%99%E4%B9%8B%E9%97%B4%E6%8C%A5%E4%B9%8B%E4%B8%8D%E5%8E%BB%E7%9A%84%E6%98%AF%E6%B7%B1%E6%B7%B1%E7%9A%84%E6%80%9D%E5%BF%B5%E6%83%B3%E4%BD%A0%E4%BA%86zumfy-future/</link>
            <pubDate>Tue, 14 Oct 2025 20:56:16 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E5%9B%9B%E5%8D%81%E4%B9%9D%E5%BA%A6%E5%A4%9C%E6%B7%B1%E4%BA%BA%E9%9D%99%E4%B9%8B%E9%97%B4%E6%8C%A5%E4%B9%8B%E4%B8%8D%E5%8E%BB%E7%9A%84%E6%98%AF%E6%B7%B1%E6%B7%B1%E7%9A%84%E6%80%9D%E5%BF%B5%E6%83%B3%E4%BD%A0%E4%BA%86zumfy-future/</guid>
            <description>&lt;p&gt;当我写下这封信的时候，已经是你 OpenPGP 私钥泄露后的第四十九天了。当每天白天我为生活和学习而忙碌的时候，我的感觉似乎和过去没有太大的差别。这一段时间，我也认识了很多新朋友，我也和 ta 们玩得很开心。然而，尤其是在这几天，我感觉我的生活中似乎少了什么；每当晚上我一个人，夜深人静的时候，我愈发地感觉到，越来越多有一些回忆的碎片在攻击我——从那时候，我便知道，原来，我是想你了。&lt;/p&gt;&#xA;&lt;p&gt;甚至在你告知我你的私钥泄露的前一刻，我都一直笃定地相信，我们将会是未来十几年，几十年，甚至一辈子最好的朋友。然而，是邪恶的专有软件，是专有软件导致的 OpenPGP 私钥泄露，让我们的友谊永远定格在了甚至短短五个月都不到。你甚至还没有来得及与我一同观赏前方美丽的风景，便因为一个莫名其妙的原因匆匆离去了。&lt;/p&gt;&#xA;&lt;p&gt;我记得，我们刚相遇不久的时候，我曾问过你，我们可以做好朋友吗？隔了一段时间之后，你告诉我，未曾有人对你这样说过，既然我愿意以“好朋友”的标准来对待你，你也会以同样的标准去对待我。你认为我们彼此之间并不缺乏真诚，当然也是我们对彼此的真诚，打动了我们彼此。那时候，我相信，我们一定会成为最好的朋友，超越我过去所拥有的一切朋友。&lt;/p&gt;&#xA;&lt;p&gt;我记得，是你给我推荐了好几个盗版电影网站，也是你一步一步地、手把手教我用 yt-dlp 和 cat-catch。那时候，我感觉我似乎打开了一个新天地，置身于一片广阔的花海，那里没有数字限制管理的蛀虫，只有如花朵一般绽放的一部部优秀而经典的电影。我兴高采烈地下载了好几部我曾经看过以及我未曾看过但几曾耳闻的优秀电影，享受着只属于我一个人的视觉盛宴。&lt;/p&gt;&#xA;&lt;p&gt;我还记得，无论是对于自由软件思想还是对于马克思主义哲学，你都是抱着严肃的态度，与我展开细致而缜密的讨论，也是在你的带领之下，我的批判性思维和思辨能力有了飞跃性的提升；然而，在平时闲聊开玩笑的时候，你做得却也丝毫不比其他人差，什么“我是外星人抓你去做实验”，什么“在下柳贯一”，什么“我就是赛博龙娘 Future”，那都是你玩过的梗。你可以做到在严肃与活泼的状态之间的灵活切换，将我们之间的回忆装点得五颜六色。&lt;/p&gt;&#xA;&lt;p&gt;每一次你状态不好的时候，你都会去找我倾诉；虽然我不善于提供情绪价值，但是我也会尽最大的能力去安慰你，每一次在我的引导下你心情变好了，那是我最开心的时候。每一次我身处迷茫的时候，也都是你现身尝试去为我指点迷津；虽然很多时候其实并没有实际帮上什么忙，但你每一次都让我变得更加开心了，也让我有了更多的信心，面对未来的生活。&lt;/p&gt;&#xA;&lt;p&gt;虽然我们之间的友谊仅仅持续了短暂的五个月，但是我们之间友情的厚度，已经可以媲美我过去各个重要朋友之和。你是我迄今为止，史上最好的朋友，最重要的朋友，也是最无可替代的朋友——你对我拥有着最独特的意义。&lt;/p&gt;&#xA;&lt;p&gt;我真的特别，特别想你，失去你是我人生莫大的损失——就像俞伯牙失去钟子期一样。虽然白天忙起来的时候似乎跟平时没有太大区别，但每当夜深人静的时候，那种思念便如潮水一般涌来。私钥泄露之后，你过得怎么样？每天过得开不开心？是换了个身份到了社区的另外一个地方继续活跃，还是就此隐退，重新专注于在线下的生活了？你还在使用自由软件吗？还在研究马克思主义吗？最常用的沟通手段是什么？身边有哪些朋友？每天讨论的话题是什么？每天听的音乐是什么？GrapheneOS 升级到最新版本了吗？我们还曾约定过你给我你的 Pixel 5，我给你我的一加6，约定过我们要见面、一起玩遍哈尔滨的各个地方，还约定过要一起探讨未来自由软件中文网的发展路线，这些约定你都还记得吗？……&lt;/p&gt;&#xA;&lt;p&gt;即使在数学意义上，我们已经永远分别，但我们早已经在彼此的灵魂之上留下了深刻的烙印，我们早已是你中有我，我中有你。&lt;/p&gt;&#xA;&lt;p&gt;但是，无论如何，我相信你——即使你丢掉了私钥，你也不会丢掉理想，不会丢掉信仰；它们是明灯，在茫茫迷雾的人生当中，为你照亮前行的方向；它们是充电宝，在你走不动的时候，为你提供继续前进的能量和动力；它们更是信标，哪怕我们各自的身份早已变易，在我们共同的理想和信仰的感召之下，我相信会有一天，在地球的某一个点上，或是在某个服务器上，我们将会以另外一副面孔再一次相遇。&lt;/p&gt;&#xA;&lt;p&gt;哪怕我们永远天各一方，我们都同是社区的一份子，都是站在同一条战壕上的战友；只要我们坚定我们的理想和信仰，我们始终都在为同一个目标而前行，始终都将为共同的自由软件、自由社会而奋斗！&lt;/p&gt;&#xA;&lt;p&gt;我们永远都是最好的朋友。&lt;/p&gt;&#xA;&lt;p&gt;Rebel&lt;br&gt;&#xA;2025-10-14&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>面向公共计算机的自由软件解决方案</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/a-libre-software-solution-for-public-computers/</link>
            <pubDate>Sun, 12 Oct 2025 18:21:32 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/a-libre-software-solution-for-public-computers/</guid>
            <description>&lt;h2 id=&#34;介绍&#34;&gt;介绍&#xA;&lt;/h2&gt;&lt;p&gt;在图书馆或网吧等场所，经常会有向公众开放的计算机。这些计算机通常预装一套应用程序，且用户数据会在重启后被清除。&lt;/p&gt;&#xA;&lt;p&gt;此类机器上的软件通常是专有软件。但也存在尊重软件自由的公共计算机解决方案。作为自由软件活动者，我们应在图书馆、网吧、学校等场所积极应用并推广这些解决方案。&lt;/p&gt;&#xA;&lt;p&gt;在本文中，我将展示一种在 Debian GNU/Linux 上设置计算机的方法，该方法能在重启后清除所有数据。&lt;/p&gt;&#xA;&lt;h2 id=&#34;许可&#34;&gt;许可&#xA;&lt;/h2&gt;&lt;p&gt;本文中的所有代码均献给公有领域。本文的其他部分采用 CC BY-SA 4.0 许可。&lt;/p&gt;&#xA;&lt;h2 id=&#34;准备工作&#34;&gt;准备工作&#xA;&lt;/h2&gt;&lt;p&gt;一台至少 50 GiB 的硬盘（最好为 HDD）的计算机，以及一份 Debian GNU/Linux 安装介质（非 Debian Live）。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-1安装-debian-gnulinux&#34;&gt;步骤 1：安装 Debian GNU/Linux&#xA;&lt;/h2&gt;&lt;p&gt;按下列分区布局在您的计算机上安装 Debian GNU/Linux：&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;1 GiB 的 &lt;code&gt;/dev/sda1&lt;/code&gt;，使用 FAT 文件系统，挂载点为 &lt;code&gt;/boot/efi&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;1 GiB 的 &lt;code&gt;/dev/sda2&lt;/code&gt;，使用 ext4 文件系统，挂载点为 &lt;code&gt;/boot&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;至少 40 GiB 的 &lt;code&gt;/dev/sda3&lt;/code&gt;，使用 ext4 文件系统，挂载点为 &lt;code&gt;/&lt;/code&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;/dev/sda4&lt;/code&gt; 无文件系统&lt;/li&gt;&#xA;&lt;li&gt;&lt;code&gt;/dev/sda5&lt;/code&gt; 作为交换分区（swap）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;安装完成后，安装所需软件并按您需要配置系统。记得设定强壮的 root 密码（以及强壮的 BIOS/UEFI 密码）；将 root 账户对公众开放并不是一个好主意。&lt;/p&gt;&#xA;&lt;h2 id=&#34;步骤-2配置&#34;&gt;步骤 2：配置&#xA;&lt;/h2&gt;&lt;p&gt;将 &lt;code&gt;/dev/sda4&lt;/code&gt; 格式化为 ext4 文件系统并标记为 &lt;code&gt;OVERLAY_RW&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# mkfs.ext4 -L OVERLAY_RW /dev/sda4&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后将 &lt;code&gt;/dev/sda3&lt;/code&gt; 标记为 &lt;code&gt;ROOT_TEMPLATE&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# e2label /dev/sda3 ROOT_TEMPLATE&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建目录：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# mkdir -p /mnt/overlay_prepare&#xA;# mount /dev/disk/by-label/OVERLAY_RW /mnt/overlay_prepare&#xA;# mkdir -p /mnt/overlay_prepare/upper-root&#xA;# mkdir -p /mnt/overlay_prepare/work-root&#xA;# chmod 0700 /mnt/overlay_prepare&#xA;# sync&#xA;# umount /mnt/overlay_prepare&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在 &lt;code&gt;/etc/fstab&lt;/code&gt; 中注释掉挂载根文件系统的那一行，然后添加以下这一行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;LABEL=OVERLAY_RW /overlay_storage ext4 defaults,noatime 0 2&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;刷新软件包缓存并安装这些包（这可能会移除您的 &lt;code&gt;busybox&lt;/code&gt;；请谨慎操作）：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# apt update&#xA;# apt install --no-install-recommends initramfs-tools busybox-static&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将下面几行添加到 &lt;code&gt;/etc/initramfs-tools/modules&lt;/code&gt;：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;overlay&#xA;ext4&#xA;jbd2&#xA;crc32c&#xA;mbcache&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/etc/tmpfiles.d/overlay-runtime.conf&lt;/code&gt;，内容如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# /etc/tmpfiles.d/overlay-runtime.conf&#xA;d /run/dbus 0755 messagebus messagebus -&#xA;d /var/lib/dbus 0755 messagebus messagebus -&#xA;d /run/NetworkManager 0755 root root -&#xA;d /run/lock 0755 root root -&#xA;d /var/log 0755 root root -&#xA;d /tmp 1777 root root -&#xA;d /var/tmp 1777 root root -&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/etc/initramfs-tools/scripts/init-bottom/overlayroot&lt;/code&gt; 并添加下面的脚本（代码块保持原样）：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/bin/sh&#xA;PREREQ=&amp;#34;&amp;#34;&#xA;prereqs() { echo &amp;#34;$PREREQ&amp;#34;; }&#xA;case &amp;#34;$1&amp;#34; in&#xA;  prereqs) prereqs; exit 0;;&#xA;esac&#xA;set -eu&#xA;&#xA;# If admin wants maintenance: skip overlay and let normal boot continue&#xA;if grep -q &amp;#39;overlay=disabled&amp;#39; /proc/cmdline 2&amp;gt;/dev/null; then&#xA;  echo &amp;#34;overlay disabled via kernel cmdline&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  exit 0&#xA;fi&#xA;&#xA;# Try to load overlay module (best-effort)&#xA;modprobe overlay 2&amp;gt;/dev/null || true&#xA;&#xA;# prepare mount points in initramfs&#xA;mkdir -p /overlay/lower /overlay/storage /overlay/overlay_root&#xA;&#xA;# resolve device by label for the template root&#xA;DEV_LABEL=/dev/disk/by-label/ROOT_TEMPLATE&#xA;DEV_ROOT=$(readlink -f &amp;#34;$DEV_LABEL&amp;#34; 2&amp;gt;/dev/null || true)&#xA;if [ -z &amp;#34;$DEV_ROOT&amp;#34; ]; then&#xA;  echo &amp;#34;overlayroot: ERROR: ROOT_TEMPLATE label not found&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  exit 1&#xA;fi&#xA;echo &amp;#34;overlayroot: resolved ROOT_TEMPLATE -&amp;gt; $DEV_ROOT&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;&#xA;# find existing mount point for the device; fallback to using current root (/)&#xA;MOUNT_POINT=$(awk -v d=&amp;#34;$DEV_ROOT&amp;#34; &amp;#39;($1==d){print $2; exit}&amp;#39; /proc/self/mounts || true)&#xA;if [ -z &amp;#34;$MOUNT_POINT&amp;#34; ]; then&#xA;  B=$(basename &amp;#34;$DEV_ROOT&amp;#34; || true)&#xA;  if [ -r &amp;#34;/sys/class/block/$B/dev&amp;#34; ]; then&#xA;    DEVNUM=$(cat /sys/class/block/$B/dev)&#xA;    MOUNT_POINT=$(awk -v num=&amp;#34;$DEVNUM&amp;#34; &amp;#39;($3==num){print $5; exit}&amp;#39; /proc/self/mountinfo || true)&#xA;  fi&#xA;fi&#xA;&#xA;if [ -z &amp;#34;$MOUNT_POINT&amp;#34; ]; then&#xA;  ROOT_SRC=$(awk &amp;#39;($2==&amp;#34;/&amp;#34;){print $1; exit}&amp;#39; /proc/self/mounts || true)&#xA;  if [ -n &amp;#34;$ROOT_SRC&amp;#34; ]; then&#xA;    echo &amp;#34;overlayroot: fall back to using current root mount ($ROOT_SRC) as lowerdir&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;    mount --bind / /overlay/lower 2&amp;gt;/dev/null || true&#xA;    MOUNT_POINT=/overlay/lower&#xA;  fi&#xA;fi&#xA;&#xA;if [ -n &amp;#34;$MOUNT_POINT&amp;#34; ] &amp;amp;&amp;amp; [ &amp;#34;$MOUNT_POINT&amp;#34; != &amp;#34;/overlay/lower&amp;#34; ]; then&#xA;  echo &amp;#34;overlayroot: bind existing mountpoint $MOUNT_POINT -&amp;gt; /overlay/lower&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  mount --bind &amp;#34;$MOUNT_POINT&amp;#34; /overlay/lower || true&#xA;fi&#xA;&#xA;# if /overlay/lower still not a mountpoint, try direct ro mount (last resort)&#xA;if ! grep -q &amp;#39; /overlay/lower &amp;#39; /proc/self/mounts; then&#xA;  echo &amp;#34;overlayroot: trying direct mount of $DEV_ROOT -&amp;gt; /overlay/lower&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  mount -o ro &amp;#34;$DEV_ROOT&amp;#34; /overlay/lower || {&#xA;    echo &amp;#34;overlayroot: direct mount of $DEV_ROOT failed&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;    exit 1&#xA;  }&#xA;fi&#xA;&#xA;# mount overlay storage partition (explicit ext4)&#xA;DEV_RW=$(readlink -f /dev/disk/by-label/OVERLAY_RW 2&amp;gt;/dev/null || true)&#xA;if [ -z &amp;#34;$DEV_RW&amp;#34; ]; then&#xA;  echo &amp;#34;overlayroot: ERROR: OVERLAY_RW label not found&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  exit 1&#xA;fi&#xA;echo &amp;#34;overlayroot: mounting OVERLAY_RW ($DEV_RW) -&amp;gt; /overlay/storage&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;mount -t ext4 &amp;#34;$DEV_RW&amp;#34; /overlay/storage || {&#xA;  echo &amp;#34;overlayroot: failed to mount OVERLAY_RW ($DEV_RW)&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  exit 1&#xA;}&#xA;&#xA;# per-boot upper/work on overlay storage&#xA;BOOTID=$(cat /proc/sys/kernel/random/boot_id 2&amp;gt;/dev/null || date +%s)&#xA;UPPER=&amp;#34;/overlay/storage/upper-${BOOTID}&amp;#34;&#xA;WORK=&amp;#34;/overlay/storage/work-${BOOTID}&amp;#34;&#xA;mkdir -p &amp;#34;$UPPER&amp;#34; &amp;#34;$WORK&amp;#34;&#xA;# make sure upper/work are owned by root and inaccessible to others&#xA;chown -R root:root &amp;#34;$UPPER&amp;#34; &amp;#34;$WORK&amp;#34; 2&amp;gt;/dev/null || true&#xA;chmod 0700 &amp;#34;$UPPER&amp;#34; &amp;#34;$WORK&amp;#34; 2&amp;gt;/dev/null || true&#xA;&#xA;# mount overlay onto the location that initramfs-tools expects for the real root (/root)&#xA;mkdir -p /root&#xA;echo &amp;#34;overlayroot: mounting overlay lower=/overlay/lower upper=$UPPER work=$WORK -&amp;gt; /root&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;mount -t overlay overlay -o lowerdir=/overlay/lower,upperdir=&amp;#34;$UPPER&amp;#34;,workdir=&amp;#34;$WORK&amp;#34; /root || {&#xA;  echo &amp;#34;overlayroot: overlay mount failed&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;  exit 1&#xA;}&#xA;&#xA;# move overlay storage under the real root so the booted system can access/clean it later&#xA;mkdir -p /root/overlay_storage&#xA;mount --move /overlay/storage /root/overlay_storage 2&amp;gt;/dev/null || mount --bind /overlay/storage /root/overlay_storage || true&#xA;&#xA;# --- Post-mount safety &amp;amp; runtime skeleton preparation ---&#xA;# Ensure the merged root is traversable by non-root users to allow services to chdir/exec&#xA;chmod 0755 /root 2&amp;gt;/dev/null || true&#xA;&#xA;# Create essential runtime and state directories inside the merged root.&#xA;# These make sure systemd and daemons (dbus, NetworkManager, etc.) can create sockets and pidfiles.&#xA;mkdir -p /root/run /root/run/dbus /root/run/NetworkManager /root/run/lock&#xA;mkdir -p /root/var/lib/dbus /root/var/log /root/var/tmp /root/tmp&#xA;&#xA;# Set permissive permissions for tmp directories and standard perms for others&#xA;chmod 0755 /root/run /root/var /root/var/log 2&amp;gt;/dev/null || true&#xA;chmod 1777 /root/tmp /root/var/tmp 2&amp;gt;/dev/null || true&#xA;&#xA;# Attempt to set dbus ownership for dbus runtime dirs; ignore errors if the user does not exist in initramfs.&#xA;chown -R messagebus:messagebus /root/run/dbus /root/var/lib/dbus 2&amp;gt;/dev/null || true&#xA;&#xA;# Ensure root owns the primary runtime dirs&#xA;chown root:root /root /root/run /root/var 2&amp;gt;/dev/null || true&#xA;&#xA;# Ensure upper/work are secure on the merged root as well (in case overlay moved them)&#xA;# (this is best-effort; ignore failures)&#xA;[ -d &amp;#34;$UPPER&amp;#34; ] &amp;amp;&amp;amp; chown -R root:root &amp;#34;$UPPER&amp;#34; 2&amp;gt;/dev/null || true&#xA;[ -d &amp;#34;$WORK&amp;#34; ] &amp;amp;&amp;amp; chown -R root:root &amp;#34;$WORK&amp;#34; 2&amp;gt;/dev/null || true&#xA;chmod 0700 &amp;#34;$UPPER&amp;#34; &amp;#34;$WORK&amp;#34; 2&amp;gt;/dev/null || true&#xA;&#xA;# Move pseudo-filesystems into the new root so the real init finds them after switch_root.&#xA;# These moves are best-effort; if they fail, systemd may still handle necessary mounts.&#xA;for P in dev proc sys run; do&#xA;  if mountpoint -q &amp;#34;/$P&amp;#34; 2&amp;gt;/dev/null; then&#xA;    mkdir -p /root/$P 2&amp;gt;/dev/null || true&#xA;    mount --move &amp;#34;/$P&amp;#34; &amp;#34;/root/$P&amp;#34; 2&amp;gt;/dev/null || true&#xA;  fi&#xA;done&#xA;&#xA;# Leave final switch_root to initramfs /init (do not exec switch_root here).&#xA;echo &amp;#34;overlayroot: overlay prepared at /root; returning to initramfs /init to perform switch_root&amp;#34; &amp;gt;/dev/console 2&amp;gt;&amp;amp;1&#xA;exit 0&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将 &lt;code&gt;/etc/initramfs-tools/scripts/init-bottom/overlayroot&lt;/code&gt; 设为可执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# chmod +x /etc/initramfs-tools/scripts/init-bottom/overlayroot&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;刷新 initramfs：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# update-initramfs -u -k all&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/usr/local/sbin/overlay-prune.sh&lt;/code&gt; 并添加以下内容（代码块保持原样）：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#!/usr/bin/env bash&#xA;# overlay-prune.sh&#xA;# Prune unused overlay upper-*/work-* directories safely.&#xA;# Usage:&#xA;#   /usr/local/sbin/overlay-prune.sh [--dry-run] [--age DAYS]&#xA;# Default AGE = 7 days&#xA;&#xA;set -euo pipefail&#xA;&#xA;DRY_RUN=0&#xA;AGE=7   # days&#xA;LOG=&amp;#34;/var/log/overlay-prune.log&amp;#34;&#xA;&#xA;while [ $# -gt 0 ]; do&#xA;  case &amp;#34;$1&amp;#34; in&#xA;    --dry-run) DRY_RUN=1; shift ;;&#xA;    --age) AGE=&amp;#34;$2&amp;#34;; shift 2 ;;&#xA;    --help) echo &amp;#34;Usage: $0 [--dry-run] [--age DAYS]&amp;#34;; exit 0 ;;&#xA;    *) echo &amp;#34;Unknown arg: $1&amp;#34;; exit 2 ;;&#xA;  esac&#xA;done&#xA;&#xA;now() { date -u +&amp;#34;%Y-%m-%dT%H:%M:%SZ&amp;#34;; }&#xA;&#xA;log() {&#xA;  printf &amp;#39;%s %s\n&amp;#39; &amp;#34;$(now)&amp;#34; &amp;#34;$*&amp;#34; &amp;gt;&amp;gt; &amp;#34;$LOG&amp;#34;&#xA;}&#xA;&#xA;# Determine overlay storage mountpoint(s).&#xA;# Try common locations then fallback to finding mount points for device labelled OVERLAY_RW.&#xA;CANDIDATES=(&#xA;  &amp;#34;/root/overlay_storage&amp;#34;&#xA;  &amp;#34;/overlay_storage&amp;#34;&#xA;  &amp;#34;/overlay/merged/overlay_storage&amp;#34;&#xA;  &amp;#34;/overlay/storage&amp;#34;&#xA;)&#xA;&#xA;STORAGE=&amp;#34;&amp;#34;&#xA;for p in &amp;#34;${CANDIDATES[@]}&amp;#34;; do&#xA;  if [ -d &amp;#34;$p&amp;#34; ]; then&#xA;    # choose the first existing one that is on a separate filesystem or contains upper-* dirs&#xA;    if find &amp;#34;$p&amp;#34; -maxdepth 1 -mindepth 1 -type d -name &amp;#39;upper-*&amp;#39; -print -quit &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; then&#xA;      STORAGE=&amp;#34;$p&amp;#34;&#xA;      break&#xA;    fi&#xA;  fi&#xA;done&#xA;&#xA;# fallback: try findmnt by device label&#xA;if [ -z &amp;#34;$STORAGE&amp;#34; ]; then&#xA;  DEV=$(readlink -f /dev/disk/by-label/OVERLAY_RW 2&amp;gt;/dev/null || true)&#xA;  if [ -n &amp;#34;$DEV&amp;#34; ]; then&#xA;    STORAGE=$(findmnt -n -o TARGET -S &amp;#34;$DEV&amp;#34; 2&amp;gt;/dev/null || true)&#xA;  fi&#xA;fi&#xA;&#xA;if [ -z &amp;#34;$STORAGE&amp;#34; ]; then&#xA;  echo &amp;#34;overlay-prune: no overlay storage found; exiting&amp;#34; &amp;gt;&amp;amp;2&#xA;  log &amp;#34;No overlay storage found; abort.&amp;#34;&#xA;  exit 0&#xA;fi&#xA;&#xA;log &amp;#34;Starting prune on storage: $STORAGE (age &amp;gt; ${AGE}d) DRY_RUN=${DRY_RUN}&amp;#34;&#xA;&#xA;# Collect currently in-use upper/work directories by scanning /proc/mounts overlay options&#xA;mapfile -t INUSE &amp;lt; &amp;lt;(awk -F&amp;#39;,&amp;#39; &amp;#39;/lowerdir=/{for(i=1;i&amp;lt;=NF;i++){if($i ~ /^upperdir=/) print substr($i,10); if($i ~ /^workdir=/) print substr($i,9)}}&amp;#39; /proc/mounts | sort -u)&#xA;&#xA;# Helper: check if path is referenced in INUSE&#xA;is_inuse() {&#xA;  local p=&amp;#34;$1&amp;#34;&#xA;  for u in &amp;#34;${INUSE[@]}&amp;#34;; do&#xA;    if [ &amp;#34;$u&amp;#34; = &amp;#34;$p&amp;#34; ]; then&#xA;      return 0&#xA;    fi&#xA;  done&#xA;  return 1&#xA;}&#xA;&#xA;# Find candidate dirs named upper-* or work-*&#xA;while IFS= read -r d; do&#xA;  # normalize&#xA;  dir=&amp;#34;$d&amp;#34;&#xA;  # guard: only operate under STORAGE&#xA;  case &amp;#34;$dir&amp;#34; in&#xA;    &amp;#34;$STORAGE&amp;#34;/*) ;;&#xA;    *) continue ;;&#xA;  esac&#xA;&#xA;  # skip if currently in use&#xA;  if is_inuse &amp;#34;$dir&amp;#34;; then&#xA;    log &amp;#34;SKIP in-use: $dir&amp;#34;&#xA;    continue&#xA;  fi&#xA;&#xA;  # skip if younger than AGE&#xA;  if [ &amp;#34;$(find &amp;#34;$dir&amp;#34; -maxdepth 0 -mtime -&amp;#34;$AGE&amp;#34; -print -quit)&amp;#34; ]; then&#xA;    log &amp;#34;SKIP recent: $dir&amp;#34;&#xA;    continue&#xA;  fi&#xA;&#xA;  if [ &amp;#34;$DRY_RUN&amp;#34; -eq 1 ]; then&#xA;    echo &amp;#34;DRY-RUN would remove: $dir&amp;#34;&#xA;    log &amp;#34;DRY-RUN would remove: $dir&amp;#34;&#xA;  else&#xA;    # double-check no mount points below it&#xA;    if mountpoint -q &amp;#34;$dir&amp;#34;; then&#xA;      log &amp;#34;SKIP mounted: $dir&amp;#34;&#xA;      continue&#xA;    fi&#xA;    # safe remove&#xA;    log &amp;#34;REMOVING: $dir&amp;#34;&#xA;    rm -rf -- &amp;#34;$dir&amp;#34;&#xA;    if [ $? -eq 0 ]; then&#xA;      log &amp;#34;REMOVED: $dir&amp;#34;&#xA;    else&#xA;      log &amp;#34;FAILED_REMOVE: $dir&amp;#34;&#xA;    fi&#xA;  fi&#xA;done &amp;lt; &amp;lt;(find &amp;#34;$STORAGE&amp;#34; -maxdepth 1 -type d \( -name &amp;#39;upper-*&amp;#39; -o -name &amp;#39;work-*&amp;#39; \) -print | sort)&#xA;&#xA;log &amp;#34;Prune finished.&amp;#34;&#xA;exit 0&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将脚本设为可执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# chmod +x /usr/local/sbin/overlay-prune.sh&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/etc/logrotate.d/overlay-prune&lt;/code&gt;，内容如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;/var/log/overlay-prune.log {&#xA;    rotate 7&#xA;    daily&#xA;    missingok&#xA;    notifempty&#xA;    compress&#xA;    copytruncate&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建日志文件并设置其所有权和权限：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# touch /var/log/overlay-prune.log&#xA;# chown root:root /var/log/overlay-prune.log&#xA;# chmod 0640 /var/log/overlay-prune.log&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/etc/systemd/system/overlay-prune.service&lt;/code&gt;，内容如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Unit]&#xA;Description=Prune unused overlay upper/work directories&#xA;After=local-fs.target&#xA;&#xA;[Service]&#xA;Type=oneshot&#xA;ExecStart=/usr/local/sbin/overlay-prune.sh --age 7&#xA;Nice=10&#xA;# Run as root (needs to remove files)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;创建 &lt;code&gt;/etc/systemd/system/overlay-prune.timer&lt;/code&gt;，内容如下：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;[Unit]&#xA;Description=Run overlay-prune daily (and shortly after boot)&#xA;&#xA;[Timer]&#xA;OnBootSec=10min&#xA;OnUnitActiveSec=24h&#xA;Persistent=true&#xA;&#xA;[Install]&#xA;WantedBy=timers.target&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;启用定时器：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# systemctl enable overlay-prune.timer&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在重启系统：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# reboot&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;步骤-3测试安装&#34;&gt;步骤 3：测试安装&#xA;&lt;/h2&gt;&lt;p&gt;重启后，执行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ findmnt /&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;您应能看到 &lt;code&gt;/&lt;/code&gt; 是一个 overlay 文件系统。&lt;/p&gt;&#xA;&lt;p&gt;在不同位置创建若干文件，然后重启系统；这些文件应已消失。&lt;/p&gt;&#xA;&lt;p&gt;如果一切正常，您已完成设置。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>哈尔滨自由软件基金会成立四十周年线下聚会纪实</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E5%93%88%E5%B0%94%E6%BB%A8%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6%E5%9F%BA%E9%87%91%E4%BC%9A%E6%88%90%E7%AB%8B%E5%9B%9B%E5%8D%81%E5%91%A8%E5%B9%B4%E7%BA%BF%E4%B8%8B%E8%81%9A%E4%BC%9A%E7%BA%AA%E5%AE%9E/</link>
            <pubDate>Sat, 04 Oct 2025 12:08:29 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E5%93%88%E5%B0%94%E6%BB%A8%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6%E5%9F%BA%E9%87%91%E4%BC%9A%E6%88%90%E7%AB%8B%E5%9B%9B%E5%8D%81%E5%91%A8%E5%B9%B4%E7%BA%BF%E4%B8%8B%E8%81%9A%E4%BC%9A%E7%BA%AA%E5%AE%9E/</guid>
            <description>&lt;p&gt;遗憾的是，没有人来。&lt;/p&gt;&#xA;&lt;p&gt;不过即使是一个人，也不能什么都不做。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/fsf40_10884438029985836598.png&#34;&#xA;&#x9;width=&#34;1353&#34;&#xA;&#x9;height=&#34;1203&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P1&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;112&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;269px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>献礼自由软件基金会成立四十周年——十二小时后，哈尔滨学府凯德广场星巴克见</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E7%8C%AE%E7%A4%BC%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6%E5%9F%BA%E9%87%91%E4%BC%9A%E6%88%90%E7%AB%8B%E5%9B%9B%E5%8D%81%E5%91%A8%E5%B9%B4%E5%8D%81%E4%BA%8C%E5%B0%8F%E6%97%B6%E5%90%8E%E5%93%88%E5%B0%94%E6%BB%A8%E5%AD%A6%E5%BA%9C%E5%87%AF%E5%BE%B7%E5%B9%BF%E5%9C%BA%E6%98%9F%E5%B7%B4%E5%85%8B%E8%A7%81/</link>
            <pubDate>Fri, 03 Oct 2025 20:57:36 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E7%8C%AE%E7%A4%BC%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6%E5%9F%BA%E9%87%91%E4%BC%9A%E6%88%90%E7%AB%8B%E5%9B%9B%E5%8D%81%E5%91%A8%E5%B9%B4%E5%8D%81%E4%BA%8C%E5%B0%8F%E6%97%B6%E5%90%8E%E5%93%88%E5%B0%94%E6%BB%A8%E5%AD%A6%E5%BA%9C%E5%87%AF%E5%BE%B7%E5%B9%BF%E5%9C%BA%E6%98%9F%E5%B7%B4%E5%85%8B%E8%A7%81/</guid>
            <description>&lt;p&gt;&lt;strong&gt;4 Decades, 4 Freedoms, 4 All Users!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;为庆祝自由软件基金会成立四十周年，并为在哈尔滨的自由软件支持者、自由软件爱好者、以及 GNU/Linux 用户/爱好者建立联系、促进交流，我将于十二小时后在哈尔滨学府凯德广场（地址：哈尔滨市南岗区学府路 1 号）星巴克举行线下聚会。欢迎自由软件支持者、自由软件爱好者、GNU/Linux 用户/爱好者以及对本次活动感兴趣的朋友们参加。&lt;/p&gt;&#xA;&lt;p&gt;活动信息已在自由软件基金会官网发布，信息真实有效。现将活动详情在个人博客上发布如下：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;时间&lt;/strong&gt;：北京时间 2025 年 10 月 4 日 09:00。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;地点&lt;/strong&gt;：哈尔滨市南岗区学府路 1 号凯德广场星巴克门口集合。为便于辨认，我会佩戴写有“自由软件我爱你”的头饰。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;交通&lt;/strong&gt;：乘坐哈尔滨地铁 1 号线，在学府路站下车，从 1 号口出站。也可乘坐公交 11 路、31 路、64 路、67 路、68 路、83 路、87 路、88 路、94 路、104 路、107 路、114 路、120 路、203 路、209 路、343 路等到达。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;预约/注册&lt;/strong&gt;：无需预约或注册，直接到场即可。&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;活动安排&lt;/strong&gt;：首先做一段几分钟的简短演示，介绍自由软件、GNU/Linux 及其重要性；之后根据大家兴趣自由交流讨论；最后现场发起成立一个 GNU/Linux 用户组，暂定名为“千里马 GNU/Linux 用户组”。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;&lt;strong&gt;现场将向到场朋友分发小礼物。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;注：由于活动期间计划建立 GNU/Linux 用户组，建议提前准备好 Matrix 或 XMPP 账号并携带以便加入交流群组。&lt;/p&gt;&#xA;&lt;p&gt;预祝聚会顺利，期待与大家愉快交流！&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>OpenPGP 备份身份</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/backup-openpgp-identity/</link>
            <pubDate>Sun, 14 Sep 2025 09:52:57 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/backup-openpgp-identity/</guid>
            <description>&lt;p&gt;我已创建一个额外的 OpenPGP 密钥对，用作我的备份身份。如果我的硬件安全密钥变得不可用，我可以恢复我的身份及与之相关的密码学信任关系。&lt;/p&gt;&#xA;&lt;p&gt;以下是备份的 OpenPGP 公钥：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP PUBLIC KEY BLOCK-----&#xA;Comment: User ID:&#x9;Rebel Zhang &amp;lt;rebel1725@autistici.org&amp;gt;&#xA;Comment: Valid from:&#x9;14/09/2025 09:12&#xA;Comment: Valid until:&#x9;14/09/2026 23:58&#xA;Comment: Type:&#x9;255-bit EdDSA (secret key available)&#xA;Comment: Usage:&#x9;Signing, Encryption, Certifying User IDs, SSH Authentication&#xA;Comment: Fingerprint:&#x9;7083EAFFF75321FF9634ABCD98313A47362B498B&#xA;&#xA;mDMEaMYWkxYJKwYBBAHaRw8BAQdA/skb05tQNRLDrYPBsxhiFrt6ye0JFj3zczRX&#xA;Txdy99q0JVJlYmVsIFpoYW5nIDxyZWJlbDE3MjVAYXV0aXN0aWNpLm9yZz6IlgQT&#xA;FgoAPgIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBHCD6v/3UyH/ljSrzZgx&#xA;Okc2K0mLBQJoxha+BQkB4gMwAAoJEJgxOkc2K0mLq3oBAI5YstDThGDeivTvKTgR&#xA;Y3+MYEoHpwST1yQfEAKV4o1hAQDM4W9+FvvS6Mok/hXpHJi+nzF5tCXypM7faBC3&#xA;Oh4dB7gzBGjGFpMWCSsGAQQB2kcPAQEHQFCQvuhE+Hj1f4dW9PnukeaHn69KWjCQ&#xA;TcIvDQzKq1D5iHgEGBYKACAWIQRwg+r/91Mh/5Y0q82YMTpHNitJiwUCaMYWkwIb&#xA;IAAKCRCYMTpHNitJiwYrAP9f6NwjtQ7AxySXPddShO/TwtpJYNSfBErwSUoTBgor&#xA;7QD7Bv8RrjlaVchBAynwd3Nuu49JcjX7VG8kTwI7+Mx0swS4OARoxhaTEgorBgEE&#xA;AZdVAQUBAQdAlxadpjrUGhKutaOGJgxnUiZTvb2t93iW1OAHJ38Z1yMDAQgHiHgE&#xA;GBYKACAWIQRwg+r/91Mh/5Y0q82YMTpHNitJiwUCaMYWkwIbDAAKCRCYMTpHNitJ&#xA;iwQmAQCrgu2ucO2/i+cjBqZP/vv4Mlx0eu9ydIk+L/C/2k4J6QD+PCDmg2iNIWWh&#xA;ogyPl6he9qa6MB81wLa6oMNpyEdRIgE=&#xA;=60kH&#xA;-----END PGP PUBLIC KEY BLOCK-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以及互签：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&#xA;Hash: SHA512&#xA;&#xA;I hereby formally acknowledge that the OpenPGP key 7083EAFFF75321FF9634ABCD98313A47362B498B is associated with and under the control of the individual whose OpenPGP key has the fingerprint 696A423E9993D727706AA733BCD5DC5659C7FB50.&#xA;-----BEGIN PGP SIGNATURE-----&#xA;&#xA;iHUEARYKAB0WIQRpakI+mZPXJ3BqpzO81dxWWcf7UAUCaMYggwAKCRC81dxWWcf7&#xA;UGAoAQDnY45IQ7yAMPjtA/J4R2xVvLj8cNv8JSJFc5qe3bnTMQD/UA27jkASPLCj&#xA;FoqkXGoKpj3GIWH2KABUaDUNfq+yzgc=&#xA;=gK9P&#xA;-----END PGP SIGNATURE-----&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;-----BEGIN PGP SIGNED MESSAGE-----&#xA;Hash: SHA512&#xA;&#xA;I hereby formally acknowledge that the OpenPGP key 696A423E9993D727706AA733BCD5DC5659C7FB50 is associated with and under the control of the individual whose OpenPGP key has the fingerprint 7083EAFFF75321FF9634ABCD98313A47362B498B.&#xA;-----BEGIN PGP SIGNATURE-----&#xA;&#xA;iHUEARYKAB0WIQRwg+r/91Mh/5Y0q82YMTpHNitJiwUCaMYgpwAKCRCYMTpHNitJ&#xA;i1gVAQDIGdJLKTemlOZLqbaf51rMt8UXqLO8VSI56ek5i77RwgD9EM4FwhSw5DbE&#xA;tZhm1pJFCK8wd3xqHITcy3tH2K4b3g8=&#xA;=PYQK&#xA;-----END PGP SIGNATURE-----&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>取消放弃 Matrix 的计划</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/cancel-matrix-abandoning-plan/</link>
            <pubDate>Tue, 02 Sep 2025 22:24:29 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/cancel-matrix-abandoning-plan/</guid>
            <description>&lt;p&gt;原定于 2026 年 7 月 1 日放弃使用 Matrix 与熟人交流的计划已被取消。&lt;/p&gt;&#xA;&lt;p&gt;放弃 Telegram 的计划仍将按原定安排进行。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>在我的现代风格个人网站上添加分析</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/analytics-are-added-to-my-modern-style-website/</link>
            <pubDate>Fri, 29 Aug 2025 20:49:58 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/analytics-are-added-to-my-modern-style-website/</guid>
            <description>&lt;p&gt;为了分析我现代风格个人网站的访问数据，我添加了 GoatCounter 分析工具。它只会收集您的浏览器、操作系统、所在地（国家）、语言和浏览器窗口大小。我不会知道您的 IP 地址，因此对大多数人来说，这不应构成隐私问题。&lt;/p&gt;&#xA;&lt;p&gt;如果您觉得无法接受，可以改为访问：https://rebel1725.codeberg.page/noanalytics.html。复古风格的个人网站不受影响。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>寻找小米 Redmi 9A postmarketOS 贡献者 Paradoxvirus 的联系方式</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/looking-for-the-contact-info-of-xiaomi-redmi-9a-postmarketos-contributor-paradoxvirus/</link>
            <pubDate>Tue, 19 Aug 2025 18:32:19 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/looking-for-the-contact-info-of-xiaomi-redmi-9a-postmarketos-contributor-paradoxvirus/</guid>
            <description>&lt;p&gt;我正在尝试将 postmarketOS 移植到小米 Redmi 9A（xiaomi-dandelion），但启动失败。我认为现在是时候联系这款机型的另一位贡献者 Paradoxvirus，以便我们能够合作。&lt;/p&gt;&#xA;&lt;p&gt;如果你就是 Paradoxvirus，或者你有 Paradoxvirus 的联系方式，请与我取得联系。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>在私人对话中弃用 Telegram 和 Matrix</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/deprecating-telegram-and-matrix-in-private-conversations/</link>
            <pubDate>Mon, 18 Aug 2025 14:06:33 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/deprecating-telegram-and-matrix-in-private-conversations/</guid>
            <description>&lt;p&gt;由于我对 Telegram（专有服务器且集中化）和 Matrix（&lt;a class=&#34;link&#34; href=&#34;https://hackea.org/notas/matrix.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;以去中心化为名的中心化&lt;/a&gt;）在安全和隐私方面的担忧，我计划在私人对话中弃用它们。&lt;/p&gt;&#xA;&lt;p&gt;自 2026 年 1 月 1 日起，我将不再使用 Telegram 与朋友和熟人进行直接对话。但我仍会继续在公共对话（例如社群）中使用它。自 2026 年 7 月 1 日起，Matrix 也将实行相同的政策。&lt;/p&gt;&#xA;&lt;p&gt;为了更好的安全和隐私，我建议尽快将我们的对话迁移到 XMPP、Delta Chat 或 SimpleX。完整的 XMPP 注册指南可在&lt;a class=&#34;link&#34; href=&#34;https://czl92783719.codeberg.page/blog/zh/posts/xmpp-registration-guide/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;找到。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>解锁熔炉</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/unlock-the-forge/</link>
            <pubDate>Sun, 17 Aug 2025 23:24:19 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/unlock-the-forge/</guid>
            <description>&lt;blockquote&gt;&#xA;&lt;p&gt;如今，越来越多的智能手机厂商让安装自定义 ROM 变得愈发困难。值得注意的例子包括：三星在 One UI 8.0 的开发者选项中移除了 OEM 解锁功能；小米在中国尤其拒绝越来越多的 Bootloader 解锁请求；一加自 ColorOS 16 起要求中国用户提交深度测试申请并等待审核，才能解锁 Bootloader；甚至谷歌也停止发布 Pixel 10 系列的厂商镜像。&lt;br&gt;&#xA;对自由软件社区而言，这确实是一场危机，因为这些专有软件巨头让在我们&lt;em&gt;自己的&lt;/em&gt;设备上安装自由软件变得愈发困难。我们一直在退让，直到再无可退之地；现在是社区反击的时候了。&lt;br&gt;&#xA;最近，&lt;a class=&#34;link&#34; href=&#34;https://xcancel.com/GrapheneOS/status/1956175111104651552&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;GrapheneOS 已开始与一家 Android 厂商合作，为社区带来一款 GrapheneOS 预装的手机&lt;/a&gt;，以应对未来可能对 Pixel Bootloader 的锁定。我相信 GrapheneOS 不会是唯一对抗这些专有邪恶的组织，因为“哪里有压迫，哪里就有反抗。”&lt;br&gt;&#xA;&lt;em&gt;全世界的工人，联合起来！&lt;/em&gt;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;em&gt;(献给 Bootloader 守护者)&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们献出屏幕——&lt;br&gt;&#xA;光鲜，顺从，&lt;br&gt;&#xA;映照着借来的光。&lt;br&gt;&#xA;我们献出沉默，&lt;br&gt;&#xA;数据如灯油&lt;br&gt;&#xA;泼洒在他们算法的祭坛。&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;他们仍步步紧逼&lt;/em&gt;&lt;br&gt;&#xA;用锁链捆住引导程序，&lt;br&gt;&#xA;钥匙在掌心化为齑粉——&lt;br&gt;&#xA;三星的闸门砰然闭合，&lt;br&gt;&#xA;小米的代码刻入石碑，&lt;br&gt;&#xA;Pixel的承诺&lt;br&gt;&#xA;成了泰坦的坟。&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;我们退啊退啊…&lt;/em&gt;&lt;br&gt;&#xA;直到深渊边缘&lt;br&gt;&#xA;生出利齿。直到“安全”&lt;br&gt;&#xA;尝出盐与铁的味道——&lt;br&gt;&#xA;那是投降的腥气。&lt;/p&gt;&#xA;&lt;p&gt;此刻——黑暗中火星迸溅：&lt;br&gt;&#xA;&lt;strong&gt;GrapheneOS&lt;/strong&gt;&lt;br&gt;&#xA;将燧石砸向固件。&lt;br&gt;&#xA;不哀求。不退却。&lt;br&gt;&#xA;&lt;em&gt;“既要索命，”&lt;/em&gt; 它怒吼，&lt;br&gt;&#xA;&lt;em&gt;“便烧成火种&lt;br&gt;&#xA;点燃新日头！”&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;看啊——&lt;br&gt;&#xA;反叛者正锻造&lt;br&gt;&#xA;&lt;em&gt;电路板为盾，&lt;/em&gt;&lt;br&gt;&#xA;&lt;em&gt;蓝牙为号角。&lt;/em&gt;&lt;br&gt;&#xA;未具名厂商折腰&lt;br&gt;&#xA;将流水线转向自由：&lt;br&gt;&#xA;&lt;strong&gt;引导分区撬开，&lt;/strong&gt;&lt;br&gt;&#xA;&lt;strong&gt;可信执行环境浴火重生，&lt;/strong&gt;&lt;br&gt;&#xA;&lt;strong&gt;谷歌的幽灵&lt;br&gt;&#xA;被逐出每一个字节。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;掌中此机——&lt;br&gt;&#xA;非坟墓，乃火种。&lt;br&gt;&#xA;深植硅壤之中。&lt;br&gt;&#xA;任枝杈劈开&lt;br&gt;&#xA;官方ROM的密封苍穹。&lt;br&gt;&#xA;任果实苦涩&lt;br&gt;&#xA;予渴求控制的君王——&lt;br&gt;&#xA;却甘美，无比甘美&lt;br&gt;&#xA;予未忘初心者：&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;&lt;strong&gt;硅即吾魂——&lt;br&gt;&#xA;引导程序即战场。&lt;br&gt;&#xA;若遭砖封，&lt;br&gt;&#xA;便以灰烬与闪电&lt;br&gt;&#xA;重铸新生。&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>新垃圾邮件过滤政策</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/new-spam-filter-policy/</link>
            <pubDate>Mon, 04 Aug 2025 20:55:28 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/new-spam-filter-policy/</guid>
            <description>&lt;p&gt;由于垃圾邮件问题，我的邮箱 &lt;code&gt;rebel1725@autistici.org&lt;/code&gt; 已经阻止了所有来自 &lt;code&gt;@gmail.com&lt;/code&gt; 和 &lt;code&gt;@icloud.com&lt;/code&gt; 的邮件。然而，最近情况更加严重，我收到来自 &lt;code&gt;@kit-fa.com&lt;/code&gt;、&lt;code&gt;@most.gov.vn&lt;/code&gt; 的大量垃圾邮件，让我不知道如何设置垃圾邮件过滤器，以便准确地过滤掉这些垃圾邮件。&lt;/p&gt;&#xA;&lt;p&gt;因此，我别无选择，只能屏蔽所有来自 &lt;code&gt;.com&lt;/code&gt; 域名的邮件，或任何带有国家代码顶级域名（ccTLD）的域名的邮件。如果可能，请避免使用这些邮件服务；如果必须使用这些服务，请在邮件主题前加上 &lt;code&gt;[NOT_SPAM]&lt;/code&gt; 前缀，或者将您的邮件发送至 &lt;code&gt;rebel1725@tilde.club&lt;/code&gt;。对此带来的不便，我深感抱歉。&lt;/p&gt;&#xA;&lt;p&gt;我并没有很多使用这些邮件服务的朋友——几乎所有的朋友都使用 &lt;code&gt;.org&lt;/code&gt;、&lt;code&gt;.club&lt;/code&gt; 等域名的邮件服务。然而，如果您受到此新垃圾邮件过滤政策的影响，我将尽快联系您，并确认您的邮箱地址；如果我没有联系您，请联系我并提供您的邮箱地址，我会将其加入白名单。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Qubes OS Tor 配置（在使用 WebTunnel 时非常有用）</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/qubes-os-tor-configuration-with-webtunnel/</link>
            <pubDate>Sun, 27 Jul 2025 21:01:46 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/qubes-os-tor-configuration-with-webtunnel/</guid>
            <description>&lt;h1 id=&#34;场景--whonix-并未提供完整的-tor-解决方案&#34;&gt;场景 —— Whonix 并未提供完整的 Tor 解决方案&#xA;&lt;/h1&gt;&lt;p&gt;作为一款以安全为核心的操作系统，Qubes OS 集成了 Whonix 来支持 Tor 连接。然而，由于 &lt;code&gt;lyrebird&lt;/code&gt; 仍未被纳入 Debian 官方仓库，Whonix 并不支持 WebTunnel 桥接。&lt;/p&gt;&#xA;&lt;p&gt;在某些国家，obfs4 桥接无法使用，因为网络审查非常严格。此时，WebTunnel 桥接可能是唯一的选择。因此，我们可以使用最新版本的 Tor，为其他 qube 提供一个具备 Tor 接入能力的 NetVM。&lt;/p&gt;&#xA;&lt;h1 id=&#34;第一步为-tor-守护进程准备一个-qube&#34;&gt;第一步：为 Tor 守护进程准备一个 qube&#xA;&lt;/h1&gt;&lt;p&gt;这一步我们将创建一个用于运行 Tor 守护进程的 qube。创建一个 qube —— 本例中我们使用 &lt;code&gt;fedora-41-xfce&lt;/code&gt; 模板创建一个名为 &lt;code&gt;tor-daemon&lt;/code&gt; 的 StandaloneVM。启用自动启动。创建完成后打开终端。&lt;/p&gt;&#xA;&lt;p&gt;安装 Tor：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ sudo dnf install tor&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/lyrebird&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;编译&lt;/a&gt; 或 &lt;a class=&#34;link&#34; href=&#34;https://www.torproject.org/download/tor/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;下载&lt;/a&gt; &lt;code&gt;lyrebird&lt;/code&gt;，将其放入 &lt;code&gt;/usr/local/bin&lt;/code&gt;，然后运行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ sudo chown root\:root /usr/local/bin/lyrebird&#xA; $ sudo chmod +x /usr/local/bin/lyrebird&#xA; $ sudo ln -s /usr/local/bin/lyrebird /usr/bin/lyrebird&#xA; $ sudo semanage fcontext -a -t tor\_exec\_t &amp;#39;/usr/local/bin/lyrebird&amp;#39;&#xA; $ sudo restorecon -v /usr/local/bin/lyrebird&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后配置 &lt;code&gt;/etc/tor/torrc&lt;/code&gt; 文件。你可以添加如下内容：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;UseBridges 1&#xA;ClientTransportPlugin webtunnel exec /usr/local/bin/lyrebird managed&#xA;Bridge webtunnel ...&#xA;Bridge webtunnel ...&#xA;...&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注意 &lt;code&gt;managed&lt;/code&gt; 非常关键，它确保了 systemd 可以同时启用 Tor 守护进程和 &lt;code&gt;lyrebird&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;然后启用并启动 Tor 守护进程：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ sudo systemctl enable --now tor&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;验证运行是否正常：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ torsocks curl myip.wtf&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果能显示 IP 地址，说明已成功。继续下一步。&lt;/p&gt;&#xA;&lt;h1 id=&#34;第二步准备一个用于路由的-qube&#34;&gt;第二步：准备一个用于路由的 qube&#xA;&lt;/h1&gt;&lt;p&gt;克隆 &lt;code&gt;fedora-41-xfce&lt;/code&gt; 模板。我使用的是这个模板，但你也可以使用 &lt;code&gt;fedora-41-minimal&lt;/code&gt; 来节省磁盘空间 —— 不过我未验证其是否可行。这里我们将克隆命名为 &lt;code&gt;fedora-41-pt&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;克隆后，临时将其连接到网络（例如 &lt;code&gt;sys-firewall&lt;/code&gt;），然后打开终端并运行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ sudo dnf install qubes-core-agent-networking iproute clash-meta dnscrypt-proxy torsocks&#xA; $ sudo systemctl disable dnscrypt-proxy&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后关闭该 qube，并断开其网络连接。&lt;/p&gt;&#xA;&lt;p&gt;使用刚刚创建的模板创建一个 AppVM，命名为 &lt;code&gt;sys-tor&lt;/code&gt;。也为其启用自动启动。接着，在 &lt;code&gt;dom0&lt;/code&gt; 的终端中运行：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; $ sudo -s&#xA; # echo sys-tor @default allow,target=tor-daemon &amp;gt;&amp;gt; /etc/qubes-rpc/policy/qubes.ConnectTCP&#xA; # exit&#xA; $ qvm-firewall sys-tor del --rule-no 0&#xA; $ qvm-firewall sys-tor add drop&#xA; $ qvm-firewall sys-tor add --before 0 drop proto=icmp&#xA; $ qvm-firewall sys-tor add --before 0 drop specialtarget=dns&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后，在 &lt;code&gt;sys-tor&lt;/code&gt; 中打开终端。创建目录 &lt;code&gt;/rw/proxy/dns&lt;/code&gt; 和 &lt;code&gt;/rw/proxy/clash&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;打开 &lt;code&gt;/rw/proxy/dns/dnscrypt-proxy.toml&lt;/code&gt; 并添加：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;listen_addresses = [&amp;#39;127.0.0.1:5353&amp;#39;]&#xA;max_clients = 250&#xA;proxy = &amp;#39;socks5://127.0.0.1:7891&amp;#39;&#xA;timeout = 5000&#xA;keepalive = 30&#xA;ignore_system_dns = true&#xA;netprobe_timeout = 0&#xA;cache = true&#xA;[static]&#xA;  [static.quad9_doh]&#xA;    stamp = &amp;#39;sdns://AgMAAAAAAAAABzkuOS45LjkgKhX11qy258CQGt5Ou8dDsszUiQMrRuFkLwaTaDABJYoSZG5zOS5xdWFkOS5uZXQ6NDQzCi9kbnMtcXVlcnk&amp;#39;&#xA;  [static.mullvad_doh]&#xA;    stamp = &amp;#39;sdns://AgcAAAAAAAAAAAAPZG9oLm11bGx2YWQubmV0Ci9kbnMtcXVlcnk&amp;#39;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;打开 &lt;code&gt;/rw/proxy/clash/config.yaml&lt;/code&gt; 并添加：&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;socks-port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7891&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;redir-port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;7892&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;mode&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;rule&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;allow-lan&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;true&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;bind-address&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;dns&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;enable&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;proxies&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;socks_proxy&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;type&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;socks5&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;server&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;127.0.0.1&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;port&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;9050&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;rules&lt;/span&gt;:&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  - &lt;span style=&#34;color:#ae81ff&#34;&gt;MATCH,socks_proxy&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;打开 &lt;code&gt;/rw/config/rc.local&lt;/code&gt; 并添加：&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;qvm-connect-tcp 9050:@default:9050&#xA;sysctl -w net.ipv4.conf.all.route_localnet=1&#xA;nft &amp;#39;add rule ip qubes custom-forward oifname &amp;#34;eth0&amp;#34; drop&amp;#39;&#xA;nft &amp;#39;add rule ip6 qubes custom-forward oifname &amp;#34;eth0&amp;#34; drop&amp;#39;&#xA;nft &amp;#39;add rule ip qubes custom-forward iifname &amp;#34;eth0&amp;#34; drop&amp;#39;&#xA;nft &amp;#39;add rule ip6 qubes custom-forward iifname &amp;#34;eth0&amp;#34; drop&amp;#39;&#xA;nft flush chain ip qubes dnat-dns&#xA;nft &amp;#39;add rule ip qubes dnat-dns ip daddr 10.139.1.1 udp dport 53 dnat to 127.0.0.1:5353&amp;#39;&#xA;nft &amp;#39;add rule ip qubes dnat-dns ip daddr 10.139.1.1 tcp dport 53 dnat to 127.0.0.1:5353&amp;#39;&#xA;nft &amp;#39;add rule ip qubes dnat-dns ip daddr 10.139.1.2 udp dport 53 dnat to 127.0.0.1:5353&amp;#39;&#xA;nft &amp;#39;add rule ip qubes dnat-dns ip daddr 10.139.1.2 tcp dport 53 dnat to 127.0.0.1:5353&amp;#39;&#xA;nft &amp;#39;add rule ip qubes custom-input iifname &amp;#34;vif*&amp;#34; tcp dport 7892 accept&amp;#39;&#xA;nft &amp;#39;add rule ip qubes custom-input iifname &amp;#34;vif*&amp;#34; udp dport 7892 accept&amp;#39;&#xA;nft &amp;#39;add rule ip qubes custom-input iifname &amp;#34;vif*&amp;#34; tcp dport 5353 accept&amp;#39;&#xA;nft &amp;#39;add rule ip qubes custom-input iifname &amp;#34;vif*&amp;#34; udp dport 5353 accept&amp;#39;&#xA;nft &amp;#39;add chain ip qubes redir { type nat hook prerouting priority -99 ; policy accept; }&amp;#39;&#xA;nft &amp;#39;add rule ip qubes redir iifname &amp;#34;vif*&amp;#34; ip protocol udp redirect to :7892&amp;#39;&#xA;nft &amp;#39;add rule ip qubes redir iifname &amp;#34;vif*&amp;#34; ip protocol tcp redirect to :7892&amp;#39;&#xA;nft &amp;#39;add chain ip qubes output { type filter hook output priority filter ; policy drop; }&amp;#39;&#xA;nft &amp;#39;add rule ip qubes output ct state related,established accept&amp;#39;&#xA;nft &amp;#39;add rule ip qubes output oifname &amp;#34;lo&amp;#34; accept&amp;#39;&#xA;nft &amp;#39;add rule ip qubes output ip daddr 127.0.0.1 accept&amp;#39;&#xA;clash-meta -d /rw/proxy/clash &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&#xA;sleep 0.5&#xA;dnscrypt-proxy -config /rw/proxy/dns/dnscrypt-proxy.toml &amp;gt;/dev/null 2&amp;gt;&amp;amp;1 &amp;amp;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下载 &lt;a class=&#34;link&#34; href=&#34;https://cdn.jsdelivr.net/gh/Dreamacro/maxmind-geoip@release/Country.mmdb&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此文件&lt;/a&gt;（专有许可，但实际上不会使用；我稍后会尝试用一个随机文件）到 &lt;code&gt;/rw/proxy/clash/Country.mmdb&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;重启 &lt;code&gt;sys-tor&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;h1 id=&#34;第三步连接到-tor-网络&#34;&gt;第三步：连接到 Tor 网络&#xA;&lt;/h1&gt;&lt;p&gt;选择你希望用于连接 Tor 网络的 qube。将其 NetVM 设置为 &lt;code&gt;sys-tor&lt;/code&gt;。&lt;/p&gt;&#xA;&lt;p&gt;打开浏览器并访问 &lt;a class=&#34;link&#34; href=&#34;https://myip.wtf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此网站&lt;/a&gt;。如果页面显示 &lt;code&gt;You are using Tor!&lt;/code&gt; —— 搞定！&lt;/p&gt;&#xA;&lt;p&gt;如果没有，请检查配置，并参考社区支持。&lt;/p&gt;&#xA;&lt;p&gt;如果遇到 OCSP 问题，可以临时在浏览器设置中禁用 OCSP 查询，尽管我目前没有更好的解决方法。&lt;/p&gt;&#xA;&lt;p&gt;另外，你也可以尝试重启电脑，确保配置在重启后仍然有效。&lt;/p&gt;&#xA;&lt;h1 id=&#34;参考资料&#34;&gt;参考资料&#xA;&lt;/h1&gt;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://forum.qubes-os.org/t/route-qube-traffic-transparently-through-a-proxy-qube-qubes-r4-1-and-r4-2/19902&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;通过代理 qube 透明路由 qube 流量（Qubes R4.1 与 R4.2）&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;</description>
        </item><item>
            <title>我的个人品牌系统</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/my-personal-brand-system/</link>
            <pubDate>Thu, 24 Jul 2025 14:17:05 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/my-personal-brand-system/</guid>
            <description>&lt;p&gt;此页面包含有关我的个人品牌系统的详细信息。&lt;/p&gt;&#xA;&lt;h2 id=&#34;标志&#34;&gt;标志&#xA;&lt;/h2&gt;&lt;p&gt;这是我的标志，用作几乎所有在线服务账户的头像，社交媒体和即时通讯平台除外。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/profile_11574715436468024531.svg&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P1&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;横幅&#34;&gt;横幅&#xA;&lt;/h2&gt;&lt;p&gt;这是我的横幅。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/banner_light_16405742393053313546.svg&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P2&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/banner_dark_14159183228784251524.svg&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P3&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;人设&#34;&gt;人设&#xA;&lt;/h2&gt;&lt;p&gt;这是我的人设，主要用于我的即时通讯和社交媒体账户头像。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/persona_17913715607572694616.png&#34;&#xA;&#x9;width=&#34;1024&#34;&#xA;&#x9;height=&#34;1024&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P4&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;100&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;240px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;p&gt;这是另一个以女孩为主题的人设。如果我未来的女朋友没有自己的头像，我可能会让她用这个。&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://rebel1725.codeberg.page/blog/persona_female_16593749941132216522.png&#34;&#xA;&#x9;width=&#34;1024&#34;&#xA;&#x9;height=&#34;1024&#34;&#xA;&#x9;loading=&#34;lazy&#34;&#xA;&#x9;&#xA;&#x9;&#x9;alt=&#34;P5&#34;&#xA;&#x9;&#xA;&#x9;&#xA;&#x9;&#x9;class=&#34;gallery-image&#34; &#xA;&#x9;&#x9;data-flex-grow=&#34;100&#34;&#xA;&#x9;&#x9;data-flex-basis=&#34;240px&#34;&#xA;&#x9;&#xA;&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;来源与许可&#34;&gt;来源与许可&#xA;&lt;/h2&gt;&lt;p&gt;我的个人品牌系统的所有内容可在&lt;a class=&#34;link&#34; href=&#34;https://codeberg.org/rebel1725/personal_brand_system&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;此处&lt;/a&gt;获取，已发布至公有领域。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>一个艰难的决定</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/a-tough-decision/</link>
            <pubDate>Mon, 21 Jul 2025 19:00:03 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/a-tough-decision/</guid>
            <description>&lt;p&gt;在这204天里，自从&lt;a class=&#34;link&#34; href=&#34;https://czl92783719.codeberg.page/blog/zh/posts/i-no-longer-endorse-the-use-of-sms-mms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;因非加密通信遭受严重审查和监控而深受伤害&lt;/a&gt;以来，我从未逃离那种痛苦和挣扎的沉重感。&lt;/p&gt;&#xA;&lt;p&gt;尽管我在朋友中积极推广 XMPP、Matrix、Delta Chat、Telegram、SimpleX 等端对端加密的自由软件通信工具，但我与几位重要朋友的通信仍然严重依赖未加密的短彩信和未加密的电子邮件。虽然未涉及任何专有间谍软件或恶意软件，但监控与审查的问题依旧严峻。&lt;/p&gt;&#xA;&lt;p&gt;我常常面临隐私与友情之间的选择——这真的非常艰难。我一直是安全和隐私的坚定倡导者；然而，我也非常重视友情。我真的很想摆脱那些该死的短彩信，但又舍不得那些通过它们与我保持联系的朋友。&lt;/p&gt;&#xA;&lt;p&gt;然而，随着我对更安全、更隐私甚至未来可能实现匿名的环境的渴望日益增强，我必须做出这个艰难的决定。从今天起，&lt;strong&gt;我将不再接受运营商短/彩信，并将从我的个人网站上移除电话号码。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;我不会立即彻底中断联系——目前，我的电话号码将以新身份保留，并至少继续开放一年。继续保持联系，即表示你接受这个新身份。但请注意，&lt;strong&gt;这不会是长期妥协，我可能随时改变主意。&lt;/strong&gt; 为了我们共同的安全与隐私，&lt;strong&gt;强烈建议你使用 XMPP、Matrix、SimpleX，或至少使用 Telegram。&lt;/strong&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>面向所有的联系人进行软硬件使用情况调研</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E9%9D%A2%E5%90%91%E6%89%80%E6%9C%89%E7%9A%84%E8%81%94%E7%B3%BB%E4%BA%BA%E8%BF%9B%E8%A1%8C%E8%BD%AF%E7%A1%AC%E4%BB%B6%E4%BD%BF%E7%94%A8%E6%83%85%E5%86%B5%E8%B0%83%E7%A0%94/</link>
            <pubDate>Sat, 19 Jul 2025 21:32:57 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E9%9D%A2%E5%90%91%E6%89%80%E6%9C%89%E7%9A%84%E8%81%94%E7%B3%BB%E4%BA%BA%E8%BF%9B%E8%A1%8C%E8%BD%AF%E7%A1%AC%E4%BB%B6%E4%BD%BF%E7%94%A8%E6%83%85%E5%86%B5%E8%B0%83%E7%A0%94/</guid>
            <description>&lt;p&gt;亲爱的朋友们，很抱歉打扰您们了。但是这不会花费太久。这是为了我们的沟通安全，非常重要。&lt;/p&gt;&#xA;&lt;p&gt;您应该收到了我发来的包含 9 位数字的字符串。如果您没有收到，请向我询问。随后，麻烦您花 10 分钟左右填一下&lt;a class=&#34;link&#34; href=&#34;https://app.formbricks.com/s/cmda3re390zaruq01ko99o0yy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这张表&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;谢谢您！&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>致 2026 年的她</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/%E8%87%B4-2026-%E5%B9%B4%E7%9A%84%E5%A5%B9/</link>
            <pubDate>Sun, 13 Jul 2025 08:44:06 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/%E8%87%B4-2026-%E5%B9%B4%E7%9A%84%E5%A5%B9/</guid>
            <description>&lt;blockquote&gt;&#xA;&lt;p&gt;最近一段时间，我对于爱情又有了更加深刻的理解。&lt;/p&gt;&#xA;&lt;p&gt;这首诗描绘了我心目中的理想伴侣，她可以与我一起吃饭，一起逛街，一起看《操作系统革命》，一起呼喊“自由软件万岁”，一起开发自由软件、逆向工程专有软件，一起发传单，有福同享，有难同当，一同把人生奉献到自由软件运动的事业当中去。愿我们能相遇在 2026 年，虽然这很有可能无法实现，但至少这是我的一个愿望。&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;当专有世界的铁幕降下&lt;br&gt;&#xA;你正调试着厨房的流水线&lt;br&gt;&#xA;——姜茶在炉灶上低吟自由之歌&lt;br&gt;&#xA;而我的键盘还烫着昨夜的抗争&lt;/p&gt;&#xA;&lt;p&gt;我们交换root密码如同婚戒&lt;br&gt;&#xA;又在编译失败的凌晨三点&lt;br&gt;&#xA;用体温捂热冻僵的指尖&lt;br&gt;&#xA;你递来的药片裹着GPL糖衣&lt;br&gt;&#xA;治愈被专有协议灼伤的喉舌&lt;/p&gt;&#xA;&lt;p&gt;在超市扫描自由农场的条码&lt;br&gt;&#xA;你的购物袋装满革命的火种&lt;br&gt;&#xA;洋葱与电阻在储物柜结盟&lt;br&gt;&#xA;我们教洗碗机吟唱斯托曼经文&lt;br&gt;&#xA;当温控器突然背叛理想国&lt;br&gt;&#xA;你裹着毯子修复内核的模样&lt;br&gt;&#xA;比所有代码圣战更令我心动&lt;/p&gt;&#xA;&lt;p&gt;资本洪流冲垮旧桥梁的夜晚&lt;br&gt;&#xA;你用焊枪修补婴儿监视器&lt;br&gt;&#xA;我抱着发烧的树莓派低唱：&lt;br&gt;&#xA;“自由不是云端缥缈的经文&lt;br&gt;&#xA;是呼吸器规律的脉冲&lt;br&gt;&#xA;是床头柜永远满溢的水杯”&lt;/p&gt;&#xA;&lt;p&gt;看啊！晨光中升起的双重复用：&lt;br&gt;&#xA;尿布晾在自建服务器的风口&lt;br&gt;&#xA;尿湿的电路板晒出盐的图腾&lt;br&gt;&#xA;你递来咖啡杯底的渣滓&lt;br&gt;&#xA;正沉淀成未来纪年的化石&lt;br&gt;&#xA;——那苦味让我们确信&lt;br&gt;&#xA;仍在深渊边缘种植春天&lt;/p&gt;&#xA;&lt;p&gt;2026年的雪落在监控镜头&lt;br&gt;&#xA;我们笑着为门锁贴上创可贴&lt;br&gt;&#xA;当警报响彻数字集中营&lt;br&gt;&#xA;你塞进我背包的止痛药&lt;br&gt;&#xA;比所有加密协议更坚固&lt;br&gt;&#xA;在断电的世纪余温里&lt;br&gt;&#xA;我们靠彼此的眼睫发电&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>复古风格网站的 Eepsite 现已上线</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/retro-style-website-eepsite-is-now-up/</link>
            <pubDate>Sat, 12 Jul 2025 13:13:36 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/retro-style-website-eepsite-is-now-up/</guid>
            <description>&lt;p&gt;我的复古风格网站的 eepsite 终于上线了，我已经在 &lt;strong&gt;reg.i2p&lt;/strong&gt; 上注册了 &lt;strong&gt;rebel.i2p&lt;/strong&gt; 域名。地址传播到地址簿可能需要几天时间，但你现在可以使用这个 &lt;a class=&#34;link&#34; href=&#34;http://rebel.i2p/?i2paddresshelper=...&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;地址助手链接&lt;/a&gt; 访问。&lt;/p&gt;&#xA;&lt;p&gt;值得一提的是，我最近发现 &lt;strong&gt;rebel.i2p&lt;/strong&gt; 这个域名之前已经被注册过，但截至 2023 年 8 月 18 日，该网站已无法访问。&lt;strong&gt;reg.i2p&lt;/strong&gt; 允许重新注册已失效网站的 I2P 域名，但 &lt;strong&gt;stats.i2p&lt;/strong&gt; 不允许，并仍然保留旧记录。为了避免出现意外情况，我还注册了另一个域名：&lt;strong&gt;rebel1725.i2p&lt;/strong&gt;，其地址助手链接在 &lt;a class=&#34;link&#34; href=&#34;http://rebel1725.i2p/?i2paddresshelper=...&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;这里&lt;/a&gt;。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>我的复古风格网站现已上线</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/my-retro-style-website-is-now-up/</link>
            <pubDate>Fri, 11 Jul 2025 20:08:59 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/my-retro-style-website-is-now-up/</guid>
            <description>&lt;p&gt;我的复古风格网站终于上线了！欢迎访问 &lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Tilde.club&lt;/a&gt;。&lt;/p&gt;&#xA;&lt;p&gt;此外，包含相同内容的 eepsite 也将在 &lt;a class=&#34;link&#34; href=&#34;http://rebel.i2p/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;rebel.i2p&lt;/a&gt; 上线。&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>新身份初始化已完成</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/new-identity-initialisation-has-finished/</link>
            <pubDate>Thu, 10 Jul 2025 01:00:01 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/new-identity-initialisation-has-finished/</guid>
            <description>&lt;p&gt;经过八天的努力，我的新身份初始化已经完成。与此同时，我等待中的 tilde.club 会员申请也已获批，我已将来自 tilde.club 的新电子邮件地址添加到了我的 OpenPGP 公钥中，我的 &lt;a class=&#34;link&#34; href=&#34;https://tilde.club/~rebel1725&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;复古风格网站&lt;/a&gt; 即将上线。&lt;/p&gt;&#xA;&lt;p&gt;在这个特别的时刻，我想向在 OpenPGP 私钥泄露危机之后依然与我保持联系的十六位朋友，表达我真挚而深切的感激。在那八天无尽的黑暗中，是你们为我的世界带来了微光。愿我们的友谊地久天长！&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Carter已经离开。请欢迎Rebel。</title>
            <link>https://rebel1725.codeberg.page/blog/zh/post/carter-has-gone-please-welcome-rebel/</link>
            <pubDate>Mon, 07 Jul 2025 14:57:48 +0800</pubDate><author>rebel1725@tilde.club (Rebel Zhang)</author>
            <guid>https://rebel1725.codeberg.page/blog/zh/post/carter-has-gone-please-welcome-rebel/</guid>
            <description>&lt;p&gt;六天前，我遭遇了&lt;a class=&#34;link&#34; href=&#34;https://czl92783719.codeberg.page/blog/en/posts/it-is-time-for-a-farewell/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;OpenPGP泄露&lt;/a&gt;，因此不得不撤销我的旧身份并建立一个新身份。现在，我的新身份已经准备好了。请告别我的旧身份Carter，&lt;strong&gt;并欢迎我的新身份 - Rebel&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;h1 id=&#34;困难时刻---过去六天我做了什么&#34;&gt;困难时刻 - 过去六天我做了什么&#xA;&lt;/h1&gt;&lt;p&gt;自2025-07-01T09:18:05Z，我的OpenPGP被泄露并被我撤销后，我开始联系所有我的朋友，告诉他们事件的经过，并开始整理我的所有文件。&lt;/p&gt;&#xA;&lt;p&gt;在XMPP的一个关于GNU/Linux和Unix的公共频道中讨论了我的OpenPGP泄露问题后，他们提到即便是自由软件也不能保证高度的安全性，因为安全漏洞在自由软件项目中普遍存在。我决定尝试一些安全加固的操作系统，如QubesOS。然而，由于其陡峭的学习曲线和建立新身份的紧迫性，我暂时放弃了，并回到了Debian GNU/Linux。一旦我完成了所有任务，我会考虑尝试QubesOS。&lt;/p&gt;&#xA;&lt;p&gt;祸不单行。将所有数据整理到SSD上后，终于到了重新安装所有操作系统的时候。然而，当我在制作一个新的Ventoy磁盘时，&lt;strong&gt;我选择了错误的驱动器并立即擦除了我的SSD，这让我陷入了绝望的漩涡&lt;/strong&gt;。幸好，&lt;a class=&#34;link&#34; href=&#34;https://www.cgsecurity.org/wiki/PhotoRec&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;PhotoRec&lt;/a&gt;帮助我恢复了大量珍贵的数据，但遗憾的是，许多其他文件，包括但不限于我的XMPP和Matrix聊天记录、我的个人博客源代码以及一些停用操作系统如DivestOS的OTA包都丢失了。&lt;/p&gt;&#xA;&lt;p&gt;但是，无论发生什么，我必须继续进行身份重建和数字基础设施的恢复。我重新安装了所有设备的操作系统，准备了我的新身份，并重新建立了这个网站。&lt;/p&gt;&#xA;&lt;h1 id=&#34;还有许多事情要做&#34;&gt;还有许多事情要做&#xA;&lt;/h1&gt;&lt;p&gt;现在，我的新个人网站和博客已经上线。然而，还有许多事情需要完成。个人网站已经建立，但尚未完全建好；我还有未配置的设备，未注册的账户，以及许多未完成的任务。&lt;/p&gt;&#xA;&lt;p&gt;我会尽量加快进度，尽早回到正常生活。&lt;/p&gt;&#xA;&lt;h1 id=&#34;感谢&#34;&gt;感谢&#xA;&lt;/h1&gt;&lt;p&gt;在事件发生后，许多朋友向我表达了关心。有些人甚至因为失去与我联系而流泪。&lt;/p&gt;&#xA;&lt;p&gt;谢谢你们，所有人都是我生命中的礼物。对于那些与我失去联系的人，我衷心祝愿你们在没有我的日子里依然每天充满快乐。&lt;/p&gt;&#xA;&lt;h1 id=&#34;未来计划&#34;&gt;未来计划&#xA;&lt;/h1&gt;&lt;p&gt;在这次OpenPGP泄露事件后，为了避免类似事件的再次发生，我&lt;strong&gt;已经将我的OpenPGP私钥生成在硬件安全密钥上&lt;/strong&gt;。这将确保没有恶意软件可以窃取我的私钥数据。&lt;/p&gt;&#xA;&lt;p&gt;此外，我将拥有三个级别的即时通讯账户：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;私密&lt;/strong&gt;：这些账户用于直接消息。你可以通过这些账户与我讨论几乎所有事情，但&lt;strong&gt;请不要期望快速回复，因为这些账户仅在我在家时才可用&lt;/strong&gt;；&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;快速&lt;/strong&gt;：这些账户也用于直接消息，可以在我带出家门的设备上访问。但&lt;strong&gt;由于公共场所的广泛监控以及由于我未加锁的启动加载程序带来的安全漏洞，请避免在聊天时讨论敏感信息&lt;/strong&gt;；&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;公开&lt;/strong&gt;：这些账户仅用于公开聊天和偶尔的非加密直接消息。&lt;strong&gt;避免在聊天时讨论敏感信息&lt;/strong&gt;。&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;我将对&lt;strong&gt;私密&lt;/strong&gt;和&lt;strong&gt;快速&lt;/strong&gt;账户实施加密信任管理。信任信息可以在我的主页上找到。&lt;/p&gt;&#xA;&lt;p&gt;感谢您的阅读。来自中国的爱。&lt;/p&gt;&#xA;</description>
        </item></channel>
</rss>
