<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>技术 on cyp0633&#39;s Blog</title>
        <link>https://cyp0633.com/categories/tech/</link>
        <description>Recent content in 技术 on cyp0633&#39;s Blog</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <copyright>cyp0633</copyright><atom:link href="https://cyp0633.com/categories/tech/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>终端Agent是更趁手的通用Agent</title>
        <link>https://cyp0633.com/post/terminal-general-agent/</link>
        <pubDate>Mon, 02 Feb 2026 21:40:54 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/terminal-general-agent/</guid>
        <description>&lt;p&gt;体验了许多的AI工具，我觉得最趁手的还是OpenCode之类的终端agent。决定终端agent优势的因素，我分三个部分：基于本地、终端形态，以及human in the loop。&lt;/p&gt;
&lt;h2 id=&#34;为什么是本地agent&#34;&gt;为什么是本地agent？
&lt;/h2&gt;&lt;p&gt;当LLM能够通过工具调用和外界打配合的时候，就已经意味着它的能力已经超越了单纯的聊天解闷，或是解决一些逻辑问题。无论是调用Python增强自己的计算精度，还是调用网络搜索获取最新的结果，甚至调用生图工具另请高明生成一张图片，这项能力似乎在至少9个月前就已经在ChatGPT中落地了。然后就是轰轰烈烈的大agent时代，先是Cursor和Claude Code等coding agent使劲从 &lt;del&gt;程序员&lt;/del&gt; vibe coder钱包里榨钱，以及MCP赋予了自定义工具的能力，之后中间省略直到最近千问整合接入了阿里的各种产品，大模型的能力边界也确确实实地随着工具的丰富而不断地扩展。&lt;/p&gt;
&lt;p&gt;模型决定了agent分析问题的准确性、调用工具的技巧，工具（或者MCP/Skills）决定了agent可以做到的事情，而agent本身运行的平台，则决定了其在不额外添加工具的情况下能办到什么。回想我体验过agent，在第三个方面都有一些特征：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT普通模式，不清楚是怎么做的，不过可以调用Python，只能用一些已有的包。可以读取用户上传的文件，另有多种App（可能是类似skill的东西），可以连接云盘。&lt;/li&gt;
&lt;li&gt;ChatGPT agent模式，在OpenAI的服务器上起一个类似Debian的容器，天然沙盒化。在上述功能外支持了接近完整的Linux能力。&lt;/li&gt;
&lt;li&gt;千问App&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，全都做成了单独的模式，单独的deep research，单独的代码执行，而用阿里旗下的点外卖、找路线，嘿，又是一个单独的模式。&lt;/li&gt;
&lt;li&gt;Cursor/Copilot/Cline等AI IDE（插件），在IDE中运行，以代码为中心，改代码甚至写论文都非常方便。&lt;/li&gt;
&lt;li&gt;Codex和OpenCode等终端编码agent，通常依托终端界面，以及本地文件系统和程序工具。&lt;/li&gt;
&lt;li&gt;Claude for Desktop和Codex App，像是Claude Code套了个壳子，不过拥有更友好的GUI界面。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当agent在本地电脑上运行的时候，它更能够像人类一样使用电脑，而不是被局限在某个App或某个平台里。利用现有的环境也可以节省很多重复性的安装依赖等工作，并使用当前人类熟悉的配置文件。更重要的是，本地agent具有本地文件系统的优势，除了代码仓库，也可以十分方便地浏览工作资料等文件，甚至操纵本地运行的客户端程序。相反，在云端运行的agent仿佛带有一种隔阂，不依赖本地的状态则不像是在“为用户”处理工作。，&lt;/p&gt;
&lt;p&gt;的确，本地的文件太过繁杂，而现在仍然需要明确告诉agent哪里有文件，它才能自觉去引用、去综合、去整理，而不能自动地附带上下文。而我要说，基于云、连接网盘的方案有一样的问题，且难以推动云存储商实现便捷的文件查找接口（即使强如OneDrive搜索功能，也未必能给ChatGPT相似级别的权限）；而对于本地，大规模RAG是一个理论上可解且工程上可行的问题，但目前确实有一些文件检索路线上的争论。&lt;/p&gt;
&lt;p&gt;本地终端的另一个优势在于，通过利用本地的命令行工具链，它能够很好地遵守Unix哲学，通过shell管道和文件系统组合各种小工具，以达到极高的自由度。丰富的训练数据令LLM天生熟练使用shell，而无需花费额外context介绍工具调用或者MCP的spec。这是云端agent难以办到的，而即使是提供一个容器的ChatGPT agent模式，也更难包含所有任务需要的工具。&lt;/p&gt;
&lt;p&gt;至于chatbot提供的工具，Codex App和Claude App也能够添加其他MCP/工具，体验也已经基本是对齐的。&lt;/p&gt;
&lt;h2 id=&#34;为什么是终端&#34;&gt;为什么是终端？
&lt;/h2&gt;&lt;p&gt;我们暂且认为本地相对更有优势，好，那么为什么是终端，而不是IDE或者GUI的形式？有主观原因也有客观原因。&lt;/p&gt;
&lt;p&gt;其一是大多的AI IDE均基于VS Code，其性能虽然在IDE中算是较为优秀，但打开项目后仍然常有数百至数千MB的开销。这在编码任务中非常方便，因为能随时审查agent对代码的修改；但在常常涉及二进制文件的其他通用任务中，则显得相对累赘。正如朱亦博老师在Step 3.5 Flash博客中提到的，许多人并不会紧盯着执行过程中的过程，写了什么样的Python脚本，而是希望专注于运行结果，而结果很可能并不由代码呈现。&lt;/p&gt;
&lt;p&gt;倒不是说终端agent都多轻多快，当然OpenCode和Claude Code等工具由于实现问题，占用内存也很大，所以这里重的感觉也未必客观，或者更多的是一种跟手感。&lt;/p&gt;
&lt;p&gt;Claude for Desktop等桌面agent很好，有很强的computer use能力，在代替人解放繁杂工作这一方面，Anthropic算是起步比较早，整得也比较明白的。也有一个比较全面的marketplace，提供了接入各种第三方平台的工具。对于买了Claude订阅的普通人来说，它是一个比较理想的通用agent形态。&lt;/p&gt;
&lt;p&gt;大部分GUI形式agent也有自己的问题，就是在远程主机上用起来十分不方便。且不提三大系统唯独缺了一个Linux版本，不管是连接Windows本地的WSL，还是远程Linux服务器，都不能指定agent的实际运行环境。Windows上的PowerShell还是不要谈Unix哲学了，毕竟它连Unix都不是。相比于标准稀碎、网络要求高的远程桌面，SSH（或类SSH）作为既成标准，连接起来一般不会出什么差错，且由于传输的数据量不太大，在处理一些主要依赖远程机器的任务时，效率也更高。当然这并不是一个常见的需求，更多的还是我的个人喜好，如果Claude for Desktop糊一层客户端与服务端通信的协议，或许也会解决这个问题。&lt;/p&gt;
&lt;h2 id=&#34;为什么不是openclaw&#34;&gt;为什么不是OpenClaw？
&lt;/h2&gt;&lt;p&gt;OpenClaw很好，好在它打通了自主行动的链条，比被动的一问一答、等待指令更加灵活；但它坏就坏在过于灵活，对于人类完全是黑盒，几乎完全不可控也不受监管，也没有内置沙盒机制（当然用户应该有这样的自觉），甚至还有Moltbook这样的注入攻击温床。如果说使用Antigravity删除家目录这种事可以通过停止agent运行或者加入命令黑白名单来解决，那么对于并不会全程暴露执行过程的OpenClaw来说，则无异于蒙着眼睛凭感觉开车，一般来说能到达终点，而翻下悬崖也没什么意外。&lt;/p&gt;
&lt;p&gt;经过几年的发展，coding agent已经有了很多防止把代码库改炸掉的方案，比如建立多个worktree分别编辑，比如利用git的功能来暂存修改，比如使用bubblewrap把agent装进沙盒，等等等等。然而，显然OpenClaw一个都没做到，顶多也就是个MVP（2026年2月）。Docker并不能解决所有问题，agent的权限范围越大，其能力也就越强，辛辛苦苦写了一大串ACL，到头来总会遇到因权限而无法完成的任务。还不如使用声明式的方案，所有的更改以文件形式暂存，用户审核后再应用到系统中——文件而非命令的配置，某种程度上又是一种Unix哲学。或者甚至直接给整个硬盘打快照，起码给了用户救回来的机会。&lt;/p&gt;
&lt;p&gt;毫无疑问这种高度自主化的agent将会是未来的发展方向，但在它彻底融入日常生活，放心地把任务交给它之前，起码还是先加一些安全措施吧。起码现在，我宁愿盯着OpenCode的执行过程，并随时准备停止、接管或者完善任务。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;为什么老是提千问？只是因为我没用过豆包，元宝只用来抢红包。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Cumulus Linux 5.1 &amp; NVUE 使用笔记</title>
        <link>https://cyp0633.com/post/cumulus-nvue/</link>
        <pubDate>Wed, 12 Nov 2025 22:55:22 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/cumulus-nvue/</guid>
        <description>&lt;p&gt;&lt;del&gt;怎么前一段时间搞软路由，这次搞起大号硬路由了（并非）&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;Cumulus Linux是NVIDIA给交换机做的Linux系统，基于Debian。NVIDIA把交换机ASIC的配置抽象出来以Linux配置的方式呈现，实际用下来使用相对熟悉的逻辑还是更方便一些。&lt;/p&gt;
&lt;p&gt;虽然是基于Debian的，但NV似乎并没有完全承诺兼容，况且交换机上那颗双核X86 CPU恐怕连星露谷都带不起来，还是别整花活了。不同的Cumulus Linux版本自带的软件包也不同，操作逻辑等有着显著的差距。NV网站上有适用于各个版本的文档，当确定不下来的时候，与其找一个不知哪来的野文档 &lt;del&gt;（包括这篇）&lt;/del&gt; 或是版本号对不上，&lt;strong&gt;不妨问问ChatGPT，让它开联网搜一搜。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;从5.0版本开始，Cumulus Linux引入了NVUE（NVIDIA Unified Extensible）配置框架（也就是 &lt;code&gt;nv&lt;/code&gt; 命令这一套），用来取代NCLU（即 &lt;code&gt;net&lt;/code&gt; 命令）。在包括5.1在内的多个版本中，NCLU的后端也是NVUE，而在更新的一些版本中，则干脆没有了NCLU。无论如何什么时候，都应该尽量避免直接编辑 &lt;code&gt;/etc/network/interfaces&lt;/code&gt;，更不应该使用systemd-networkd、netplan或者NetworkManager之类的工具，尽量将NVUE作为single source of truth。&lt;/p&gt;
&lt;h2 id=&#34;用户管理&#34;&gt;用户管理
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-51/System-Configuration/Authentication-Authorization-and-Accounting/User-Accounts/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-51/System-Configuration/Authentication-Authorization-and-Accounting/User-Accounts/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;默认用户名是 &lt;code&gt;cumulus&lt;/code&gt;，但和其他许多Linux一样，可以通过 &lt;code&gt;adduser&lt;/code&gt; 工具添加用户，正常地设置密码，正常地配置SSH public key。&lt;/p&gt;
&lt;p&gt;与简单的判断sudoer不同，NVUE有着自己的更细粒度的用户组权限控制。三个不同等级的用户组分别为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nvshow&lt;/code&gt;，只能查看配置（如 &lt;code&gt;nv show config&lt;/code&gt;），不能修改&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvset&lt;/code&gt;，可以执行 &lt;code&gt;set&lt;/code&gt; 或 &lt;code&gt;unset&lt;/code&gt; 命令，但不能实际提交（即真正生效）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nvapply&lt;/code&gt;，不仅可以编辑staging的配置，还可以提交生效&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;声明式配置管理&#34;&gt;声明式配置管理
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/networking-ethernet-software/nvue-reference/Config-Commands/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.nvidia.com/networking-ethernet-software/nvue-reference/Config-Commands/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;NVUE进行系统配置的方法是声明式的。有些读者可能会立即想到Nix，事实上它们确实很相似：系统的状态由配置文件描述，更改系统的配置本质上就是更新配置文件，然后触发系统的重配置。的确，Linux系统的网络配置仍然由命令式的 &lt;code&gt;ifupdown&lt;/code&gt; 等工具处理，NVUE只是将配置文件抽象为NVUE的配置模型，然后替我们生成底层的配置文件，或是调用对应的命令。只需查看 &lt;code&gt;nvued.service&lt;/code&gt; 的日志就能发现这一点。&lt;/p&gt;
&lt;p&gt;声明式配置的一个好处是，可以用一个文件直接描述系统的配置状态。只需要 &lt;code&gt;nv config show&lt;/code&gt; 命令，就可以看到当前交换机的所有配置信息，就像这样：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;- set:
    bridge:
      domain:
        tor_bridge:
          type: vlan-aware
          stp:
            state:
              up: {}
          vlan:
            &amp;#39;102&amp;#39;: {}

    qos:
      roce:
        enable: on
        mode: lossless

    system:
      config:
        snippet:
          ifupdown2_eni:
            swp1: |
              post-up   ip neigh replace 10.0.255.2 lladdr 90:0a:84:xx:xx:xx dev swp1 nud permanent
              pre-down  ip neigh del     10.0.255.2 dev swp1

    vrf:
      tora:
        table: auto
        router:
          static:
            192.168.106.0/24:
              address-family: ipv4-unicast
              via:
                10.0.255.2:
                  type: ipv4-address

    interface:
      eth0:
        type: eth
        ip:
          address:
            10.0.25.1/16: {}

      swp1:
        type: swp
        ip:
          address:
            10.0.255.1/24: {}
          vrf: tora

      tor_bridge:
        type: bridge

      vlan102:
        base-interface: tor_bridge
        type: svi
        vlan: 102
        ip:
          address:
            192.168.102.1/24: {}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;59
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;bridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;domain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tor_bridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;vlan-aware&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;stp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;state&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;up&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;vlan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#39;102&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;qos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;roce&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;enable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;on&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;lossless&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;system&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;config&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ifupdown2_eni&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;swp1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;sd&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;              post-up   ip neigh replace 10.0.255.2 lladdr 90:0a:84:xx:xx:xx dev swp1 nud permanent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;sd&#34;&gt;              pre-down  ip neigh del     10.0.255.2 dev swp1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;              
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;vrf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tora&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;table&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;auto&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;router&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;static&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;192.168.106.0/24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address-family&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ipv4-unicast&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;              &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;via&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;10.0.255.2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;                  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;ipv4-address&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;eth0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;eth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;10.0.25.1/16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;swp1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;swp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;10.0.255.1/24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;vrf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tora&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;tor_bridge&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;bridge&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;vlan102&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;base-interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;tor_bridge&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;svi&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;vlan&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;102&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;192.168.102.1/24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这个片段展示了一个简单的交换机配置，包括VLAN、VRF、QoS以及接口配置等。可以看到，配置是以层次化的YAML格式呈现的，非常直观。值得注意的是里面有以命令形式存在的snippet，虽然的确是命令式配置，但也是NVUE不支持配置情况下的无奈之举（5.1.0还不支持固定neighbor）。&lt;/p&gt;
&lt;p&gt;用文件描述配置的另一个好处在于，版本控制非常方便。事实上NVUE也是这么做的：它真的用Git来管理历史，不信可以试试 &lt;code&gt;nv config history&lt;/code&gt; 命令，应用的配置相当于被commit了。同样还有来自Git的staging概念，熟悉Git的读者应该很容易上手这几个选项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nv config apply&lt;/code&gt;：将暂存中的配置生效&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nv config detach&lt;/code&gt;：放弃暂存的配置，从当前应用的配置开始做修改&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对暂存的配置作出修改，有三种方式：其一是直接使用 &lt;code&gt;nv set&lt;/code&gt; 和 &lt;code&gt;nv unset&lt;/code&gt; 命令，其二是用新的配置文件替换当前的配置，其三则是将新的配置文件合并到当前的配置中。第一种方式相对更接近先前的命令式配置习惯，至于后两种方式，则使用下面的例子来说明。&lt;/p&gt;
&lt;p&gt;假设当前 &lt;code&gt;nv show config&lt;/code&gt; 输出如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;- set:
    interface:
      eth0:
        type: eth
        ip:
          address:
            10.0.25.1/16: {}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;eth0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;eth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;10.0.25.1/16&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;有一个新的配置文件 &lt;code&gt;new.yaml&lt;/code&gt;，内容如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;- set:
      swp1:
        type: swp
        ip:
          address:
            10.0.255.1/24: {}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;- &lt;span class=&#34;nt&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;swp1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;swp&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;          &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;address&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;            &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;10.0.255.1/24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;{}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果使用 &lt;code&gt;nv config replace new.yaml&lt;/code&gt; 进行替换，那非常不巧，你的 &lt;code&gt;eth0&lt;/code&gt; 配置就丢了，下一步大概就是去找串口线改配置了。而如果使用 &lt;code&gt;nv config merge new.yaml&lt;/code&gt;，那就会把 &lt;code&gt;swp1&lt;/code&gt; 的配置加进去，&lt;code&gt;eth0&lt;/code&gt; 依然保留。&lt;/p&gt;
&lt;p&gt;当你终于下定决心，要试试新调整的配置会不会把交换机搞崩的时候，可以使用 &lt;code&gt;nv config apply&lt;/code&gt; 把配置提交生效。好消息是NVIDIA早就考虑到了配置错了SSH都连不上的问题，所以可以加一个 &lt;code&gt;--confirm&lt;/code&gt; 选项，在10分钟内没有手动确认的话，配置会自动回滚，即使刚刚误用了 &lt;code&gt;replace&lt;/code&gt;，也只是断10分钟而已。&lt;/p&gt;
&lt;h2 id=&#34;排除连接问题&#34;&gt;排除连接问题
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-51/Monitoring-and-Troubleshooting/Troubleshooting-Network-Interfaces/Troubleshoot-Layer-1/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://docs.nvidia.com/networking-ethernet-software/cumulus-linux-51/Monitoring-and-Troubleshooting/Troubleshooting-Network-Interfaces/Troubleshoot-Layer-1/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;有时候因为各种原因某个口死活up不起来，Cumulus Linux提供了一个方便的工具：&lt;code&gt;l1-show&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;cyp0633@cumulus:mgmt:~$ sudo l1-show 1-3
Port:  swp1
  Module Info
      Vendor Name: FINISAR CORP.          PN: FTLC1154RDNL-FH
      Identifier: 0x11 (QSFP28)           Type: 100g-lr4
  Configured State
      Admin: Admin Up     Speed: 100G     MTU: 9216
      Autoneg: Off                        FEC: Auto
  Operational State
      Link Status: Kernel: Up             Hardware: Up
      Speed: Kernel: 100G                 Hardware: 100G
      Autoneg: Off                        FEC: RS
      TX Power (mW): [1.8559, 1.839, 1.7584, 1.783]
      RX Power (mW): [0.878, 1.0508, 0.9174, 0.9853]
      Topo File Neighbor: None, None
      LLDP Neighbor:      cumulus, swp3
  Port Hardware State:
      Compliance Code: 100GBASE-LR4 or 25GBASE-LR
      Cable Type: Optical Module (separated)
      Speed: 100G                         Autodetect: FORCE - 100G
      Eyes: 385, 365, 419, 366            Grade: 31012, 21952, 31012, 25147
      Troubleshooting Info: No issue was observed.&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cyp0633@cumulus:mgmt:~$ sudo l1-show 1-3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Port:  swp1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Module Info
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Vendor Name: FINISAR CORP.          PN: FTLC1154RDNL-FH
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Identifier: 0x11 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;QSFP28&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;           Type: 100g-lr4
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Configured State
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Admin: Admin Up     Speed: 100G     MTU: &lt;span class=&#34;m&#34;&gt;9216&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Autoneg: Off                        FEC: Auto
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Operational State
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Link Status: Kernel: Up             Hardware: Up
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Speed: Kernel: 100G                 Hardware: 100G
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Autoneg: Off                        FEC: RS
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      TX Power &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;mW&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;1.8559, 1.839, 1.7584, 1.783&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      RX Power &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;mW&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;0.878, 1.0508, 0.9174, 0.9853&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Topo File Neighbor: None, None
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      LLDP Neighbor:      cumulus, swp3
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  Port Hardware State:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Compliance Code: 100GBASE-LR4 or 25GBASE-LR
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Cable Type: Optical Module &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;separated&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Speed: 100G                         Autodetect: FORCE - 100G
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Eyes: 385, 365, 419, &lt;span class=&#34;m&#34;&gt;366&lt;/span&gt;            Grade: 31012, 21952, 31012, &lt;span class=&#34;m&#34;&gt;25147&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      Troubleshooting Info: No issue was observed.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;当某个接口起不来的时候，不妨直接看 &lt;code&gt;l1-show&lt;/code&gt; 的输出，在Troubleshooting Info一栏中，基本上有什么问题一目了然。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>屏蔽了一些爬虫</title>
        <link>https://cyp0633.com/post/block-scrapers/</link>
        <pubDate>Sun, 07 Sep 2025 10:57:46 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/block-scrapers/</guid>
        <description>&lt;p&gt;本来读了研也确实没有本科那么强的折腾精神了，服务器除了续费和升级软件也没怎么动过。按理说这么小的网站Googlebot都基本不访问才对，但偶然检查一下还是发现了一些异样。以下分享三则最近发现的乱爬案例。&lt;/p&gt;
&lt;h2 id=&#34;阿里云阴兵过境&#34;&gt;阿里云阴兵过境
&lt;/h2&gt;&lt;p&gt;第一关是不明新加坡阿里云爬虫。&lt;/p&gt;
&lt;p&gt;位于香港的服务器上一直运行着一个Gitea做自己GitHub的镜像，由于某些原因没有挂Cloudflare，我那点垃圾代码按理说也没人看吧。诶恰恰相反，其实早在很久之前就有相当数量的爬虫在爬，只是比较节制，不会爬个没完。直到前段时间登上腾讯云，发现一个月竟然差不多用完了1TB的流量，并非互联网上一个偏远角落的正常访问量。以7天为尺度观察统计图表，好家伙直接把我CPU全跑满了呀。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;block-scrapers/server-resource-stats.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;腾讯云的统计&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;腾讯云的统计&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;不过话说回来幸亏是CPU-bound的Gitea，CPU打满了，30M的带宽还没打满，不然下场估计是先被腾讯断网，现在跑得慢但起码还能访问。导出Gitea的日志一看（共49万行），大部分是我本科边抄边写的操作系统实验，算是别人的代码，不是垃圾代码：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;log&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/rss/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/sign.c for 47.79.214.90:0, 404 Not Found in 0.2ms @ &amp;lt;autogenerated&amp;gt;:1(WebNotFound)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/kernel.ld for 47.79.199.163:0, 200 OK in 365.3ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/printfmt.c for 47.79.215.248:0, 200 OK in 518.0ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab1_result/tools/lab1init for 47.79.197.254:0, 200 OK in 481.5ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/rss/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/stdarg.h for 47.79.193.156:0, 404 Not Found in 0.5ms @ &amp;lt;autogenerated&amp;gt;:1(WebNotFound)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes/lab7/tools for 47.79.213.176:0, 200 OK in 223.1ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/string.h for 47.79.199.252:0, 200 OK in 568.3ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/raw/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/error.h for 47.79.215.8:0, 200 OK in 201.5ms @ repo/download.go:111(repo.SingleDownload)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes_answer/lab2_result/kern/debug for 47.79.204.14:0, 200 OK in 351.2ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/kern/libs/readline.c for 47.79.213.33:0, 200 OK in 519.4ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/raw/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/kernel.ld for 47.79.194.9:0, 200 OK in 121.7ms @ repo/download.go:111(repo.SingleDownload)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/stdlib.h for 47.79.192.216:0, 200 OK in 272.8ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/dirent.h for 47.79.205.12:0, 200 OK in 283.5ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs for 47.79.212.251:0, 200 OK in 163.6ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/blame/commit/d41b9e7f4fce933f5ce58c9c42e2f0bd5c7f6fc4/labcodes/lab7/Makefile for 47.79.213.33:0, 200 OK in 521.9ms @ repo/blame.go:42(repo.RefBlame)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes/lab7/tools/kernel.ld for 47.79.194.123:0, 200 OK in 392.8ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools for 47.79.192.112:0, 200 OK in 138.9ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/sign.c for 47.79.205.59:0, 200 OK in 105.0ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/defs.h for 47.79.192.12:0, 200 OK in 154.0ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/x86.h for 47.79.192.12:0, 200 OK in 345.3ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/blame/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/defs.h for 47.79.198.73:0, 200 OK in 164.4ms @ repo/blame.go:42(repo.RefBlame)&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/rss/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/sign.c for 47.79.214.90:0, 404 Not Found in 0.2ms @ &amp;lt;autogenerated&amp;gt;:1(WebNotFound)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/kernel.ld for 47.79.199.163:0, 200 OK in 365.3ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/printfmt.c for 47.79.215.248:0, 200 OK in 518.0ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab1_result/tools/lab1init for 47.79.197.254:0, 200 OK in 481.5ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/rss/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/stdarg.h for 47.79.193.156:0, 404 Not Found in 0.5ms @ &amp;lt;autogenerated&amp;gt;:1(WebNotFound)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes/lab7/tools for 47.79.213.176:0, 200 OK in 223.1ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/string.h for 47.79.199.252:0, 200 OK in 568.3ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/raw/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/error.h for 47.79.215.8:0, 200 OK in 201.5ms @ repo/download.go:111(repo.SingleDownload)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes_answer/lab2_result/kern/debug for 47.79.204.14:0, 200 OK in 351.2ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/kern/libs/readline.c for 47.79.213.33:0, 200 OK in 519.4ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/raw/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/kernel.ld for 47.79.194.9:0, 200 OK in 121.7ms @ repo/download.go:111(repo.SingleDownload)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/stdlib.h for 47.79.192.216:0, 200 OK in 272.8ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/dirent.h for 47.79.205.12:0, 200 OK in 283.5ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs for 47.79.212.251:0, 200 OK in 163.6ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/blame/commit/d41b9e7f4fce933f5ce58c9c42e2f0bd5c7f6fc4/labcodes/lab7/Makefile for 47.79.213.33:0, 200 OK in 521.9ms @ repo/blame.go:42(repo.RefBlame)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/0a7d3faa0b7804e45252a70e583ede3459b16949/labcodes/lab7/tools/kernel.ld for 47.79.194.123:0, 200 OK in 392.8ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools for 47.79.192.112:0, 200 OK in 138.9ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/commits/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab3_result/tools/sign.c for 47.79.205.59:0, 200 OK in 105.0ms @ repo/commit.go:44(repo.RefCommits)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/defs.h for 47.79.192.12:0, 200 OK in 154.0ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/src/commit/a29ae0982ac021cc2abeb75004af69b1b0d29f53/labcodes_answer/lab8_result/libs/x86.h for 47.79.192.12:0, 200 OK in 345.3ms @ repo/view_home.go:332(repo.Home)
Aug 05 08:57:04 VM-8-17-ubuntu gitea[4160705]: 2025/08/05 08:57:04 ...eb/routing/logger.go:102:func1() [I] router: completed GET /cyp0633/ucore-lab/blame/commit/5204cd45e8a0f09f7a27ddad803bf28d56474dba/labcodes_answer/lab2_result/libs/defs.h for 47.79.198.73:0, 200 OK in 164.4ms @ repo/blame.go:42(repo.RefBlame)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;vibe了一个分析脚本，发现28分钟的记录时间内处理了 &lt;strong&gt;56182&lt;/strong&gt; 个请求，平均每分钟高达2000多个；请求来自于750个不同的IP，全都来自于47.79.0.0/16这个阿里云新加坡的IP段，这样分摊到每个IP上，半个小时不到200次请求，看起来非常的人畜无害。这使得手写IP封禁或者速率限制变得不切实际。为了保险起见，该日先把Gitea关掉了。&lt;/p&gt;
&lt;p&gt;为了进一步确认这些IP的身份，将Gitea暂时关闭数天后，还导出了Caddy的日志。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;log&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2537313,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.201.138&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;56801&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.201.138&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/b66679d36acc0443078dafdfc5452880f376e015/layouts/partials/footer/script.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000190728,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;00uu9mrsp&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.260209,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;39054&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/opengraph/include.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000227457,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;aa84vne2s&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2617188,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.206.1&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;30313&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.206.1&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000177793,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;7jqfa7yiq&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2736785,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.198.78&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;25315&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.198.78&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/compact.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000182872,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;89gyde5bz&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2741818,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.201&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12618&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.201&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000194264,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;mzpuq5vau&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2894285,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.195.97&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;5843&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.195.97&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/tile.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.00023476,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;v3azrf597&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2902029,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.193.3&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;51386&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.193.3&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/image.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000307345,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;6gv9knvpm&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2950988,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.193.80&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;24245&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.193.80&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/c6661196ad92dfa72513582c40f75a6a5f514851/layouts/partials?page=1&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000194966,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;ju8k688tg&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3023942,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.205.248&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12381&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.205.248&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/sidebar/right.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000187251,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;4m19ms28b&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3110833,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;57044&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/compact.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000179277,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;hk01fb751&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.31186,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.205.70&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;51797&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.205.70&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/icon.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.00037888,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;7dz5tnw6r&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3274698,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.118&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;13643&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.118&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/data/description.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000217268,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;ht5drxez1&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3605616,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.215&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;44762&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.215&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/opengraph/provider&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000191609,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;fhuzf2976&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3730135,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.163&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;20753&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.163&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/data/description.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000226774,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;kprf6bcji&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4402184,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.195.231&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;49027&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.195.231&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/style.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000254457,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;yp9xbpai2&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4595432,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.216&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;3491&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.216&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/icon.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000294471,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;txnhq2xhy&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4613986,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.119&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;54239&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.119&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000191127,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;a7uvn7yxk&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2537313,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.201.138&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;56801&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.201.138&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/b66679d36acc0443078dafdfc5452880f376e015/layouts/partials/footer/script.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000190728,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;00uu9mrsp&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.260209,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;39054&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/opengraph/include.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000227457,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;aa84vne2s&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2617188,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.206.1&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;30313&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.206.1&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000177793,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;7jqfa7yiq&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2736785,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.198.78&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;25315&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.198.78&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/compact.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000182872,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;89gyde5bz&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2741818,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.201&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12618&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.201&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000194264,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;mzpuq5vau&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2894285,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.195.97&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;5843&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.195.97&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/tile.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.00023476,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;v3azrf597&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2902029,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.193.3&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;51386&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.193.3&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/image.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000307345,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;6gv9knvpm&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.2950988,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.193.80&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;24245&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.193.80&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/c6661196ad92dfa72513582c40f75a6a5f514851/layouts/partials?page=1&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000194966,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;ju8k688tg&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3023942,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.205.248&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12381&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.205.248&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/sidebar/right.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000187251,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;4m19ms28b&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3110833,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;57044&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.212.84&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/commits/commit/2fd3bde9a40790bf98893b0c5062a2f4c0ac9d8f/layouts/partials/article-list/compact.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000179277,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;hk01fb751&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.31186,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.205.70&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;51797&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.205.70&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/icon.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.00037888,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;7dz5tnw6r&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3274698,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.118&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;13643&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.118&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/data/description.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000217268,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;ht5drxez1&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3605616,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.215&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;44762&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.215&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/opengraph/provider&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000191609,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;fhuzf2976&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.3730135,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.215.163&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;20753&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.215.163&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/0af9d23e4989ed7ada10e6990802ccd9a28d8797/layouts/partials/data/description.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000226774,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;kprf6bcji&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4402184,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.195.231&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;49027&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.195.231&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/25581cc44637909a75aacdf33f896192f0569689/layouts/partials/head/style.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000254457,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;yp9xbpai2&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4595432,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.216&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;3491&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.216&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/d04b3a8771386c9988be00adda53f0bf542cf269/layouts/partials/helper/icon.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000294471,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;txnhq2xhy&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}
Aug 19 21:00:32 VM-8-17-ubuntu caddy[5430]: {&amp;#34;level&amp;#34;:&amp;#34;error&amp;#34;,&amp;#34;ts&amp;#34;:1755608432.4613986,&amp;#34;logger&amp;#34;:&amp;#34;http.log.error&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;dial tcp :3001: connect: connection refused&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;47.79.200.119&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;54239&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;47.79.200.119&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/1.1&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/25a72940b8184b41de36fec9a3fcdd6387e006b0/layouts/partials/sidebar/left.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Sec-Ch-Ua-Mobile&amp;#34;:[&amp;#34;?0&amp;#34;],&amp;#34;Priority&amp;#34;:[&amp;#34;u=0, i&amp;#34;],&amp;#34;Upgrade-Insecure-Requests&amp;#34;:[&amp;#34;1&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Connection&amp;#34;:[&amp;#34;keep-alive&amp;#34;],&amp;#34;Pragma&amp;#34;:[&amp;#34;no-cache&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en,en-US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/91.0.4472.124&amp;#34;],&amp;#34;Sec-Ch-Ua&amp;#34;:[&amp;#34;\&amp;#34;Google Chrome\&amp;#34;;v=\&amp;#34;135\&amp;#34;, \&amp;#34;Not-A.Brand\&amp;#34;;v=\&amp;#34;8\&amp;#34;, \&amp;#34;Chromium\&amp;#34;;v=\&amp;#34;135\&amp;#34;&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, deflate&amp;#34;],&amp;#34;Sec-Ch-Ua-Platform&amp;#34;:[&amp;#34;\&amp;#34;macOS\&amp;#34;&amp;#34;],&amp;#34;Sec-Fetch-Dest&amp;#34;:[&amp;#34;document&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;*/*&amp;#34;],&amp;#34;Sec-Fetch-Mode&amp;#34;:[&amp;#34;navigate&amp;#34;],&amp;#34;Sec-Fetch-Site&amp;#34;:[&amp;#34;none&amp;#34;],&amp;#34;Sec-Fetch-User&amp;#34;:[&amp;#34;?1&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;http/1.1&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;duration&amp;#34;:0.000191127,&amp;#34;status&amp;#34;:502,&amp;#34;err_id&amp;#34;:&amp;#34;a7uvn7yxk&amp;#34;,&amp;#34;err_trace&amp;#34;:&amp;#34;reverseproxy.statusError (reverseproxy.go:1373)&amp;#34;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;没想到即使遭遇了数天的HTTP 502，这些IP还是不死心，在坚持不懈地进行访问。一模一样的IP段，一模一样的访问模式，一模一样的假User-Agent。在意识到还是不如套个Cloudflare来得方便后，我便打开了代理开关，把这些IP全都上报到了AbuseIPDB。这个阿里云用户似乎没有完全罢休，在切换到Cloudflare后仍然锲而不舍地爬了好一会，造成了Cloudflare访问统计上的一座高峰；之后还使用阿里云香港，隶属于AS45102的IP继续尝试访问，不过都被Cloudflare挡下来了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;block-scrapers/cloudflare-traffic.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Cloudflare 访问统计&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Cloudflare 访问统计&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;刷爆对象存储但是细水长流&#34;&gt;刷爆对象存储，但是细水长流
&lt;/h2&gt;&lt;p&gt;前段时间阿里云给我发了条短信：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【阿里云】尊敬的cyp*33，截至2025-08-21 18:02:57，您的剩余可用额度为1.24元。根据您以往消费情况预测，剩余可用额度可能不足以支撑您未来7天的消费，为了避免欠费导致产品停止服务，请您及时充值。您可以登录阿里云官网查询账户可用额度信息和延停权益。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;当时没太在意，以为是正常的余额消耗，因为虽然OSS一个月花不了几毛钱，但阿里云上还有大模型推理，可能最近用模型太多了。然而过了四天，就用掉了0.71元，消耗速度有些异常：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;【阿里云】尊敬的cyp*33，截至2025-08-25 15:02:10，您的剩余可用额度为0.53元。根据您以往消费情况预测，剩余可用额度可能不足以支撑您未来3天的消费。为了避免欠费导致产品停止服务，请您及时充值。您可以登录阿里云官网查询账户可用额度信息和延停权益。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;进阿里云一看，才发现是OSS在花钱。为了节省Netlify的空间，提高国内的访问速度，Netlify上仅有博客的核心静态资源，而图片等大文件托管在内地的一个公共读阿里云OSS上。虽然开启了Referer白名单防盗链，但鉴于Referer投可以伪造，所以还是不保险。相比于之前的消耗速度，一天两毛钱已经算是警告了：如果再不处理，恐怕真的要欠费了。&lt;/p&gt;
&lt;p&gt;依旧导出了一些OSS的日志：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;csv&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;__source__,__time__,__topic__,acc_access_region,access_id,archive_direct_read_size,bucket,bucket_location,bucket_storage_type,cdn_in,cdn_out,client_ip,content_length_in,content_length_out,delta_data_size,ec,end_time,error_code,extend_information,get_request,host,http_method,http_status,http_type,intranet_in,intranet_out,logging_flag,metering_datasize,metering_datasize_ca,metering_datasize_zrs,metering_datasize_zrsii,network_in,network_out,object,object_size,operation,owner_id,process_img,process_img_size,put_request,referer,region,request_id,request_length,request_uri,requester_id,response_body_length,response_time,restore_priority,server_cost_time,sign_type,start_time,storage,storage_type,sync_in,sync_out,sync_request,target_storage_class,time,user_agent,user_defined_log_fields,vpc_addr,vpc_id
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,185189,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,need-for-speed-unbound%2FNeed%20for%20Speed%E2%84%A2%20Unbound%202023-01-22%2010-57-14.mp4_20230122_151607.850.avif,185189,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979E8569830337BD3AC,750,/need-for-speed-unbound/Need%20for%20Speed%E2%84%A2%20Unbound%202023-01-22%2010-57-14.mp4_20230122_151607.850.avif HTTP/1.1,-,185189,24,-,22,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,76636,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,nuc-homelab%2Fdiskperf.avif,76636,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E97978A51C363838F585,662,/nuc-homelab/diskperf.avif HTTP/1.1,-,76636,41,-,41,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,233860,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,vscode-latex%2Fvscode-with-extension.avif,233860,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E97978A51C35354AF585,676,/vscode-latex/vscode-with-extension.avif HTTP/1.1,-,233860,33,-,31,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,144022,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-bugs%2Fwin11bug21.avif,144022,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9794A68943931DED990,668,/windows-11-bugs/win11bug21.avif HTTP/1.1,-,144022,31,-,30,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,158049,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,wild-chicken-university%2Ftianyancha.avif,158049,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798F796838331F52B9,676,/wild-chicken-university/tianyancha.avif HTTP/1.1,-,158049,30,-,27,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,28216,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,vmware-ubuntu-12.04%2Faccount.avif,28216,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9792E174C34349AADA1,669,/vmware-ubuntu-12.04/account.avif HTTP/1.1,-,28216,33,-,32,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,55299,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Fstart-menu.avif,55299,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979AF9A9630396238AC,676,/windows-11-21996-leaked/start-menu.avif HTTP/1.1,-,55299,27,-,26,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,14143,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Foobe4.avif,14143,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979AF9A9635306338AC,671,/windows-11-21996-leaked/oobe4.avif HTTP/1.1,-,14143,33,-,32,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,20354,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Fwindows-10-calendar.avif,20354,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798D51EC3531998676,685,/windows-11-21996-leaked/windows-10-calendar.avif HTTP/1.1,-,20354,34,-,34,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,32798,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Foobe5.avif,32798,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798D51EC3230A48676,671,/windows-11-21996-leaked/oobe5.avif HTTP/1.1,-,32798,32,-,30,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,61159,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-bugs%2Fwin11bug5.avif,61159,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C759F63035B22080,667,/windows-11-bugs/win11bug5.avif HTTP/1.1,-,61159,23,-,18,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,199772,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,nuc-homelab%2Fsiyuan.avif,199772,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C70CA13536A34EB1,660,/nuc-homelab/siyuan.avif HTTP/1.1,-,199772,45,-,44,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,41757,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,csapp-bufferlab%2Fstackframe.avif,41757,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C70CA13931A94EB1,668,/csapp-bufferlab/stackframe.avif HTTP/1.1,-,41757,67,-,66,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;__source__,__time__,__topic__,acc_access_region,access_id,archive_direct_read_size,bucket,bucket_location,bucket_storage_type,cdn_in,cdn_out,client_ip,content_length_in,content_length_out,delta_data_size,ec,end_time,error_code,extend_information,get_request,host,http_method,http_status,http_type,intranet_in,intranet_out,logging_flag,metering_datasize,metering_datasize_ca,metering_datasize_zrs,metering_datasize_zrsii,network_in,network_out,object,object_size,operation,owner_id,process_img,process_img_size,put_request,referer,region,request_id,request_length,request_uri,requester_id,response_body_length,response_time,restore_priority,server_cost_time,sign_type,start_time,storage,storage_type,sync_in,sync_out,sync_request,target_storage_class,time,user_agent,user_defined_log_fields,vpc_addr,vpc_id
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,185189,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,need-for-speed-unbound%2FNeed%20for%20Speed%E2%84%A2%20Unbound%202023-01-22%2010-57-14.mp4_20230122_151607.850.avif,185189,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979E8569830337BD3AC,750,/need-for-speed-unbound/Need%20for%20Speed%E2%84%A2%20Unbound%202023-01-22%2010-57-14.mp4_20230122_151607.850.avif HTTP/1.1,-,185189,24,-,22,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,76636,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,nuc-homelab%2Fdiskperf.avif,76636,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E97978A51C363838F585,662,/nuc-homelab/diskperf.avif HTTP/1.1,-,76636,41,-,41,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,233860,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,vscode-latex%2Fvscode-with-extension.avif,233860,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E97978A51C35354AF585,676,/vscode-latex/vscode-with-extension.avif HTTP/1.1,-,233860,33,-,31,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,144022,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-bugs%2Fwin11bug21.avif,144022,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9794A68943931DED990,668,/windows-11-bugs/win11bug21.avif HTTP/1.1,-,144022,31,-,30,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,158049,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,wild-chicken-university%2Ftianyancha.avif,158049,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798F796838331F52B9,676,/wild-chicken-university/tianyancha.avif HTTP/1.1,-,158049,30,-,27,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,28216,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,vmware-ubuntu-12.04%2Faccount.avif,28216,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9792E174C34349AADA1,669,/vmware-ubuntu-12.04/account.avif HTTP/1.1,-,28216,33,-,32,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,55299,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Fstart-menu.avif,55299,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979AF9A9630396238AC,676,/windows-11-21996-leaked/start-menu.avif HTTP/1.1,-,55299,27,-,26,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,14143,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Foobe4.avif,14143,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979AF9A9635306338AC,671,/windows-11-21996-leaked/oobe4.avif HTTP/1.1,-,14143,33,-,32,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,20354,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Fwindows-10-calendar.avif,20354,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798D51EC3531998676,685,/windows-11-21996-leaked/windows-10-calendar.avif HTTP/1.1,-,20354,34,-,34,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,32798,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-21996-leaked%2Foobe5.avif,32798,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E9798D51EC3230A48676,671,/windows-11-21996-leaked/oobe5.avif HTTP/1.1,-,32798,32,-,30,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,61159,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,windows-11-bugs%2Fwin11bug5.avif,61159,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C759F63035B22080,667,/windows-11-bugs/win11bug5.avif HTTP/1.1,-,61159,23,-,18,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,199772,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,nuc-homelab%2Fsiyuan.avif,199772,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C70CA13536A34EB1,660,/nuc-homelab/siyuan.avif HTTP/1.1,-,199772,45,-,44,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0
log_dispatch,1756752249,oss_access_log,-,-,-,cyp0633-blogasset,oss-cn-qingdao-h,standard,,,46.62.169.27,-,41757,-,-,,-,-,,cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,GET,200,https,,,true,,,,,,,csapp-bufferlab%2Fstackframe.avif,41757,GetObject,1385315732671155,,,,https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com,,68B5E979C70CA13931A94EB1,668,/csapp-bufferlab/stackframe.avif HTTP/1.1,-,41757,67,-,66,NotSign,,,,,,-,-,02/Sep/2025:02:44:09,&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36&amp;#34;,-,172563320,0&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在开启日志后5天的时间里，OSS总共有10217次访问，而其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有一个IP 46.62.169.27猜出了我的Referer白名单，访问了 &lt;strong&gt;5571&lt;/strong&gt; 次，其中最多的一个小时访问了376次；&lt;/li&gt;
&lt;li&gt;有至少7个GCP的IP带着Thumbor的User-Agent和空Referer访问了1451次，鉴于我并不用这个软件，应该是被盗图了；&lt;/li&gt;
&lt;li&gt;还有一些其他的可疑访问，但数量较少。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了防止进一步当冤大头，我再次开始了vibe。ChatGPT给我提供了一个方案：利用Netlify Functions给图片签名，一次访问签整个页面的图片，然后用户使用带签名的URL访问OSS。OSS可以设为私有读，从而防止被猜出OSS白名单；签名TTL可以设置得很小，以防止损失过大。以下是基于Hugo完整的代码，虽然全是vibe的，但证明有效。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;netlify/functions/sign-oss.js&lt;/strong&gt;，在Netlify服务器上运行，用于访问阿里服务器进行签名（同时要安装 &lt;code&gt;ali-oss&lt;/code&gt; NPM包）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;javascript&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;&amp;#39;use strict&amp;#39;;

const OSS = require(&amp;#39;ali-oss&amp;#39;);

// Allow all by default for a dedicated bucket; override via OSS_ALLOWED_PREFIXES
const RAW_PREFIXES = process.env.OSS_ALLOWED_PREFIXES;
const ALLOWED_PREFIXES = (RAW_PREFIXES &amp;amp;&amp;amp; RAW_PREFIXES.trim().length &amp;gt; 0 ? RAW_PREFIXES : &amp;#39;*&amp;#39;)
 .split(&amp;#39;,&amp;#39;).map(s =&amp;gt; s.trim()).filter(Boolean);

function isAllowedKey(key) {
 if (!/^[\w\-./]&amp;#43;$/.test(key)) return false;
 if (ALLOWED_PREFIXES.includes(&amp;#39;*&amp;#39;)) return true;
 return ALLOWED_PREFIXES.some(p =&amp;gt; key.startsWith(p));
}

function parseAllowedOrigins() {
 return (process.env.ALLOWED_ORIGINS || &amp;#39;&amp;#39;)
  .split(&amp;#39;,&amp;#39;)
  .map(s =&amp;gt; s.trim())
  .filter(Boolean);
}

const client = new OSS({
 region: process.env.OSS_REGION,
 accessKeyId: process.env.OSS_ACCESS_KEY_ID,
 accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
 bucket: process.env.OSS_BUCKET
});

exports.handler = async (event) =&amp;gt; {
 try {
  const method = (event.httpMethod || &amp;#39;GET&amp;#39;).toUpperCase();
  const headers = event.headers || {};
  const origin = headers.origin || headers.Origin || &amp;#39;&amp;#39;;
  const allowedOrigins = parseAllowedOrigins();
  const acao = allowedOrigins.length ? (allowedOrigins.includes(origin) ? origin : &amp;#39;*&amp;#39;) : &amp;#39;*&amp;#39;;

  if (method === &amp;#39;OPTIONS&amp;#39;) {
   return {
    statusCode: 204,
    headers: {
     &amp;#39;access-control-allow-origin&amp;#39;: acao,
     &amp;#39;access-control-allow-methods&amp;#39;: &amp;#39;GET,POST,OPTIONS&amp;#39;,
     &amp;#39;access-control-allow-headers&amp;#39;: &amp;#39;content-type&amp;#39;,
     &amp;#39;cache-control&amp;#39;: &amp;#39;private, max-age=60&amp;#39;
    }
   };
  }

  if (method !== &amp;#39;GET&amp;#39; &amp;amp;&amp;amp; method !== &amp;#39;POST&amp;#39;) {
   return { statusCode: 405, body: &amp;#39;Method Not Allowed&amp;#39; };
  }

  if (allowedOrigins.length &amp;amp;&amp;amp; !allowedOrigins.includes(origin)) {
   return { statusCode: 403, body: &amp;#39;Forbidden&amp;#39;, headers: { &amp;#39;access-control-allow-origin&amp;#39;: acao } };
  }

  let keys = [], ttl = 600;
  if (method === &amp;#39;GET&amp;#39;) {
   const qs = event.queryStringParameters || {};
   const rawKeys = qs.keys || &amp;#39;&amp;#39;;
   keys = String(rawKeys).split(&amp;#39;,&amp;#39;).map(s =&amp;gt; s.trim()).filter(Boolean);
   ttl = parseInt(qs.ttl || &amp;#39;600&amp;#39;, 10);
  } else {
   let bodyObj = {};
   if (event.body) {
    try {
     const text = event.isBase64Encoded ? Buffer.from(event.body, &amp;#39;base64&amp;#39;).toString(&amp;#39;utf8&amp;#39;) : event.body;
     bodyObj = JSON.parse(text);
    } catch (_) {
     bodyObj = {};
    }
   }
   keys = Array.isArray(bodyObj.keys) ? bodyObj.keys : [];
   ttl = parseInt(bodyObj.ttl ?? 600, 10);
  }

  ttl = Math.min(Math.max(ttl, 30), 3600);
  const sanitized = keys.filter(isAllowedKey);
  if (sanitized.length === 0) {
   return {
    statusCode: 400,
    headers: { &amp;#39;access-control-allow-origin&amp;#39;: acao },
    body: JSON.stringify({ error: &amp;#39;No valid keys&amp;#39; })
   };
  }

  const now = Math.floor(Date.now() / 1000);
  const urls = await Promise.all(sanitized.map(async (key) =&amp;gt; {
   const url = client.signatureUrl(key, { expires: ttl, method: &amp;#39;GET&amp;#39; });
   return { key, url, exp: now &amp;#43; ttl };
  }));

  return {
   statusCode: 200,
   headers: {
    &amp;#39;content-type&amp;#39;: &amp;#39;application/json; charset=utf-8&amp;#39;,
    &amp;#39;cache-control&amp;#39;: &amp;#39;private, max-age=60&amp;#39;,
    &amp;#39;access-control-allow-origin&amp;#39;: acao,
    &amp;#39;access-control-allow-methods&amp;#39;: &amp;#39;GET,POST,OPTIONS&amp;#39;,
    &amp;#39;access-control-allow-headers&amp;#39;: &amp;#39;content-type&amp;#39;
   },
   body: JSON.stringify({ urls })
  };
 } catch (e) {
  return { statusCode: 500, body: JSON.stringify({ error: &amp;#39;Server error&amp;#39; }) };
 }
};&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;use strict&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;OSS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;require&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ali-oss&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Allow all by default for a dedicated bucket; override via OSS_ALLOWED_PREFIXES
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;RAW_PREFIXES&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;OSS_ALLOWED_PREFIXES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ALLOWED_PREFIXES&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;RAW_PREFIXES&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;RAW_PREFIXES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;RAW_PREFIXES&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;isAllowedKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;sr&#34;&gt;/^[\w\-./]+$/&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ALLOWED_PREFIXES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;includes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ALLOWED_PREFIXES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;some&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;startsWith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;parseAllowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ALLOWED_ORIGINS&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;OSS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nx&#34;&gt;region&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;OSS_REGION&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nx&#34;&gt;accessKeyId&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;OSS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nx&#34;&gt;accessKeySecret&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;OSS_ACCESS_KEY_SECRET&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nx&#34;&gt;bucket&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;process&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;env&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;OSS_BUCKET&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;exports&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;handler&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;httpMethod&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toUpperCase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;origin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;origin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Origin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;allowedOrigins&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;parseAllowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;acao&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;allowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;allowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;includes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;origin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;origin&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;OPTIONS&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;204&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-origin&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;acao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-methods&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET,POST,OPTIONS&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-headers&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;s1&#34;&gt;&amp;#39;cache-control&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;private, max-age=60&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!==&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;405&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Method Not Allowed&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;allowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;allowedOrigins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;includes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;origin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;403&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Forbidden&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-origin&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;acao&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;qs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;queryStringParameters&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;rawKeys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;qs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;rawKeys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;split&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;s&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;trim&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;qs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;600&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;kd&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isBase64Encoded&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;toString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;utf8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;event&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isArray&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;bodyObj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;??&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;max&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;30&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;sanitized&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;isAllowedKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sanitized&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;400&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-origin&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;acao&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;stringify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;No valid keys&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Math&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;floor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;Date&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;urls&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Promise&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sanitized&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;signatureUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;expires&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;method&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;exp&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;now&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ttl&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;headers&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s1&#34;&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;application/json; charset=utf-8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s1&#34;&gt;&amp;#39;cache-control&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;private, max-age=60&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-origin&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;acao&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-methods&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;GET,POST,OPTIONS&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s1&#34;&gt;&amp;#39;access-control-allow-headers&amp;#39;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;content-type&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;stringify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;urls&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;statusCode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;500&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;body&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;JSON&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;stringify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;Server error&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;netlify.toml&lt;/strong&gt; 添加配置，指定函数目录：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;toml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;[build]
  functions = &amp;#34;netlify/functions&amp;#34;

[functions]
  node_bundler = &amp;#34;esbuild&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;functions&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;netlify/functions&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;functions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;node_bundler&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;esbuild&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;config.toml&lt;/strong&gt;，定义OSS前缀链接：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;toml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;[params.oss]
hosts = [
  &amp;#34;https://cyp0633-blogasset.oss-cn-qingdao.aliyuncs.com/&amp;#34;,
  &amp;#34;https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com/&amp;#34;
]&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;oss&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;hosts&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://cyp0633-blogasset.oss-cn-qingdao.aliyuncs.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://cyp0633-blogasset.cn-qingdao.oss.aliyuncs.com/&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;layouts/_default/_markup/render-image.html&lt;/strong&gt;，将具有上述前缀的链接替换为 &lt;code&gt;data-oss-key&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;html&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;{{- /*
 Override: detect OSS remote images and emit data-oss-key for client signing,
 other images fall back to theme default behavior.
*/ -}}
{{- $dest := .Destination | safeURL -}}
{{- $alt := .PlainText | safeHTML -}}

{{- /* Determine if remote and hosted on OSS */ -}}
{{- $isRemote := or (hasPrefix $dest &amp;#34;http://&amp;#34;) (hasPrefix $dest &amp;#34;https://&amp;#34;) -}}
{{- $ossHosts := site.Params.oss.hosts | default (slice) -}}
{{- $matchOss := false -}}
{{- if $isRemote -}}
 {{- if gt (len $ossHosts) 0 -}}
  {{- range $ossHosts -}}
   {{- if hasPrefix $dest . -}}
    {{- $matchOss = true -}}
   {{- end -}}
  {{- end -}}
 {{- else -}}
  {{- /* Fallback: aliyun OSS domain heuristic (aliyuncs.com and aliyun.com) */ -}}
  {{- if or (findRE `^https?://[^/]*(aliyuncs\.com)/` $dest) (findRE `^https?://[^/]*(aliyun\.com)/` $dest) -}}
   {{- $matchOss = true -}}
  {{- end -}}
 {{- end -}}
{{- end -}}

{{- if and $isRemote $matchOss -}}
 {{- /* Extract object key (path without leading slash) */ -}}
 {{- $key := (replaceRE `^https?://[^/]*/` `` $dest) -}}
 {{- $key = (replaceRE `^/` `` $key) -}}
 {{- $placeholder := `data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==` -}}
 &amp;lt;figure style=&amp;#34;max-width: 80%; margin: auto;&amp;#34;&amp;gt;
  &amp;lt;img data-oss-key=&amp;#34;{{ $key }}&amp;#34; src=&amp;#34;{{ $placeholder | safeURL }}&amp;#34; loading=&amp;#34;lazy&amp;#34; {{ with $alt }} alt=&amp;#34;{{ . }}&amp;#34; {{ end }}
   style=&amp;#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&amp;#34;&amp;gt;
  {{ if .Title }}
  &amp;lt;figcaption&amp;gt;{{ .Title | markdownify }}&amp;lt;/figcaption&amp;gt;
  {{ end }}
 &amp;lt;/figure&amp;gt;
{{- else -}}
 {{- /* Default theme behavior for local or non-OSS remote images */ -}}
 {{- $image := .Page.Resources.GetMatch (printf &amp;#34;%s&amp;#34; (.Destination | safeURL)) -}}
 {{- $Permalink := .Destination | relURL | safeURL -}}
 &amp;lt;figure style=&amp;#34;max-width: 80%; margin: auto;&amp;#34;&amp;gt;
  &amp;lt;img src=&amp;#34;{{ $Permalink }}&amp;#34; loading=&amp;#34;lazy&amp;#34; {{ with $alt }} alt=&amp;#34;{{ . }}&amp;#34; {{ end }}
   style=&amp;#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&amp;#34;&amp;gt;
  {{ if .Title }}
  &amp;lt;figcaption&amp;gt;{{ .Title | markdownify }}&amp;lt;/figcaption&amp;gt;
  {{ end }}
 &amp;lt;/figure&amp;gt;
{{- end -}}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- /*
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; Override: detect OSS remote images and emit data-oss-key for client signing,
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; other images fall back to theme default behavior.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;*/ -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- $dest := .Destination | safeURL -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- $alt := .PlainText | safeHTML -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- /* Determine if remote and hosted on OSS */ -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- $isRemote := or (hasPrefix $dest &amp;#34;http://&amp;#34;) (hasPrefix $dest &amp;#34;https://&amp;#34;) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- $ossHosts := site.Params.oss.hosts | default (slice) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- $matchOss := false -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- if $isRemote -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- if gt (len $ossHosts) 0 -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{- range $ossHosts -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   {{- if hasPrefix $dest . -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    {{- $matchOss = true -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- else -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{- /* Fallback: aliyun OSS domain heuristic (aliyuncs.com and aliyun.com) */ -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{- if or (findRE `^https?://[^/]*(aliyuncs\.com)/` $dest) (findRE `^https?://[^/]*(aliyun\.com)/` $dest) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   {{- $matchOss = true -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- end -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- if and $isRemote $matchOss -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- /* Extract object key (path without leading slash) */ -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- $key := (replaceRE `^https?://[^/]*/` `` $dest) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- $key = (replaceRE `^/` `` $key) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- $placeholder := `data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==` -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figure&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;max-width: 80%; margin: auto;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;data-oss-key&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;{{ $key }}&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;{{ $placeholder | safeURL }}&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;loading&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;lazy&amp;#34;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;}}&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;{{ . }}&amp;#34;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;na&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{ if .Title }}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figcaption&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;{{ .Title | markdownify }}&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figcaption&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- else -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- /* Default theme behavior for local or non-OSS remote images */ -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- $image := .Page.Resources.GetMatch (printf &amp;#34;%s&amp;#34; (.Destination | safeURL)) -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; {{- $Permalink := .Destination | relURL | safeURL -}}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figure&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;max-width: 80%; margin: auto;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;img&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;src&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;{{ $Permalink }}&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;loading&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;lazy&amp;#34;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;}}&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;alt&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;{{ . }}&amp;#34;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;{{&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;na&#34;&gt;style&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{ if .Title }}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figcaption&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;{{ .Title | markdownify }}&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figcaption&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  {{ end }}
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;figure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;{{- end -}}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;assets/ts/custom.ts&lt;/strong&gt;，用于收集 &lt;code&gt;data-oss-key&lt;/code&gt; 请求签名：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;typescript&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;type SignedEntry = { key: string; url: string; exp: number };

function collectOssKeys(): string[] {
 const imgs = Array.from(document.querySelectorAll&amp;lt;HTMLImageElement&amp;gt;(&amp;#39;img[data-oss-key]&amp;#39;));
 const keys = imgs
  .map((img) =&amp;gt; img.dataset.ossKey || &amp;#39;&amp;#39;)
  .filter((k) =&amp;gt; k.length &amp;gt; 0);
 return Array.from(new Set(keys));
}

async function fetchSignedUrls(keys: string[], ttlSeconds = 600): Promise&amp;lt;Map&amp;lt;string, string&amp;gt;&amp;gt; {
 const endpoint = &amp;#39;/.netlify/functions/sign-oss&amp;#39;;
 const url = `${endpoint}?ttl=${encodeURIComponent(String(ttlSeconds))}&amp;amp;keys=${encodeURIComponent(keys.join(&amp;#39;,&amp;#39;))}`;
 const res = await fetch(url, { credentials: &amp;#39;omit&amp;#39;, cache: &amp;#39;no-store&amp;#39; });
 if (!res.ok) return new Map();
 const data = (await res.json()) as { urls?: SignedEntry[] };
 const map = new Map&amp;lt;string, string&amp;gt;();
 (data.urls || []).forEach((u) =&amp;gt; {
  if (u &amp;amp;&amp;amp; u.key &amp;amp;&amp;amp; u.url) map.set(u.key, u.url);
 });
 return map;
}

function applySignedUrls(map: Map&amp;lt;string, string&amp;gt;): void {
 document.querySelectorAll&amp;lt;HTMLImageElement&amp;gt;(&amp;#39;img[data-oss-key]&amp;#39;).forEach((img) =&amp;gt; {
  const key = img.dataset.ossKey || &amp;#39;&amp;#39;;
  const signed = key ? map.get(key) : undefined;
  if (signed) {
   img.src = signed;
   img.removeAttribute(&amp;#39;data-oss-key&amp;#39;);
  }
 });
}

async function initOssSigning(): Promise&amp;lt;void&amp;gt; {
 const keys = collectOssKeys();
 if (keys.length === 0) return;
 try {
  const map = await fetchSignedUrls(keys, 600);
  applySignedUrls(map);
 } catch {
  // no-op
 }
}

if (document.readyState === &amp;#39;loading&amp;#39;) {
 document.addEventListener(&amp;#39;DOMContentLoaded&amp;#39;, () =&amp;gt; {
  void initOssSigning();
 });
} else {
 void initOssSigning();
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-typescript&#34; data-lang=&#34;typescript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;SignedEntry&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;exp&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;collectOssKeys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;imgs&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;HTMLImageElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;img[data-oss-key]&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;imgs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dataset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ossKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;k&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Array&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fetchSignedUrls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;ttlSeconds&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Promise&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;endpoint&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;/.netlify/functions/sign-oss&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;endpoint&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;?ttl=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ttlSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;&amp;amp;keys=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;encodeURIComponent&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;,&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;sb&#34;&gt;`&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;res&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fetch&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;credentials&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;omit&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;no-store&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt; &lt;span class=&#34;kr&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;urls?&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;SignedEntry&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;urls&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;forEach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;u&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;applySignedUrls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;: &lt;span class=&#34;kt&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;HTMLImageElement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;img[data-oss-key]&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;forEach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dataset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ossKey&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;||&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;signed&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;undefined&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;signed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;src&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;signed&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;   &lt;span class=&#34;nx&#34;&gt;img&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;removeAttribute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;data-oss-key&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;initOssSigning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Promise&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;void&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;collectOssKeys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kr&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;fetchSignedUrls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;keys&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;600&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;applySignedUrls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// no-op
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;readyState&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;===&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;loading&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;nb&#34;&gt;document&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;addEventListener&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;DOMContentLoaded&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;initOssSigning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;initOssSigning&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;另外还需要在Netlify上设置环境变量：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ALLOWED_PREFIXES&lt;/code&gt;：如果所有图片都在同一个目录下可以使用；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OSS_REGION&lt;/code&gt;：OSS地域，例如 &lt;code&gt;oss-cn-qingdao&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OSS_BUCKET&lt;/code&gt;：OSS Bucket名称，例如 &lt;code&gt;cyp0633-blogasset&lt;/code&gt;；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;OSS_ACCESS_KEY_ID&lt;/code&gt; 和 &lt;code&gt;OSS_ACCESS_KEY_SECRET&lt;/code&gt;：访问密钥。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就行了。构建时Hugo会自动将OSS链接替换为key，只能在访问时签名，签名只能用于特定的文件，且有效期有限；即使key特征明显，也无法直接访问OSS。&lt;/p&gt;
&lt;p&gt;在部署这个方案之后，收到的成效非常显著：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;46.62.169.27再也没有出现过；&lt;/li&gt;
&lt;li&gt;盗图的Thumbor也没有再出现过；&lt;/li&gt;
&lt;li&gt;搜索引擎索引（包括Bingbot、Googlebot、ChatGPT搜索和Petalbot等）正常访问。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;block-scrapers/hourly_counts.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;按小时的访问量统计&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;按小时的访问量统计&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;block-scrapers/oss_access_patterns.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Top IP 访问量统计&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Top IP 访问量统计&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;不出意外的话，你也能访问这个页面的图片内容，如果不能的话，请你在评论区留言，除非你的评论区也加载不出来：）&lt;/p&gt;
&lt;h2 id=&#34;超级分布式gitea爬虫&#34;&gt;超级分布式Gitea爬虫
&lt;/h2&gt;&lt;p&gt;其实大家都知道上面的办法治标不治本，我也知道。8月针对爬取Gitea的办法是屏蔽网段+挂CF，而一旦网段这个简单的特征被稀释，或者说爬取者找到了足够大的IP池，这个办法就不会有任何效果了。而对于大的AI训练者来说，他们最不缺的就是钱——起码与几万张B200相比，几台VPS根本不算什么。&lt;/p&gt;
&lt;p&gt;于是在10月末，我又收到了这样的日志：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-8&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-8&#34; style=&#34;display:none;&#34;&gt;{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.1998942,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.70.42.189&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11100&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.70.42.189&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/raw/commit/028ae12ea56077fb630bbf12ed46781db583fe2a/layouts/_default/baseof.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;23.239.187.90&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;23.239.187.90&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effb9b4a057f-IAD&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.065625343,&amp;#34;size&amp;#34;:352,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Last-Modified&amp;#34;:[&amp;#34;Thu, 24 Dec 2020 10:06:58 GMT&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;private, max-age=300&amp;#34;],&amp;#34;Content-Disposition&amp;#34;:[&amp;#34;inline; filename=\&amp;#34;baseof.html\&amp;#34;; filename*=UTF-8&amp;#39;&amp;#39;baseof.html&amp;#34;],&amp;#34;Content-Encoding&amp;#34;:[&amp;#34;gzip&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Access-Control-Expose-Headers&amp;#34;:[&amp;#34;Content-Disposition&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/plain; charset=utf-8&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Content-Type-Options&amp;#34;:[&amp;#34;nosniff&amp;#34;],&amp;#34;Etag&amp;#34;:[&amp;#34;\&amp;#34;ce0ddae104d973c67c938411e1c9fc19c4f383ef-gzip\&amp;#34;&amp;#34;],&amp;#34;Vary&amp;#34;:[&amp;#34;Accept-Encoding&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.2023957,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;162.158.79.51&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11567&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;162.158.79.51&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ns3-datacenter/commits/commit/dc680c3cf9a4de64facbb20355ae718e1a51adbb/simulator/bake&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effb9a9cd679-IAD&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;45.41.164.103&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;45.41.164.103&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.071713334,&amp;#34;size&amp;#34;:26876,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.2423117,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.166.230&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11416&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.166.230&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/compiler-lab/raw/commit/f9764c54da2bf5ed944b69de05030d407fd32a16/lab1/convert_test.go&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;140.99.218.213&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;MX&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effbef97379d-DFW&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;140.99.218.213&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.088202332,&amp;#34;size&amp;#34;:1103,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;private, max-age=300&amp;#34;],&amp;#34;Last-Modified&amp;#34;:[&amp;#34;Sat, 25 Mar 2023 02:59:49 GMT&amp;#34;],&amp;#34;Content-Disposition&amp;#34;:[&amp;#34;inline; filename=\&amp;#34;convert_test.go\&amp;#34;; filename*=UTF-8&amp;#39;&amp;#39;convert_test.go&amp;#34;],&amp;#34;Etag&amp;#34;:[&amp;#34;\&amp;#34;b4da01f8edc68fb19d2ea64add3fb0cdf169de00-gzip\&amp;#34;&amp;#34;],&amp;#34;X-Content-Type-Options&amp;#34;:[&amp;#34;nosniff&amp;#34;],&amp;#34;Access-Control-Expose-Headers&amp;#34;:[&amp;#34;Content-Disposition&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/plain; charset=utf-8&amp;#34;],&amp;#34;Content-Encoding&amp;#34;:[&amp;#34;gzip&amp;#34;],&amp;#34;Vary&amp;#34;:[&amp;#34;Accept-Encoding&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.269168,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.210.233&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;10408&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.210.233&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/92a6d71ce5d49583a8ad6ac0819cdbef740e6fe4/exampleSite/README.md&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;75.102.28.121&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effd19159b4a-HKG&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;JP&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;75.102.28.121&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.00977558,&amp;#34;size&amp;#34;:9325,&amp;#34;status&amp;#34;:404,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.327542,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.166.230&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11416&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.166.230&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/rss/commit/57bfea833850e0565cf81d9a26c52359427151a2/archetypes/tags.md&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;23.230.234.184&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;23.230.234.184&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effcdcf3e956-DFW&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Trailer/93.3.8652.5&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.013796775,&amp;#34;size&amp;#34;:9322,&amp;#34;status&amp;#34;:404,&amp;#34;resp_headers&amp;#34;:{&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.4023278,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.70.115.160&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;10314&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.70.115.160&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ns3-datacenter/src/commit/f92fef3b51b8354ae8941280a43a2554c9646017/simulator/pybindgen-0.22.0/tox.ini&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;213.201.198.112&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;213.201.198.112&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effbbf96dd82-EWR&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.26401861,&amp;#34;size&amp;#34;:30170,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.4635193,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.70.38.6&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;14185&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.70.38.6&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ModelComputer/commits/commit/8f16f8e97d493fd4683831f95cd8825f4ea9f760/ALU&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;23.226.223.128&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc7d1c392b-IAD&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;23.226.223.128&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.195946316,&amp;#34;size&amp;#34;:26304,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.4655995,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.194.111&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;14185&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.194.111&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/c41a3e0621b51c831804502d761b2ddd370ccd38/layouts/index.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 OPR/117.0.0.0&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;89.116.14.139&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc0c1cd6e8-IAD&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;89.116.14.139&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.262741163,&amp;#34;size&amp;#34;:32454,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.472112,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;162.158.175.131&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11188&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;162.158.175.131&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ns3-datacenter/src/commit/281afc20f5e6a6ba20a13cab31e730a435959050/simulator/ns-3.39/.vscode/tasks.json&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;45.56.186.71&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effbb9ee4796-DFW&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;45.56.186.71&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.342308283,&amp;#34;size&amp;#34;:35925,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.4908528,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.69.22.17&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12062&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.69.22.17&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ns3-datacenter/src/commit/40b84300cf5bc6b41953239419aa8b9022a793d4/simulator/ns-3.35/bindings/python/ns__init__.py&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effbeaef15e1-SJC&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;166.0.180.40&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;166.0.180.40&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.341574757,&amp;#34;size&amp;#34;:28822,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.4981875,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.191.124&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12844&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.191.124&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/a5986b92fdd601bd8b9e6907b01750bf9fbde741/layouts/_default/single.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;104.194.220.229&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;104.194.220.229&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effbfb0be639-IAD&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.297898894,&amp;#34;size&amp;#34;:86599,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.509331,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;162.158.122.174&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;10970&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;162.158.122.174&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/src/commit/34cd7852bc115f926b131e99c6384609d048f28f/layouts/partials/pagination.html&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;45.157.185.71&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc4a4acbb6-MAD&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;ES&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;45.157.185.71&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.291499759,&amp;#34;size&amp;#34;:36375,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.5167801,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.23.49&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;10556&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.23.49&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/NanaMail-android/src/commit/59c843537d84d1c6737d5d71a708b459ab53cf98/.idea/gradle.xml&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;85.254.125.48&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;85.254.125.48&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc2e95afbf-ATL&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.298081216,&amp;#34;size&amp;#34;:34775,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.5189972,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.68.234.49&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;11517&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.68.234.49&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ostep-homework/commits/commit/375d19ba4b693a0f70f7632b82729fb212471564/threads-locks/test-and-set.s&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effd0f4de1cd-MRS&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;IN&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;110.44.2.253&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;110.44.2.253&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.195997813,&amp;#34;size&amp;#34;:26607,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.554788,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;104.23.190.253&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;10096&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;104.23.190.253&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ns3-datacenter/src/commit/cbf82ca5c485aa25a521641d98f7057869b65c98/simulator/netanim-3.109/qtpropertybrowser/src/QtCheckBoxFactory&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc08b82732-EWR&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;84.37.134.1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;84.37.134.1&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.362997391,&amp;#34;size&amp;#34;:29091,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.5676897,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.71.175.92&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12402&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.71.175.92&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/ostep-homework/blame/commit/a9800f62f7c4b5b73acf8b239912981066893c30/threads-cv/main-common.c&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effcecf13acd-DFW&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;85.254.139.44&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;85.254.139.44&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.232635982,&amp;#34;size&amp;#34;:148573,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.5740168,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;172.70.34.170&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12627&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;172.70.34.170&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/k12-math-paper-generator/commits/commit/a42e3bc68b2f3285da3368127b642b5999fef9a0/frontend/src/App.vue&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;89.116.14.10&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effc0f995a45-IAD&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;89.116.14.10&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.371793012,&amp;#34;size&amp;#34;:68154,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;]}}
{&amp;#34;level&amp;#34;:&amp;#34;info&amp;#34;,&amp;#34;ts&amp;#34;:1761649310.6670785,&amp;#34;logger&amp;#34;:&amp;#34;http.log.access.log1&amp;#34;,&amp;#34;msg&amp;#34;:&amp;#34;handled request&amp;#34;,&amp;#34;request&amp;#34;:{&amp;#34;remote_ip&amp;#34;:&amp;#34;162.158.167.69&amp;#34;,&amp;#34;remote_port&amp;#34;:&amp;#34;12289&amp;#34;,&amp;#34;client_ip&amp;#34;:&amp;#34;162.158.167.69&amp;#34;,&amp;#34;proto&amp;#34;:&amp;#34;HTTP/2.0&amp;#34;,&amp;#34;method&amp;#34;:&amp;#34;GET&amp;#34;,&amp;#34;host&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;,&amp;#34;uri&amp;#34;:&amp;#34;/cyp0633/stack-mod/blame/commit/41c3033d1ac6b9596ce3ae861484e855b619705a/i18n/en.yaml&amp;#34;,&amp;#34;headers&amp;#34;:{&amp;#34;Referrer&amp;#34;:[&amp;#34;https://www.google.com/&amp;#34;],&amp;#34;Accept-Encoding&amp;#34;:[&amp;#34;gzip, br&amp;#34;],&amp;#34;Cf-Ray&amp;#34;:[&amp;#34;9959effec835cf2e-SJC&amp;#34;],&amp;#34;Cf-Connecting-Ip&amp;#34;:[&amp;#34;50.114.108.24&amp;#34;],&amp;#34;Accept&amp;#34;:[&amp;#34;text/html,application/xhtml&amp;#43;xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;],&amp;#34;Cdn-Loop&amp;#34;:[&amp;#34;cloudflare; loops=1&amp;#34;],&amp;#34;Cf-Ipcountry&amp;#34;:[&amp;#34;US&amp;#34;],&amp;#34;Cf-Visitor&amp;#34;:[&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;],&amp;#34;User-Agent&amp;#34;:[&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;],&amp;#34;Accept-Language&amp;#34;:[&amp;#34;en-US,en;q=0.5&amp;#34;],&amp;#34;X-Forwarded-For&amp;#34;:[&amp;#34;50.114.108.24&amp;#34;],&amp;#34;X-Forwarded-Proto&amp;#34;:[&amp;#34;https&amp;#34;]},&amp;#34;tls&amp;#34;:{&amp;#34;resumed&amp;#34;:false,&amp;#34;version&amp;#34;:772,&amp;#34;cipher_suite&amp;#34;:4865,&amp;#34;proto&amp;#34;:&amp;#34;h2&amp;#34;,&amp;#34;server_name&amp;#34;:&amp;#34;git.cyp0633.icu&amp;#34;}},&amp;#34;bytes_read&amp;#34;:0,&amp;#34;user_id&amp;#34;:&amp;#34;&amp;#34;,&amp;#34;duration&amp;#34;:0.064485444,&amp;#34;size&amp;#34;:121024,&amp;#34;status&amp;#34;:200,&amp;#34;resp_headers&amp;#34;:{&amp;#34;X-Frame-Options&amp;#34;:[&amp;#34;SAMEORIGIN&amp;#34;],&amp;#34;Server&amp;#34;:[&amp;#34;Caddy&amp;#34;],&amp;#34;Alt-Svc&amp;#34;:[&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;],&amp;#34;Date&amp;#34;:[&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;],&amp;#34;Cache-Control&amp;#34;:[&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;],&amp;#34;Content-Type&amp;#34;:[&amp;#34;text/html; charset=utf-8&amp;#34;],&amp;#34;Set-Cookie&amp;#34;:[&amp;#34;REDACTED&amp;#34;]}}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.1998942&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.42.189&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11100&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.42.189&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/raw/commit/028ae12ea56077fb630bbf12ed46781db583fe2a/layouts/_default/baseof.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.239.187.90&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.239.187.90&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effb9b4a057f-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.065625343&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;352&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Last-Modified&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Thu, 24 Dec 2020 10:06:58 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;private, max-age=300&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Disposition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline; filename=\&amp;#34;baseof.html\&amp;#34;; filename*=UTF-8&amp;#39;&amp;#39;baseof.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Access-Control-Expose-Headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Disposition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/plain; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Content-Type-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nosniff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Etag&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;\&amp;#34;ce0ddae104d973c67c938411e1c9fc19c4f383ef-gzip\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Vary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.2023957&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.79.51&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11567&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.79.51&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ns3-datacenter/commits/commit/dc680c3cf9a4de64facbb20355ae718e1a51adbb/simulator/bake&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effb9a9cd679-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.41.164.103&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.41.164.103&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.071713334&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;26876&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.2423117&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.166.230&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11416&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.166.230&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/compiler-lab/raw/commit/f9764c54da2bf5ed944b69de05030d407fd32a16/lab1/convert_test.go&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;140.99.218.213&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;MX&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effbef97379d-DFW&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;140.99.218.213&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.088202332&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1103&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;private, max-age=300&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Last-Modified&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Sat, 25 Mar 2023 02:59:49 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Disposition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;inline; filename=\&amp;#34;convert_test.go\&amp;#34;; filename*=UTF-8&amp;#39;&amp;#39;convert_test.go&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Etag&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;\&amp;#34;b4da01f8edc68fb19d2ea64add3fb0cdf169de00-gzip\&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Content-Type-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;nosniff&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Access-Control-Expose-Headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Content-Disposition&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/plain; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Vary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.269168&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.210.233&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10408&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.210.233&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/rss/commit/92a6d71ce5d49583a8ad6ac0819cdbef740e6fe4/exampleSite/README.md&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;75.102.28.121&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effd19159b4a-HKG&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;JP&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;75.102.28.121&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.00977558&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9325&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;404&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.327542&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.166.230&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11416&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.166.230&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/rss/commit/57bfea833850e0565cf81d9a26c52359427151a2/archetypes/tags.md&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.230.234.184&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.230.234.184&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effcdcf3e956-DFW&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Trailer/93.3.8652.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.013796775&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9322&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;404&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.4023278&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.115.160&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10314&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.115.160&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ns3-datacenter/src/commit/f92fef3b51b8354ae8941280a43a2554c9646017/simulator/pybindgen-0.22.0/tox.ini&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;213.201.198.112&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;213.201.198.112&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effbbf96dd82-EWR&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.26401861&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30170&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.4635193&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.38.6&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;14185&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.38.6&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ModelComputer/commits/commit/8f16f8e97d493fd4683831f95cd8825f4ea9f760/ALU&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.226.223.128&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc7d1c392b-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;23.226.223.128&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.195946316&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;26304&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.4655995&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.194.111&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;14185&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.194.111&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/src/commit/c41a3e0621b51c831804502d761b2ddd370ccd38/layouts/index.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 OPR/117.0.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;89.116.14.139&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc0c1cd6e8-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;89.116.14.139&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.262741163&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;32454&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.472112&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.175.131&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11188&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.175.131&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ns3-datacenter/src/commit/281afc20f5e6a6ba20a13cab31e730a435959050/simulator/ns-3.39/.vscode/tasks.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.56.186.71&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effbb9ee4796-DFW&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.56.186.71&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.342308283&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;35925&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.4908528&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.69.22.17&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12062&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.69.22.17&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ns3-datacenter/src/commit/40b84300cf5bc6b41953239419aa8b9022a793d4/simulator/ns-3.35/bindings/python/ns__init__.py&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effbeaef15e1-SJC&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;166.0.180.40&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;166.0.180.40&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.341574757&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;28822&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.4981875&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.191.124&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12844&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.191.124&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/blame/commit/a5986b92fdd601bd8b9e6907b01750bf9fbde741/layouts/_default/single.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;104.194.220.229&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;104.194.220.229&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effbfb0be639-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.297898894&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;86599&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.509331&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.122.174&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10970&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.122.174&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/src/commit/34cd7852bc115f926b131e99c6384609d048f28f/layouts/partials/pagination.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.157.185.71&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc4a4acbb6-MAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ES&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;45.157.185.71&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.291499759&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;36375&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.5167801&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.23.49&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10556&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.23.49&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/NanaMail-android/src/commit/59c843537d84d1c6737d5d71a708b459ab53cf98/.idea/gradle.xml&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;85.254.125.48&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;85.254.125.48&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc2e95afbf-ATL&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.298081216&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;34775&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.5189972&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.68.234.49&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;11517&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.68.234.49&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ostep-homework/commits/commit/375d19ba4b693a0f70f7632b82729fb212471564/threads-locks/test-and-set.s&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effd0f4de1cd-MRS&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;IN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;110.44.2.253&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;110.44.2.253&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.195997813&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;26607&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.554788&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;104.23.190.253&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;10096&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;104.23.190.253&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ns3-datacenter/src/commit/cbf82ca5c485aa25a521641d98f7057869b65c98/simulator/netanim-3.109/qtpropertybrowser/src/QtCheckBoxFactory&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc08b82732-EWR&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;84.37.134.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;84.37.134.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.362997391&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;29091&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.5676897&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.175.92&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12402&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.71.175.92&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/ostep-homework/blame/commit/a9800f62f7c4b5b73acf8b239912981066893c30/threads-cv/main-common.c&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effcecf13acd-DFW&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;85.254.139.44&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;85.254.139.44&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.232635982&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;148573&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.5740168&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.34.170&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12627&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;172.70.34.170&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/k12-math-paper-generator/commits/commit/a42e3bc68b2f3285da3368127b642b5999fef9a0/frontend/src/App.vue&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;89.116.14.10&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effc0f995a45-IAD&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;89.116.14.10&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.371793012&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;68154&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;level&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;info&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;ts&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;1761649310.6670785&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;logger&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;http.log.access.log1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;msg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;handled request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.167.69&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;remote_port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;12289&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;client_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;162.158.167.69&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;HTTP/2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;method&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;GET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;host&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;uri&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;/cyp0633/stack-mod/blame/commit/41c3033d1ac6b9596ce3ae861484e855b619705a/i18n/en.yaml&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Referrer&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://www.google.com/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Encoding&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;gzip, br&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;9959effec835cf2e-SJC&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Connecting-Ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;50.114.108.24&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cdn-Loop&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare; loops=1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Ipcountry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;US&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cf-Visitor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;{\&amp;#34;scheme\&amp;#34;:\&amp;#34;https\&amp;#34;}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;User-Agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.10 Safari/605.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Accept-Language&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;en-US,en;q=0.5&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-For&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;50.114.108.24&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Forwarded-Proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resumed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;772&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;cipher_suite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4865&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;proto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;server_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;git.cyp0633.icu&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}},&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;bytes_read&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;user_id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;duration&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;0.064485444&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;size&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;121024&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;resp_headers&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;X-Frame-Options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;SAMEORIGIN&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Server&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Caddy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Alt-Svc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;h3=\&amp;#34;:443\&amp;#34;; ma=2592000&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Tue, 28 Oct 2025 11:01:50 GMT&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Cache-Control&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;max-age=0, private, must-revalidate, no-transform&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Content-Type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;text/html; charset=utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;&amp;#34;Set-Cookie&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;REDACTED&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]}}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;与上次Gitea被大规模爬取不同，日志中的2134个不同的源IP来自世界各地的不同国家，也有着各种可以以假乱真的User-Agent，光凭最简单的两个特征已经无法分辨爬虫和正常访问；&lt;code&gt;Referrer&lt;/code&gt; 字段倒是统一的Google，一个根本无法屏蔽的值。在开始记录到爬取停止的30分钟内总共有超过25000条请求，也就是说平均每秒近14条，且endpoint基本都是 &lt;code&gt;/src&lt;/code&gt;、&lt;code&gt;/raw/&lt;/code&gt; 和 &lt;code&gt;/blame/&lt;/code&gt; 之类的高开销请求。&lt;/p&gt;
&lt;p&gt;怎么办呢？部分在ChatGPT的帮助下（用AI防御AI），本着尽量不影响正常用户访问（虽然没几个）、尽量block掉爬虫的原则，有了这么几种办法：&lt;/p&gt;
&lt;h3 id=&#34;表层特征过滤和速率限制&#34;&gt;表层特征过滤和速率限制
&lt;/h3&gt;&lt;p&gt;由于爬虫有着巨大的IP池和不断变化的User-Agent，这些表层措施（甚至包括fail2ban）可以说收效甚微。而这些爬虫IP十分随机，以至于试了好几个都在AbuseIPDB上完全没有风险，下载其数据库也无法有效匹配。&lt;/p&gt;
&lt;p&gt;同样的，由于请求被分摊到了大量IP上，针对IP做限速也是完全无效的。半小时的请求平均下来每个IP才12次，真人的请求都比这个多。&lt;/p&gt;
&lt;h3 id=&#34;js-challenge&#34;&gt;JS challenge
&lt;/h3&gt;&lt;p&gt;就像前两天被打得叫苦不迭的GNOME GitLab和AUR一样，上Anubis之类的JS challenge？&lt;a class=&#34;link&#34; href=&#34;https://fxgn.dev/blog/anubis/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;其实很可能没什么用&lt;/a&gt;，从代价来看它根本防御不了爬虫。&lt;/p&gt;
&lt;p&gt;无节制的爬虫与DDoS有着本质的区别。DDoS的目的是把服务器打垮、资源耗尽，即内存频繁缺页、CPU负载过高、刷爆CDN流量，或是令网络提供商不得不进行路由黑洞等，而不追求真的能访问到网页内容，因此DDoS通常有着极高的强度，而平均到每次请求所允许的开销很低，尤其考虑到DDoS的直接请求者经常是各种IoT肉鸡的情况下。从这个角度上来说，JS challenge通过大幅增加请求者的计算开销来阻挡DDoS是非常有效的。&lt;/p&gt;
&lt;p&gt;而爬虫则不同。一方面，它们在提高爬取强度之前，需要确保访问的内容是可用的，所以不会以“打死”为目的；另一方面，财大气粗的AI企业能够购买大量合法的网络资源。更多的总资源，更少的请求频率，使得分配到每次请求的计算开销显著提高，即使让爬虫去解JS challenge成本也是可控的，AI企业有足够的动机去做这件事。&lt;/p&gt;
&lt;p&gt;上面链接中的博客说的是同一件事。计算发现解一个Anubis这样的challenge成本几乎为零，而某个刚刚套壳了别人模型的厂恰巧也发现了，只要给爬虫加个runtime就行了。&lt;/p&gt;
&lt;h3 id=&#34;gitea限制用户访问&#34;&gt;Gitea限制用户访问
&lt;/h3&gt;&lt;p&gt;Gitea配置中自带一个限制高开销endpoint的选项：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-9&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-9&#34; style=&#34;display:none;&#34;&gt;[service]
REQUIRE_SIGNIN_VIEW = expensive&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;REQUIRE_SIGNIN_VIEW&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;expensive&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;开启后，所有未登录用户访问 &lt;code&gt;/src&lt;/code&gt;、&lt;code&gt;/raw/&lt;/code&gt;、&lt;code&gt;/blame/&lt;/code&gt; 等高开销页面时会被重定向到登录页面。这非常非常有效，只需检测一下登录状态，就能让正常用户继续访问，起码可以clone下来仓库自己研究，而爬虫则会收到一个Unauthorized。&lt;/p&gt;
&lt;p&gt;直到爬虫（或者后面的人）找到了个口子：&lt;code&gt;/compare/&lt;/code&gt; 路径。不知为何这个路径没有被Gitea算作高开销，反而实际上开销比前三个更大。所以这个办法也宣告失败了。&lt;/p&gt;
&lt;h3 id=&#34;自己写一层gateway&#34;&gt;自己写一层gateway
&lt;/h3&gt;&lt;p&gt;Anubis也是gateway，不过自己写一个gateway可以做很多自由的事，甚至坏事。Gitea本身对外提供OAuth2接口，可以在gateway中判断是否登录，然后决定是否放行请求。还可以根据系统负载来动态决定是否对未登录用户进行更严格的限制。&lt;/p&gt;
&lt;p&gt;我有一个坏想法：Gitea的上述高开销端点都是根据模板渲染出来的，gateway也可以使用这些模板来伪造以假乱真的响应内容。与此同时，也有足够轻量的生成乱序假代码的逻辑。你可能猜到了我的目的：对爬虫进行投毒。只要做好足够的禁止爬虫声明，并在渲染出来的网页上显著标识“这是伪造内容”，大概便无需为此而自责，正常人应该都可以识别出来。&lt;/p&gt;
&lt;p&gt;只是写这样的gateway有点工作量，等开题结束再说吧。&lt;/p&gt;
&lt;h3 id=&#34;深层特征辨别&#34;&gt;深层特征辨别
&lt;/h3&gt;&lt;p&gt;TLS指纹也算是一种特征，这可能是一种可行的方向，但效率恐怕没有下面这种的高。&lt;/p&gt;
&lt;h3 id=&#34;验证cookie&#34;&gt;验证Cookie
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://fxgn.dev/blog/anubis/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;同样是揭露 Anubis 有效性的那篇博客&lt;/a&gt; 探讨了一种Caddy设置cookie的方法（具体请自己点进去看），我推测这是一个非常简单且有效的办法。Gitea对于每个初次访问者都会设置CSRF token cookie，而统计发现上述爬取时段内非首次访问的请求仅有0.41% 具有cookie；这证明了这些爬虫没有处理cookie的能力。&lt;/p&gt;
&lt;p&gt;这个博客提到的方法中，如果没有携带cookie，则仅能返回一个自动刷新的空页面；而携带了cookie的请求则会被正常转发到后端Gitea。这样一来，爬虫就只能拿到空页面了。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;未雨绸缪，好消息是我的博客是静态页面，爬也没用。坏消息是评论系统是动态的，而且开销还不低。不过也好搞，到时候把评论关了完事。&lt;/p&gt;
&lt;h2 id=&#34;meta连爬6天&#34;&gt;Meta连爬6天
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;怎么都挑我时间紧的时候打啊，上次是忙开题，这次又是忙找实习，我真没空陪你们闹了。&lt;/p&gt;
&lt;p&gt;感谢阿里巴巴公开免费的Qwen3.6-Plus，对于这些数据分析来说非常够用，又没有GPT-5.4那样的严重AI味。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最重量级的一集，&lt;code&gt;robots.txt&lt;/code&gt; 也不管，登录限制的endpoint遇到redirect也嗯爬，之前提到的 &lt;code&gt;/compare/&lt;/code&gt; 口子也嗯爬，6天爬了110万次请求。几点观察：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全无视 &lt;code&gt;robots.txt&lt;/code&gt;，作为落在通配符上的其他UA，仍然应爬尽爬。&lt;/li&gt;
&lt;li&gt;前几天的爬取主要落在 &lt;code&gt;src&lt;/code&gt;、&lt;code&gt;commits&lt;/code&gt;、&lt;code&gt;raw&lt;/code&gt;、&lt;code&gt;blame&lt;/code&gt;、&lt;code&gt;rss&lt;/code&gt; 等endpoint上，而最近几个小时才转移到 &lt;code&gt;compare&lt;/code&gt; 这个未拦截的端点。所以到第6天才被腾讯云告警发现，之前流量也没浪费多少。&lt;/li&gt;
&lt;li&gt;6天内也不是一直在爬，每天总有那么几个小时没有爬；但在爬取时段，基本维持在每秒3次左右的频率上。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;find&lt;/code&gt;、&lt;code&gt;releases&lt;/code&gt;、&lt;code&gt;actions&lt;/code&gt;、&lt;code&gt;commit&lt;/code&gt;、&lt;code&gt;activity&lt;/code&gt; 等endpoint也有所爬取，但并不随着commit变化，加之 &lt;code&gt;find&lt;/code&gt; 被验证登录了，所以频率也不高，加起来才几千次请求。&lt;/li&gt;
&lt;li&gt;几个高开销端点的commit hash均为真实存在，我就奇怪了，上述的endpoint都加了登录限制，compare爬得又晚，它到底是怎么知道commit hash的？而且有36%的请求是重复的，看样子还是不太死心。&lt;/li&gt;
&lt;li&gt;IP段比较集中，103个IPv6分布在2a03:2880:f810::/48下，101个IPv4分布在/24下，都是Meta自己的归属地西雅图的IP。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当然，也不是所有的bot都遵守了 &lt;code&gt;robots.txt&lt;/code&gt; 要求，但是这么久的请求中，根本不查询这些要求的，只有Meta一家别无分店。不同于ExternalFetcher，ExternalAgent并没有标明不遵守 &lt;code&gt;robots.txt&lt;/code&gt;。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;UA&lt;/th&gt;
&lt;th&gt;结论&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;meta-externalagent/1.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ &lt;strong&gt;从未查询，直接无视&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applebot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌ &lt;strong&gt;查了但照爬不误&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;DotBot/1.2 (Moz)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;完全遵守&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;YandexBot/3.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;完全遵守&lt;/strong&gt;（在允许名单内）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ClaudeBot/1.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;完全遵守&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;facebookexternalhit/1.1&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;完全遵守&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;bingbot/2.0&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;完全遵守&lt;/strong&gt;（在允许名单内）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;剩下的不必多言，大家请看图。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;block-scrapers/meta-crawl-distribution.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;分端点爬取次数随时间的分布&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;分端点爬取次数随时间的分布&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;话又说回来了，说这些我自己也没什么办法，不管是上面的阿里云还是各路IP池，还都是用黑手套的IP来爬取的，给雇主留点面子。直到这里明晃晃地使用了Meta自己的IP段、Meta自己的User-Agent，更是肆无忌惮，目前的时间也只能谴责而已。总之Meta是真的找不出数据训llama5了是吧，能爬我的代码爬得起劲那真是这辈子有了。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>在 Linux 上使用微软套件的最好办法，就是没有办法</title>
        <link>https://cyp0633.com/post/microsoft-suite-linux/</link>
        <pubDate>Wed, 05 Mar 2025 16:49:43 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/microsoft-suite-linux/</guid>
        <description>&lt;p&gt;大半年前，在工位的电脑上装了EndeavourOS，从此开始了无Windows的学习生活尝试。在Linux上打大部分游戏都有完善方案的现在，用Linux办公仍然是个难题，很神奇吧？拜微软所赐，Linux上现在还没有我习惯的原生版MS Office，更没有OneDrive和Office 365。&lt;/p&gt;
&lt;h2 id=&#34;wps-office又不是不能用&#34;&gt;WPS Office：又不是不能用
&lt;/h2&gt;&lt;p&gt;在Windows上，WPS Office就已经与MS Office（Microsoft 365）相爱相杀了二十多年；而在缺失MS Office的Linux原生办公方案中，WPS Office仍然是其中翘楚，比什么LibreOffice高到不知哪里去了。&lt;/p&gt;
&lt;p&gt;或许拜近些年的信创风所赐，需要称赞的是Linux上的WPS Office清爽无广告，该有的基本功能也都有。不出意外的话，这已经是原生Linux办公软件中体验最好的一个了。然而在一些小细节上，雷老板的产品仍然没打磨好：比如交叉引用功能，Word会自动提取文章中已有的标签和编号格式，而WPS文字就不会，不得不手动添加标签。&lt;/p&gt;
&lt;p&gt;OneDrive也是个麻烦：第三方的onedriver客户端经常丢认证掉挂载，只能重新打开开关，同时用WPS也没有增量同步和自动保存。&lt;/p&gt;
&lt;h2 id=&#34;office-online六边形战士但六边都不长&#34;&gt;Office Online：六边形战士，但六边都不长
&lt;/h2&gt;&lt;p&gt;微软原厂方案，OneDrive集成，在线编辑实时保存，不需要虚拟机或者转译，占用空间小，真有这种美事？有的兄弟有的，但这些话都只说了一半。只有最基础的功能，打开网页巨慢无比（挂了梯子），打的字时不时会被吃掉，字体都不能正常显示，操作比虚拟机还卡。套着微软的光环也不行，如果说WPS的同步和细节问题都可以克服一下，那么有以上任何一条都表示，Office Online基本是不可用的。&lt;/p&gt;
&lt;p&gt;我看大家也别笑金山文档、腾讯文档甚至Google Docs什么的，起码人家操作真流畅。&lt;/p&gt;
&lt;h2 id=&#34;虚拟机堕落的混乱邪恶派&#34;&gt;虚拟机：堕落的混乱邪恶派
&lt;/h2&gt;&lt;p&gt;虚拟机纯属无奈之举呀，毕竟要划走好几个核，以及数GB的内存；明明是为了躲避垃圾Windows才装的Linux，反过来又把Windows请回来了。但除此之外基本都是优点，全功能的Office，一般不出岔子的OneDrive，剩下的缺点基本只有与GNOME桌面环境格格不入了。&lt;/p&gt;
&lt;h2 id=&#34;winapps想法很美好但没有wayland&#34;&gt;WinApps：想法很美好，但没有Wayland
&lt;/h2&gt;&lt;p&gt;虚拟机的更进一步，加入了与桌面环境的深度集成，甚至可以在主机中注册文件扩展，听起来非常美好。但装了一半才发现没有Wayland显示协议，都5202年了真有人用X11吗。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;除了原生WPS和虚拟机以外都不及格。如果能忍虚拟机带来的额外开销，那么虚拟机是最好的；如果不能，我会选择WPS Office。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>记导出 Android 版 NTQQ 聊天记录</title>
        <link>https://cyp0633.com/post/android-qqnt-export/</link>
        <pubDate>Tue, 31 Dec 2024 16:46:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/android-qqnt-export/</guid>
        <description>&lt;p&gt;正值2024年的最后一天，群友突发奇想，该做群聊年终总结了。而众所周知，自从QQ全平台更新到了NT架构，原有的聊天记录导出方法就全都失效了。本文记录一下根据网上现有方案导出Android版NTQQ（版本9.1.5）聊天记录的过程。&lt;/p&gt;
&lt;p&gt;我准备了一台root过的小米15，以及一台Linux PC。&lt;/p&gt;
&lt;h2 id=&#34;导出数据库1&#34;&gt;导出数据库&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;
&lt;/h2&gt;&lt;p&gt;其实由于各平台使用了统一的NT架构进行核心的消息处理，各个平台导出的数据库大同小异，但获取密钥的方式差异比较大。PC版QQ需要使用IDA进行反编译调试，试了几次并没有成功，Android设备没有root的读者可以尝试使用PC版QQ的方法，在此不详述。而root后的Android手机可以通过adb shell运行 &lt;code&gt;su&lt;/code&gt; 切换为root用户，这样能够方便地进入QQ的私有目录浏览所需的文件。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;dada:/ $ su
dada:/ # whoami
root&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dada:/ $ su
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dada:/ &lt;span class=&#34;c1&#34;&gt;# whoami&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;密钥由 &lt;code&gt;uid&lt;/code&gt; 和 &lt;code&gt;rand&lt;/code&gt; 两个参数生成。其中 &lt;code&gt;uid&lt;/code&gt; 并不是用户的QQ号，而是形如 &lt;code&gt;u_xxxxxxx&lt;/code&gt; 的一串字符串；&lt;code&gt;rand&lt;/code&gt; 嵌在数据库文件中。&lt;/p&gt;
&lt;p&gt;首先获取 &lt;code&gt;uid&lt;/code&gt;。进入 &lt;code&gt;/data/data/com.tencent.mobileqq/files/uid/&lt;/code&gt; 目录，其中的文件名记录了QQ号和 &lt;code&gt;uid&lt;/code&gt; 的对应关系。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;dada:/ # ls -l /data/user/0/com.tencent.mobileqq/files/uid/                                                                              
total 0
-rw------- 1 u0_a327 u0_a327 0 2023-12-22 18:49 2660000000###u_U6vwQunVqPOUxxxxxxxxxx&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dada:/ &lt;span class=&#34;c1&#34;&gt;# ls -l /data/user/0/com.tencent.mobileqq/files/uid/                                                                              &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;total &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327 &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; 2023-12-22 18:49 2660000000###u_U6vwQunVqPOUxxxxxxxxxx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后获取数据库。这个时候强烈建议暂时关闭QQ的 &lt;strong&gt;自启动和后台运行权限&lt;/strong&gt;，以防QQ运行时修改数据库，从而影响校验和计算和比对。其数据库保存在 &lt;code&gt;/data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_&amp;lt;QQ_path_hash&amp;gt;/nt_msg.db&lt;/code&gt; 中，其中 &lt;code&gt;QQ_path_hash&lt;/code&gt; 可以在 &lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 页面顶部的小工具中计算得到。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;dada:/ # ls -lh /data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_5937760ce9717f9d58748067ce3a5e3b                                                            
total 3.5M
......
-rw------- 1 u0_a327 u0_a327 2.3G 2024-12-31 18:20 nt_msg.db
-rw------- 1 u0_a327 u0_a327  16K 2024-12-31 15:56 nt_msg.db-first.material
-rw------- 1 u0_a327 u0_a327  16K 2024-12-31 15:48 nt_msg.db-last.material
-rw------- 1 u0_a327 u0_a327  32K 2024-12-31 18:21 nt_msg.db-shm
-rw------- 1 u0_a327 u0_a327 499K 2024-12-31 18:21 nt_msg.db-wal
......&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dada:/ &lt;span class=&#34;c1&#34;&gt;# ls -lh /data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_5937760ce9717f9d58748067ce3a5e3b                                                            &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;total 3.5M
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;......
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327 2.3G 2024-12-31 18:20 nt_msg.db
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327  16K 2024-12-31 15:56 nt_msg.db-first.material
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327  16K 2024-12-31 15:48 nt_msg.db-last.material
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327  32K 2024-12-31 18:21 nt_msg.db-shm
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw------- &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; u0_a327 u0_a327 499K 2024-12-31 18:21 nt_msg.db-wal
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;......&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;先将数据库复制到一个普通用户可以获取的位置，然后使用 &lt;code&gt;adb pull&lt;/code&gt; 将其保存到电脑上：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;dada:/ # cp /data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_5937760ce9717f9d58748067ce3a5e3b/nt_msg.db /sdcard/

# 这之后都在本机 shell 中运行
$ adb pull sdcard/nt_msg.db ./
sdcard/nt_msg.db: 1 file pulled, 0 skipped. 171.7 MB/s (2487477248 bytes in 13.817s)&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dada:/ &lt;span class=&#34;c1&#34;&gt;# cp /data/user/0/com.tencent.mobileqq/databases/nt_db/nt_qq_5937760ce9717f9d58748067ce3a5e3b/nt_msg.db /sdcard/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 这之后都在本机 shell 中运行&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ adb pull sdcard/nt_msg.db ./
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sdcard/nt_msg.db: &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; file pulled, &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; skipped. 171.7 MB/s &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2487477248&lt;/span&gt; bytes in 13.817s&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;提取字符串后，建议在手机和PC上分别计算校验和，确保数据完整性。 &lt;code&gt;rand&lt;/code&gt; 字段在数据库二进制文件的 &lt;code&gt;QQ_NT&lt;/code&gt; 字段附近。使用 &lt;code&gt;strings&lt;/code&gt; 提取数据库中的可读字符串，然后使用 &lt;code&gt;grep&lt;/code&gt; 将其找出，或使用其他类似工具读取二进制文件：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;$ strings nt_msg.db | grep --context 3 &amp;#34;QQ_NT&amp;#34;
SQLite header 3
QQ_NT DB
Z68aUxXX
1.0.0.1&amp;#34; HMAC_SHA1
\[`-&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ strings nt_msg.db &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; grep --context &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;QQ_NT&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SQLite header &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;QQ_NT DB
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Z68aUxXX
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1.0.0.1&lt;span class=&#34;s2&#34;&gt;&amp;#34; HMAC_SHA1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;\[`-&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;由上述信息，得到 &lt;code&gt;rand&lt;/code&gt; 字符串为 &lt;code&gt;Z68aUxXX&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;解密数据库2&#34;&gt;解密数据库&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;
&lt;/h2&gt;&lt;p&gt;先计算数据库口令，在 &lt;sup id=&#34;fnref2:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; 顶部的小工具中可以计算。看起来腾讯在数据库的头上加了些元数据，先把它截掉：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;tail -c &amp;#43;1025 nt_msg.db &amp;gt; nt_msg.clean.db&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tail -c +1025 nt_msg.db &amp;gt; nt_msg.clean.db&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;之后用sqlcipher打开，输入以下内容，将你的口令替换进去，尝试解密：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;$ sqlcipher nt_msg.clean.db
SQLite version 3.45.3 2024-04-15 13:34:05 (SQLCipher 4.6.0 community)
Enter &amp;#34;.help&amp;#34; for usage hints.
sqlite&amp;gt; PRAGMA key = &amp;#39;&amp;lt;your-key&amp;gt;&amp;#39;;
PRAGMA kdf_iter = 4000;
PRAGMA cipher_hmac_algorithm = HMAC_SHA1;
ok
sqlite&amp;gt; SELECT name FROM sqlite_master WHERE type=&amp;#39;table&amp;#39;;
c2c_msg_table
c2c_msg_flow_table
group_msg_table
group_msg_flow_table
c2c_temp_msg_table
c2c_temp_msg_flow_table
......&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ sqlcipher nt_msg.clean.db
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;SQLite version 3.45.3 2024-04-15 13:34:05 &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;SQLCipher 4.6.0 community&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Enter &lt;span class=&#34;s2&#34;&gt;&amp;#34;.help&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; usage hints.
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite&amp;gt; PRAGMA &lt;span class=&#34;nv&#34;&gt;key&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;lt;your-key&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PRAGMA &lt;span class=&#34;nv&#34;&gt;kdf_iter&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; 4000&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PRAGMA &lt;span class=&#34;nv&#34;&gt;cipher_hmac_algorithm&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; HMAC_SHA1&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ok
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite&amp;gt; SELECT name FROM sqlite_master WHERE &lt;span class=&#34;nv&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;table&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c2c_msg_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c2c_msg_flow_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;group_msg_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;group_msg_flow_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c2c_temp_msg_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;c2c_temp_msg_flow_table
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;......&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果能像上面这样看到表名，那么到这一步都是正确的。解密时，若按照 &lt;sup id=&#34;fnref1:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 中的教程操作可能出现“database disk image is malformed”，这可能并没有出问题。这时候可以先dump下来，然后再导入未加密的SQLite数据库&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;sqlite&amp;gt; .output nt_msg.sql
sqlite&amp;gt; .dump
sqlite&amp;gt; .exit
$ cat nt_msg.sql | sed -e &amp;#39;s|^ROLLBACK;\( -- due to errors\)*$|COMMIT;|g&amp;#39; | sqlite3 nt_msg.decrypt.db&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite&amp;gt; .output nt_msg.sql
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite&amp;gt; .dump
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sqlite&amp;gt; .exit
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ cat nt_msg.sql &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sed -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;s|^ROLLBACK;\( -- due to errors\)*$|COMMIT;|g&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sqlite3 nt_msg.decrypt.db&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;现在得到的 &lt;code&gt;nt_msg.decrypt.db&lt;/code&gt; 就是解密后的数据库了，可以直接打开查看。&lt;/p&gt;
&lt;h2 id=&#34;导出聊天记录&#34;&gt;导出聊天记录
&lt;/h2&gt;&lt;p&gt;数据库的schema很抽象，其中一列甚至是二进制。好在网络上已经有了数据库字段含义 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; 和二进制Protobuf payload定义&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;，对于提取文字消息而言是非常够用的。&lt;/p&gt;
&lt;p&gt;首先将该链接内的Protobuf定义编译为Python类：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-8&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-8&#34; style=&#34;display:none;&#34;&gt;protoc --python_out=. message.proto&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;protoc --python_out&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;. message.proto&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;我让Claude帮我写了一份代码，用于把特定群组的文字消息导出为JSON，包含发送方和发送时间，效果还行，搭配上述Python类食用即可，可以选择发送时间：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;python&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-9&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-9&#34; style=&#34;display:none;&#34;&gt;import sqlite3
import base64
import json
from datetime import datetime
import argparse
from message_pb2 import Message

def timestamp_to_datetime(timestamp):
    &amp;#34;&amp;#34;&amp;#34;将时间戳转换为可读的日期时间格式&amp;#34;&amp;#34;&amp;#34;
    return datetime.fromtimestamp(timestamp).strftime(&amp;#39;%Y-%m-%d %H:%M:%S&amp;#39;)

def decode_message(blob_content):
    &amp;#34;&amp;#34;&amp;#34;解码BLOB数据并解析protobuf消息&amp;#34;&amp;#34;&amp;#34;
    try:
        message = Message()
        message.ParseFromString(blob_content)
        return message
    except Exception as e:
        print(f&amp;#34;Error decoding message: {e}&amp;#34;)
        return None


def extract_text_messages(message):
    &amp;#34;&amp;#34;&amp;#34;从消息中提取文字内容&amp;#34;&amp;#34;&amp;#34;
    messages = []
    for single_msg in message.messages:
        if single_msg.messageType == 1:  # 文字消息
            print(&amp;#34;Debug info for message:&amp;#34;)
            print(f&amp;#34;Raw sendTimestamp: {single_msg.sendTimestamp}&amp;#34;)
            print(f&amp;#34;Raw senderUid: {single_msg.senderUid}&amp;#34;)
            print(f&amp;#34;Raw messageText: {single_msg.messageText}&amp;#34;)
            print(&amp;#34;Message full content:&amp;#34;)
            print(single_msg)
            print(&amp;#34;------------------------&amp;#34;)
            
            messages.append({
                &amp;#39;time&amp;#39;: timestamp_to_datetime(single_msg.sendTimestamp),
                &amp;#39;sender_id&amp;#39;: single_msg.senderUid,
                &amp;#39;content&amp;#39;: single_msg.messageText
            })
    return messages


def fetch_messages(db_path, group_id, start_time=None, end_time=None):
    &amp;#34;&amp;#34;&amp;#34;从数据库中获取消息&amp;#34;&amp;#34;&amp;#34;
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    query = &amp;#39;SELECT &amp;#34;40050&amp;#34;, &amp;#34;40033&amp;#34;, &amp;#34;40800&amp;#34; FROM group_msg_table WHERE &amp;#34;40027&amp;#34; = ?&amp;#39;
    params = [group_id]
    
    if start_time:
        query &amp;#43;= &amp;#39; AND &amp;#34;40050&amp;#34; &amp;gt;= ?&amp;#39;
        params.append(start_time)
    if end_time:
        query &amp;#43;= &amp;#39; AND &amp;#34;40050&amp;#34; &amp;lt;= ?&amp;#39;
        params.append(end_time)
    
    query &amp;#43;= &amp;#39; ORDER BY &amp;#34;40050&amp;#34; ASC&amp;#39;
    
    try:
        cursor.execute(query, params)
        results = cursor.fetchall()
        
        all_messages = []
        for timestamp, sender_id, content in results:
            if content:  # 确保内容不为空
                message = decode_message(content)
                if message:
                    # 从protobuf中只提取消息文本
                    for single_msg in message.messages:
                        if single_msg.messageType == 1:  # 文字消息
                            all_messages.append({
                                &amp;#39;timestamp&amp;#39;: timestamp_to_datetime(timestamp),
                                &amp;#39;sender_id&amp;#39;: sender_id,
                                &amp;#39;content&amp;#39;: single_msg.messageText
                           python extract.py --help                                                                                                                    ✔  20:21:06   
usage: extract.py [-h] [--start START] [--end END] [--output OUTPUT] db_path group_id

Extract QQ group chat messages

positional arguments:
  db_path          Path to the SQLite database file
  group_id         Group ID to extract messages from

options:
  -h, --help       show this help message and exit
  --start START    Start timestamp (optional)
  --end END        End timestamp (optional)
  --output OUTPUT  Output JSON file path (optional)

        conn.close()


def main():
    parser = argparse.ArgumentParser(description=&amp;#39;Extract QQ group chat messages&amp;#39;)
    parser.add_argument(&amp;#39;db_path&amp;#39;, help=&amp;#39;Path to the SQLite database file&amp;#39;)
    parser.add_argument(&amp;#39;group_id&amp;#39;, type=int, help=&amp;#39;Group ID to extract messages from&amp;#39;)
    parser.add_argument(&amp;#39;--start&amp;#39;, type=int, help=&amp;#39;Start timestamp (optional)&amp;#39;)
    parser.add_argument(&amp;#39;--end&amp;#39;, type=int, help=&amp;#39;End timestamp (optional)&amp;#39;)
    parser.add_argument(&amp;#39;--output&amp;#39;, help=&amp;#39;Output JSON file path (optional)&amp;#39;)
    
    args = parser.parse_args()
    
    messages = fetch_messages(args.db_path, args.group_id, args.start, args.end)
    
    # 将结果转换为JSON
    output = {
        &amp;#39;group_id&amp;#39;: args.group_id,
        &amp;#39;messages&amp;#39;: messages
    }
    
    # 输出结果
    if args.output:
        with open(args.output, &amp;#39;w&amp;#39;, encoding=&amp;#39;utf-8&amp;#39;) as f:
            json.dump(output, f, ensure_ascii=False, indent=2)
    else:
        print(json.dumps(output, ensure_ascii=False, indent=2))

if __name__ == &amp;#34;__main__&amp;#34;:
    main()&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;  1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;  9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 57
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 58
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 59
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 60
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 61
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 62
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 63
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 64
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 65
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 66
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 67
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 68
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 69
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 70
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 71
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 72
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 73
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 74
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 75
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 76
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 77
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 78
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 79
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 80
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 81
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 82
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 83
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 84
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 85
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 86
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 87
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 88
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 89
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 90
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 91
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 92
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 93
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 94
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 95
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 96
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 97
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 98
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 99
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;100
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;101
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;102
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;103
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;104
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;105
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;106
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;107
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;108
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;109
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;110
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;111
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;112
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;113
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;114
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;115
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;116
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;117
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;118
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;119
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;120
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;121
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;sqlite3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;base64&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;json&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;argparse&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;message_pb2&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;timestamp_to_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;将时间戳转换为可读的日期时间格式&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fromtimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;strftime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;%Y-%m-&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;%d&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt; %H:%M:%S&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;decode_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;blob_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;解码BLOB数据并解析protobuf消息&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ParseFromString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;blob_content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;except&lt;/span&gt; &lt;span class=&#34;ne&#34;&gt;Exception&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Error decoding message: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;e&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;extract_text_messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;从消息中提取文字内容&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 文字消息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Debug info for message:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Raw sendTimestamp: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sendTimestamp&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Raw senderUid: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;senderUid&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Raw messageText: &lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageText&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Message full content:&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;------------------------&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s1&#34;&gt;&amp;#39;time&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timestamp_to_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;sendTimestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s1&#34;&gt;&amp;#39;sender_id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;senderUid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s1&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageText&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;fetch_messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;从数据库中获取消息&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sqlite3&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;SELECT &amp;#34;40050&amp;#34;, &amp;#34;40033&amp;#34;, &amp;#34;40800&amp;#34; FROM group_msg_table WHERE &amp;#34;40027&amp;#34; = ?&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39; AND &amp;#34;40050&amp;#34; &amp;gt;= ?&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39; AND &amp;#34;40050&amp;#34; &amp;lt;= ?&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;query&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39; ORDER BY &amp;#34;40050&amp;#34; ASC&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;results&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;cursor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fetchall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;all_messages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sender_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;results&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 确保内容不为空&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;decode_message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;c1&#34;&gt;# 从protobuf中只提取消息文本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageType&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# 文字消息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                            &lt;span class=&#34;n&#34;&gt;all_messages&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &lt;span class=&#34;s1&#34;&gt;&amp;#39;timestamp&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timestamp_to_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &lt;span class=&#34;s1&#34;&gt;&amp;#39;sender_id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sender_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                                &lt;span class=&#34;s1&#34;&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;single_msg&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;messageText&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                           &lt;span class=&#34;n&#34;&gt;python&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;extract&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;py&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;                                                                                                                   &lt;span class=&#34;err&#34;&gt;&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;✔&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;20&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;06&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;&lt;/span&gt;  
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;usage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;extract&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;py&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;START&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OUTPUT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db_path&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Extract&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;QQ&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;group&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;chat&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;positional&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;arguments&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;db_path&lt;/span&gt;          &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;the&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SQLite&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;database&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;         &lt;span class=&#34;n&#34;&gt;Group&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ID&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;extract&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nn&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;h&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;       &lt;span class=&#34;n&#34;&gt;show&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;this&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;START&lt;/span&gt;    &lt;span class=&#34;n&#34;&gt;Start&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;END&lt;/span&gt;        &lt;span class=&#34;n&#34;&gt;End&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;timestamp&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;o&#34;&gt;--&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;OUTPUT&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;Output&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;JSON&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;optional&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;conn&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;close&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;argparse&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ArgumentParser&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Extract QQ group chat messages&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;db_path&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Path to the SQLite database file&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;group_id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Group ID to extract messages from&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;--start&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Start timestamp (optional)&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;--end&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;End timestamp (optional)&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_argument&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;--output&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;help&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Output JSON file path (optional)&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parser&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;parse_args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fetch_messages&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;db_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 将结果转换为JSON&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;output&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s1&#34;&gt;&amp;#39;group_id&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s1&#34;&gt;&amp;#39;messages&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;messages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# 输出结果&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;args&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;encoding&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dump&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dumps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;output&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ensure_ascii&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;False&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;indent&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;用法：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-10&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-10&#34; style=&#34;display:none;&#34;&gt;$ python extract.py --help
usage: extract.py [-h] [--start START] [--end END] [--output OUTPUT] db_path group_id

Extract QQ group chat messages

positional arguments:
  db_path          Path to the SQLite database file
  group_id         Group ID to extract messages from

options:
  -h, --help       show this help message and exit
  --start START    Start timestamp (optional)
  --end END        End timestamp (optional)
  --output OUTPUT  Output JSON file path (optional)&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ python extract.py --help
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;usage: extract.py &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;-h&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--start START&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--end END&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;--output OUTPUT&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt; db_path group_id
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Extract QQ group chat messages
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;positional arguments:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  db_path          Path to the SQLite database file
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  group_id         Group ID to extract messages from
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;options:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  -h, --help       show this &lt;span class=&#34;nb&#34;&gt;help&lt;/span&gt; message and &lt;span class=&#34;nb&#34;&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --start START    Start timestamp &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;optional&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --end END        End timestamp &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;optional&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  --output OUTPUT  Output JSON file path &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;optional&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;最后祝各位新年快乐！&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://qq.sbcnm.top/decrypt/NTQQ%20%28Android%29.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://qq.sbcnm.top/decrypt/NTQQ%20(Android).html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref2:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://qq.sbcnm.top/decrypt/NTQQ%20%E8%A7%A3%E5%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://qq.sbcnm.top/decrypt/NTQQ%20%E8%A7%A3%E5%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93.html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/QQBackup/QQDecrypt/blob/2b02dc97894ff0a811240b7f1647f39ab17f78cf/docs/decrypt/NTQQ%20%28Windows%29.md?plain=1#L154&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/QQBackup/QQDecrypt/blob/2b02dc97894ff0a811240b7f1647f39ab17f78cf/docs/decrypt/NTQQ%20(Windows).md?plain=1#L154&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mobyw/GroupChatAnnualReport?tab=readme-ov-file#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AD%97%E6%AE%B5%E5%90%AB%E4%B9%89&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/mobyw/GroupChatAnnualReport?tab=readme-ov-file#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AD%97%E6%AE%B5%E5%90%AB%E4%B9%89&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/QQBackup/qq-win-db-key/issues/38#issuecomment-2294619828&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/QQBackup/qq-win-db-key/issues/38#issuecomment-2294619828&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>RivaTuner Statistics Server 游戏悬浮窗入门</title>
        <link>https://cyp0633.com/post/rtss-overlay/</link>
        <pubDate>Mon, 22 Jul 2024 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/rtss-overlay/</guid>
        <description>&lt;p&gt;RivaTuner Statistics Server（下称RTSS）能够根据用户设定的悬浮窗样式，在特定应用/游戏中显示实时性能数据。它并不像游戏加加等程序一样是个开箱即用的工具，因此仍然需要进行一些摸索。&lt;/p&gt;
&lt;h2 id=&#34;初始设置&#34;&gt;初始设置
&lt;/h2&gt;&lt;p&gt;安装环节在此略过，本文需要RTSS和HWiNFO64。&lt;/p&gt;
&lt;p&gt;打开RTSS后，如果出现&amp;quot;xxx cannot be hooked right now&amp;quot;，可以暂时忽视。打开主界面后，需要先把 &amp;ldquo;Show OSD&amp;rdquo; 和 &amp;ldquo;OSD support&amp;rdquo; 两个开关打开。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;rtss-overlay/rtss-interface.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;RTSS 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;RTSS 主界面&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;导入现有悬浮窗样式&#34;&gt;导入现有悬浮窗样式
&lt;/h2&gt;&lt;p&gt;现在打开游戏并不会显示任何悬浮窗，因为并没有自定义样式。为了方便，可以先从网上下一个，比如 &lt;a class=&#34;link&#34; href=&#34;https://github.com/lscambo13/ElegantMustard/releases/tag/v4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个&lt;/a&gt;，或是其他的ovx文件。&lt;/p&gt;
&lt;p&gt;在RTSS主界面点击 &lt;strong&gt;Setup&lt;/strong&gt;，找到 &lt;strong&gt;Plugins&lt;/strong&gt;，将 &lt;strong&gt;OverlayEditor&lt;/strong&gt; 的勾勾上，然后双击它，就进入了编辑悬浮窗样式的界面。&lt;/p&gt;
&lt;p&gt;点击左上角的 &lt;strong&gt;Layouts&lt;/strong&gt;，点击 &lt;strong&gt;Import&lt;/strong&gt;，选择刚刚下载的ovx，你下载的样式就被导入进来了。然后保存即可。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;rtss-overlay/overlay-editor.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;悬浮窗编辑器&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;悬浮窗编辑器&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;悬浮窗编辑器上已经显示了样式预览，你也可以打开游戏试一试。当前买家秀和卖家秀基本差不多，但似乎部分数据是空的，比如CPU温度、频率和功耗等。可能因硬件而异，仅供参考。&lt;/p&gt;
&lt;h2 id=&#34;添加并替换hwinfo64数据源&#34;&gt;添加并替换HWiNFO64数据源
&lt;/h2&gt;&lt;p&gt;上述的数据源均是来自于RTSS自己的测量，因此对新硬件的支持可能较差。可以从HWiNFO64中获取硬件数据，更准确，数据也更多。&lt;/p&gt;
&lt;p&gt;先打开HWiNFO64，在启动画面上可勾选 &lt;strong&gt;“仅传感器”（Sensors Only）&lt;/strong&gt;，然后点击设置，勾选 &lt;strong&gt;“共享内存支持”（Shared Memory Support）&lt;/strong&gt; &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，以允许RTSS读取数据。然后，启动HWiNFO64。&lt;/p&gt;
&lt;p&gt;回到上图中的悬浮窗编辑器，点击 &lt;strong&gt;Data sources&lt;/strong&gt;，点击 &lt;strong&gt;Edit&lt;/strong&gt;，即可进入数据源列表窗口。它们名称前的图标代指的是来源应用程序，如小飞机就是Afterburner，因为我没开（也不必开）所以全部显示N/A。&lt;/p&gt;
&lt;p&gt;在数据源列表下方点击 &lt;strong&gt;Add&lt;/strong&gt;，添加新的数据源。Data provider选择HWiNFO64，然后选择上面缺失的CPU温度（CPU Package）和功耗（CPU Package Power）点击OK，这样就导入了两个缺失的数据源。&lt;/p&gt;
&lt;p&gt;找到上面显示N/A的缺失数据源中对应CPU温度和功耗的名称（CPU power和CPU temperature），分别双击上面添加的CPU Package和CPU Package Power打开编辑窗口，在 &lt;strong&gt;Overlay data source properties&lt;/strong&gt; 里改为上面对应的名字，这样RTSS就会认为是不同的数据源提供的同一个数据。&lt;/p&gt;
&lt;p&gt;点击OK，CPU温度和功耗应该都正常显示了。但还有一个CPU频率上文故意没有添加，可能是因为该CPU中有两种不同规模的核心，所以一起统计频率是不合适的。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;rtss-overlay/add-data-source.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;添加数据源&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;添加数据源&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;使用hwinfo64自定义传感器设计数据源&#34;&gt;使用HWiNFO64自定义传感器设计数据源
&lt;/h2&gt;&lt;p&gt;本章的目标是自定义一个数据源，从而在HWiNFO64和RTSS中分别显示P核和E核的平均频率。RTSS本身并不支持通过运算得到新的数据源，所以需要在HWiNFO64中定义。当然也可以通过简单的算术运算，得到其他的结果。在此之前建议将HWiNFO64的语言设为英语&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;自定义传感器需要编辑注册表，虽然我也不知道为什么非要这么做。以如下文件为例，该文件新建了一个叫做CoreUltraExtended的传感器，有Avg P-core Clock和Avg E-core Clock两个频率传感器指标，分别将平均P-core频率和平均E-core频率求和然后求平均。&lt;/p&gt;
&lt;p&gt;如果你也使用酷睿Ultra 7 155H，可以将下面内容另存为 &lt;code&gt;.reg&lt;/code&gt; 格式，直接导入；其他操作可以参考 &lt;a class=&#34;link&#34; href=&#34;https://www.hwinfo.com/forum/threads/custom-user-sensors-in-hwinfo.5817/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;教程&lt;/a&gt;，对照下列步骤操作，还是看不懂的话可以让GPT解释。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;reg&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended]

[HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended\Clock0]
&amp;#34;Name&amp;#34;=&amp;#34;Avg P-core Clock&amp;#34;
&amp;#34;Value&amp;#34;=&amp;#34;\&amp;#34;P-core 8 Clock\&amp;#34; &amp;#43; \&amp;#34;P-core 9 Clock\&amp;#34; &amp;#43; \&amp;#34;P-core 10 Clock\&amp;#34; &amp;#43; \&amp;#34;P-core 11 Clock\&amp;#34; &amp;#43; \&amp;#34;P-core 12 Clock\&amp;#34; &amp;#43; \&amp;#34;P-core 13 Clock\&amp;#34; / 6&amp;#34;

[HKEY_CURRENT_USER\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended\Clock1]
&amp;#34;Name&amp;#34;=&amp;#34;Avg E-core Clock&amp;#34;
&amp;#34;Value&amp;#34;=&amp;#34;\&amp;#34;E-core 0 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 1 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 2 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 3 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 4 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 5 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 6 Clock\&amp;#34; &amp;#43; \&amp;#34;E-core 7 Clock\&amp;#34; &amp;#43;  / 8&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-reg&#34; data-lang=&#34;reg&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Windows Registry Editor Version 5.00
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended\Clock0]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Avg P-core Clock&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;P-core 8 Clock\&amp;#34; + \&amp;#34;P-core 9 Clock\&amp;#34; + \&amp;#34;P-core 10 Clock\&amp;#34; + \&amp;#34;P-core 11 Clock\&amp;#34; + \&amp;#34;P-core 12 Clock\&amp;#34; + \&amp;#34;P-core 13 Clock\&amp;#34; / 6&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;HKEY_CURRENT_USER&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;\Software\HWiNFO64\Sensors\Custom\CoreUltraExtended\Clock1]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Avg E-core Clock&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;&amp;#34;Value&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;\&amp;#34;E-core 0 Clock\&amp;#34; + \&amp;#34;E-core 1 Clock\&amp;#34; + \&amp;#34;E-core 2 Clock\&amp;#34; + \&amp;#34;E-core 3 Clock\&amp;#34; + \&amp;#34;E-core 4 Clock\&amp;#34; + \&amp;#34;E-core 5 Clock\&amp;#34; + \&amp;#34;E-core 6 Clock\&amp;#34; + \&amp;#34;E-core 7 Clock\&amp;#34; +  / 8&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;编辑完成后，注册表大概是这个样子。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;rtss-overlay/regedit.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;注册表预览&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;注册表预览&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;现在打开HWiNFO64传感器界面，应该有了新的选项；进入刚刚的添加数据源处，应该也可以看到了。把上述新增的数据源添加进来，不用改名。&lt;/p&gt;
&lt;p&gt;悬浮窗里每个数据，对应的都是一个层（layer）双击悬浮窗编辑器里那个空的CPU频率显示（MHz），进入层属性界面。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;rtss-overlay/layer-properies.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;层属性界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;层属性界面&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hypertext&lt;/strong&gt; 一栏中为该层的格式化文本，其中两个百分号包裹着的是数据源的名称，换行使用 &lt;code&gt;\n&lt;/code&gt; 转义。通过改为上图的文本，可以实现两种核心频率的分别显示。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;该选项标注的12小时限制并非12小时后必须重新开启一次，事实上重新打开HWiNFO64时会自动重启计时。但是如果HWiNFO64一直开着，那么RTSS会在12小时后自动断开连接。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;这是一个可能的bug，调整语言后可能无法获取值： &lt;a class=&#34;link&#34; href=&#34;https://www.hwinfo.com/forum/threads/custom-user-sensors-in-hwinfo.5817/post-46045&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.hwinfo.com/forum/threads/custom-user-sensors-in-hwinfo.5817/post-46045&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>安装 Arch Linux 「未曾设想的道路」</title>
        <link>https://cyp0633.com/post/install-arch-endeavour/</link>
        <pubDate>Thu, 02 May 2024 10:06:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/install-arch-endeavour/</guid>
        <description>&lt;p&gt;TL;DR：使用EndeavourOS的LiveCD可以与官方ISO一样安装Arch Linux，还能享受Gparted、浏览器、文字编辑器等图形界面软件的便利。&lt;/p&gt;
&lt;p&gt;在数次尝试中，使用Arch Linux官方LiveCD的tty界面安装系统总是令我感觉十分不便，或许我还是需要一个带图形界面的安装器，但又不愿意抛弃命令行安装方法。然而，虽然Arch Linux并没有提供图形化LiveCD，但是与其共享同一个软件库的EndeavourOS有啊！LiveCD里带的工具也算比较全乎。&lt;/p&gt;
&lt;p&gt;理论存在，开始实践。&lt;/p&gt;
&lt;h2 id=&#34;分区&#34;&gt;分区
&lt;/h2&gt;&lt;p&gt;分区反倒是我觉得最困难的。&lt;/p&gt;
&lt;p&gt;这一步要先考虑好将内核镜像装到EFI分区还是系统分区 /boot里面（对应 &lt;a class=&#34;link&#34; href=&#34;https://wiki.archlinuxcn.org/wiki/EFI_%E7%B3%BB%E7%BB%9F%E5%88%86%E5%8C%BA#%E5%85%B8%E5%9E%8B%E6%8C%82%E8%BD%BD%E7%82%B9&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EFI 分区的挂载点&lt;/a&gt;）。前者会多花至少100MB空间，但不管怎么样，都应该先保证EFI分区空间足够。联想给了一个仅260MB的EFI分区（/dev/nvme1n1p1），而且后面跟着的就是MSR和Windows系统分区，不敢动，所以选择后者，又不是不能用.jpg。&lt;/p&gt;
&lt;p&gt;然后可以先将Arch的系统分区分出来了。我分了一个Btrfs分区（/dev/nvme0n1p2），有两个子卷 @ 和 @home，分别挂载到 / 和 /home。分区操作很容易使用Gparted搞定，然后在终端中输入：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;sh&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;sudo btrfs subvolume create /mnt/@
sudo btrfs subvolume create /mnt/@home
sudo umount -R /mnt
sudo mount -o subvol=@ /dev/nvme1n1p2 /mnt
sudo mount --mkdir -o subvol=@home /dev/nvme1n1p2 /mnt/home
sudo mount /dev/nvme1n1p1 /mnt/efi&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo btrfs subvolume create /mnt/@
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo btrfs subvolume create /mnt/@home
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo umount -R /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo mount -o &lt;span class=&#34;nv&#34;&gt;subvol&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;@ /dev/nvme1n1p2 /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo mount --mkdir -o &lt;span class=&#34;nv&#34;&gt;subvol&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;@home /dev/nvme1n1p2 /mnt/home
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo mount /dev/nvme1n1p1 /mnt/efi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这时候带一个桌面环境的LiveCD的优势又体现出来了：可以一边用Gparted看分区，一边在终端里操作。&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装
&lt;/h2&gt;&lt;p&gt;然后就是正常的安装流程了。换完源之后进入root账户，然后：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;sh&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;pacstrap -K /mnt base linux linux-firmware nano intel-ucode btrfs-progs networkmanager iwd man-db man-pages # 每人需要的包不同
genfstab -U /mnt &amp;gt;&amp;gt; /mnt/etc/fstab&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pacstrap -K /mnt base linux linux-firmware nano intel-ucode btrfs-progs networkmanager iwd man-db man-pages &lt;span class=&#34;c1&#34;&gt;# 每人需要的包不同&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;genfstab -U /mnt &amp;gt;&amp;gt; /mnt/etc/fstab&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;建议在生成完fstab之后检查一下，确定btrfs的子卷挂载点是对的。然后就是chroot进入新系统，设置时区和硬件时间：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;sh&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;arch-chroot /mnt
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
hwclock --systohc&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;arch-chroot /mnt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hwclock --systohc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;以及本地化、主机名、密码等等，参考Arch Wiki就行了，不要忘了。也可以先enable一下NetworkManager和iwd的service。&lt;/p&gt;
&lt;p&gt;然后是引导器，我使用rEFInd，先按照Wiki中的步骤安装即可，会自动添加Btrfs驱动。注意其chroot环境下会添加LiveCD的分区信息（而非新系统的），所以不如全图图掉，从 &lt;a class=&#34;link&#34; href=&#34;https://wiki.archlinuxcn.org/wiki/REFInd#refind_linux.conf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Arch Wiki 示例&lt;/a&gt;上换个新的 &lt;code&gt;/boot/refind_linux.conf&lt;/code&gt;（chroot路径），以下配置已加入Btrfs子卷配置。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plaintext&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;&amp;#34;Boot using default options&amp;#34;     &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v.img&amp;#34;
&amp;#34;Boot using fallback initramfs&amp;#34;  &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v-fallback.img&amp;#34;
&amp;#34;Boot to terminal&amp;#34;               &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v.img systemd.unit=multi-user.target&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;Boot using default options&amp;#34;     &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v.img&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;Boot using fallback initramfs&amp;#34;  &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v-fallback.img&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&amp;#34;Boot to terminal&amp;#34;               &amp;#34;root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw rootflags=subvol=@ add_efi_memmap initrd=@\boot\intel-ucode.img initrd=@\boot\amd-ucode.img initrd=@\boot\initramfs-%v.img systemd.unit=multi-user.target&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这时候图形界面的另一个优点就体现出来了，可以直接从Arch Wiki里方便地复制内容。这里的PARTUUID可以用 &lt;code&gt;blkid&lt;/code&gt; 查看，输入Btrfs分区的UUID即可（子卷的你也找不到啊）。另外不要忘了针对性地更改 &lt;code&gt;/efi/EFI/refind/refind.conf&lt;/code&gt;（chroot路径），以检测Arch Linux initramfs和Btrfs子卷。&lt;/p&gt;
&lt;p&gt;确定步骤都正确走完了的话，就可以重启了。rEFInd会自动把自己设为默认的。&lt;/p&gt;
&lt;h2 id=&#34;后续工作&#34;&gt;后续工作
&lt;/h2&gt;&lt;p&gt;重新启动后当然是tty了，用NetworkManager连上网之后，就可以装些别的了。我装了这些：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;sh&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;sudo pacman -S gnome sudo vi adobe-source-han-sans-otc-fonts&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo pacman -S gnome sudo vi adobe-source-han-sans-otc-fonts&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;仅供参考，有需要的自己装就行。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>和「LSP」一起写代码：VS Code &#43; Clangd 编写 C/C&#43;&#43;</title>
        <link>https://cyp0633.com/post/cpp-vscode-clangd/</link>
        <pubDate>Tue, 27 Feb 2024 23:19:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/cpp-vscode-clangd/</guid>
        <description>&lt;p&gt;微软出品的VS Code官方C/C++ 插件当然很好，似乎在C/C++ 用户中也是用得较为广泛的，调试功能很好用。然而在稍大一点的项目中，有时会出现找不到代码索引的问题，以及代码补全、提示不够智能等，在一定程度上Clangd就能够解决这个问题。&lt;/p&gt;
&lt;p&gt;Clangd是LLVM社区的一个项目，是一个基于 &lt;del&gt;LSP&lt;/del&gt; Language Server Protocol的C/C++ 语言服务器（类似于rust-analyzer、gopls等），与编辑器插件和其他工具结合使用，能够提供错误提示、代码补全、重构、语法高亮等功能。&lt;/p&gt;
&lt;h2 id=&#34;对比&#34;&gt;对比
&lt;/h2&gt;&lt;p&gt;以下部分选取之前的课程实验uCore代码，对Clangd 15.0.0和微软C/C++ 插件的对应部分功能进行比较。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-1-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Clangd：能够正确找到符号定义对应的源文件，提示较多&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Clangd：能够正确找到符号对应的源文件&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-1-2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;C/C&amp;#43;&amp;#43;：未找到符号定义，仅有返回值提示&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;C/C++：未找到符号定义 ，仅有返回值提示&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-2-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Clangd：有较完整的补全列表&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Clangd：有较完整的补全列表&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-2-2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;C/C&amp;#43;&amp;#43;：无法补全&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;C/C++：无法补全&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-3-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Clangd：识别到格式错误，并提供修改建议&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Clangd：识别到格式错误，并提供修改建议&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cpp-vscode-clangd/comparison-3-2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;C/C&amp;#43;&amp;#43;：未识别到格式错误&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;C/C++：未识别到格式错误&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;注：C/C++ 插件也能够读取 &lt;code&gt;compile_commands.json&lt;/code&gt;，但索引很慢，且对于JSON中没有覆盖到的源文件，并不能推测符号位置，并不是完全不能找到定义。然而即使找到，提示功能也逊于Clangd。&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装
&lt;/h2&gt;&lt;p&gt;首先你需要安装Clang，macOS的Xcode命令行工具自带，Linux可以通过包管理器安装（也可以只安装clang-tools），Windows则可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/mstorsjo/llvm-mingw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;llvm-mingw&lt;/a&gt; 中的Clang。个人建议有条件的话使用一个较新的版本，特性会有显著的差异。&lt;/p&gt;
&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;关于 Windows 下安装 llvm-mingw&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;ul&gt;
&lt;li&gt;从上述GitHub页面的releases中选择一个版本，下载assets中适合你电脑处理器的版本压缩包（如 &lt;code&gt;llvm-mingw-yyyymmdd-ucrt-x86_64.zip&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;将该压缩包所有内容解压到电脑上你喜欢的位置&lt;/li&gt;
&lt;li&gt;将含有数百个exe那个文件夹 &lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/231668109&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;加入到环境变量中&lt;/a&gt;（通常路径含有 &lt;code&gt;bin&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;打开你的终端，如果运行 &lt;code&gt;clang -v&lt;/code&gt; 显示与刚刚下载所匹配的版本，则安装完成&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在Windows和macOS下，Clang默认能够模拟GCC命令，因此无需再安装GCC。&lt;/p&gt;
    &lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;然后你当然需要VS Code，以及clangd插件，但没有必要卸载官方C/C++ 插件。但如果确实安装了，需要在VS Code的设置（文件-首选项-设置 或Code-首选项-设置）中禁用其IntelliSense代码补全（&lt;code&gt;C_Cpp.intelliSenseEngine&lt;/code&gt; 设置为 &lt;code&gt;disabled&lt;/code&gt;）。&lt;/p&gt;
&lt;h2 id=&#34;解析索引文件&#34;&gt;解析、索引文件
&lt;/h2&gt;&lt;p&gt;Clangd并不是强在可以完全自动找出索引，而是可以通过方便的方式生成索引。很多简单的项目可以直接使用类似 &lt;code&gt;clang main.c&lt;/code&gt; 之类的一条命令编译，此时Clangd也可以正常找到引用的所有文件和符号，下面这一段也就暂时没用了。&lt;/p&gt;
&lt;p&gt;然而复杂的项目则不然。就拿阿里巴巴前两年一篇HPCC论文的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/alibaba-edu/High-Precision-Congestion-Control/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;代码&lt;/a&gt; 来说，ns-3本身就是一个十分复杂的项目，仿真程序的引用也弯弯绕绕，也总不能把头文件全部装到系统目录中。虽然有较为方便的编译运行方式，但Clangd就不能自动处理所有引用了。因此下面介绍了几种办法，供各位参考。&lt;/p&gt;
&lt;h3 id=&#34;给clangd传入参数&#34;&gt;给Clangd传入参数
&lt;/h3&gt;&lt;p&gt;就像GCC/Clang一样，可以将 &lt;code&gt;-I&lt;/code&gt; 等参数传入Clangd，来指定它寻找头文件的范围。VS Code可以对每个工作区设定单独的Clangd参数（&lt;code&gt;clangd.arguments&lt;/code&gt;），这样每个项目的配置都可以不同了。&lt;/p&gt;
&lt;p&gt;虽然小项目手动传命令确实不麻烦，但小项目也用不着手动索引呀。所以这个办法其实不是特别方便。&lt;/p&gt;
&lt;h3 id=&#34;使用bear生成-compile_commandsjson&#34;&gt;使用Bear生成 &lt;code&gt;compile_commands.json&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;&lt;code&gt;compile_commands.json&lt;/code&gt; 记录了每个源文件的编译命令。例如HPCC代码的（&lt;strong&gt;该JSON仅供参考，不同版本生成工具格式有所改变&lt;/strong&gt;）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[
    {
        &amp;#34;command&amp;#34;: &amp;#34;c&amp;#43;&amp;#43; -c -O0 -ggdb -g3 -std=gnu&amp;#43;&amp;#43;11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/ss-scheduler.cc.1.o simulation/src/wimax/model/ss-scheduler.cc&amp;#34;,
        &amp;#34;directory&amp;#34;: &amp;#34;simulation/build&amp;#34;,
        &amp;#34;file&amp;#34;: &amp;#34;simulation/src/wimax/model/ss-scheduler.cc&amp;#34;
    },
    {
        &amp;#34;command&amp;#34;: &amp;#34;c&amp;#43;&amp;#43; -c -O0 -ggdb -g3 -std=gnu&amp;#43;&amp;#43;11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/wimax-mac-queue.cc.1.o simulation/src/wimax/model/wimax-mac-queue.cc&amp;#34;,
        &amp;#34;directory&amp;#34;: &amp;#34;simulation/build&amp;#34;,
        &amp;#34;file&amp;#34;: &amp;#34;simulation/src/wimax/model/wimax-mac-queue.cc&amp;#34;
    },
    {
        &amp;#34;command&amp;#34;: &amp;#34;c&amp;#43;&amp;#43; -c -O0 -ggdb -g3 -std=gnu&amp;#43;&amp;#43;11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/bs-scheduler-simple.cc.1.o simulation/src/wimax/model/bs-scheduler-simple.cc&amp;#34;,
        &amp;#34;directory&amp;#34;: &amp;#34;simulation/build&amp;#34;,
        &amp;#34;file&amp;#34;: &amp;#34;simulation/src/wimax/model/bs-scheduler-simple.cc&amp;#34;
    },
    ......
]&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;c++ -c -O0 -ggdb -g3 -std=gnu++11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/ss-scheduler.cc.1.o simulation/src/wimax/model/ss-scheduler.cc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;directory&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/src/wimax/model/ss-scheduler.cc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;c++ -c -O0 -ggdb -g3 -std=gnu++11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/wimax-mac-queue.cc.1.o simulation/src/wimax/model/wimax-mac-queue.cc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;directory&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/src/wimax/model/wimax-mac-queue.cc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;c++ -c -O0 -ggdb -g3 -std=gnu++11 -Wno-error=deprecated-declarations -fstrict-aliasing -Wstrict-aliasing -fPIC -pthread -Isimulation/build -Isimulation -I/usr/include/libxml2 -DNS3_ASSERT_ENABLE -DNS3_LOG_ENABLE -DHAVE_PACKET_H=1 -DHAVE_SQLITE3=1 -DHAVE_IF_TUN_H=1 -o src/wimax/model/bs-scheduler-simple.cc.1.o simulation/src/wimax/model/bs-scheduler-simple.cc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;directory&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;simulation/src/wimax/model/bs-scheduler-simple.cc&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;......&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;正因为Clangd同时也可以识别Clang的参数，所以通过提供编译命令，Clangd可以自动获取其引用的源代码所在的目录，从而处理引用，以及一些其他的功效。这个文件一般也没人手搓，太麻烦了。&lt;/p&gt;
&lt;p&gt;虽然C/C++ 生态的构建系统千变万化，但是仍然可以用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/rizsotto/Bear&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Bear&lt;/a&gt; 截取编译命令。不同版本Bear使用方式不同，需要预先注意：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;shell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;# 较老版本
bear &amp;lt;compile_command&amp;gt;
# 较新版本
bear -- &amp;lt;compile_command&amp;gt;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-shell&#34; data-lang=&#34;shell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 较老版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bear &amp;lt;compile_command&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# 较新版本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;bear -- &amp;lt;compile_command&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这样跑过一次编译之后，就在当前目录生成 &lt;code&gt;compile_commands.json&lt;/code&gt; 文件了。&lt;/p&gt;
&lt;h3 id=&#34;使用cmake生成-compile_commandsjson&#34;&gt;使用CMake生成 &lt;code&gt;compile_commands.json&lt;/code&gt;
&lt;/h3&gt;&lt;p&gt;如果整个项目使用CMake来构建，可以添加这个参数来生成它：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cmake -DCMAKE_EXPORT_COMPILE_COMMANDS&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;CMake会将该文件存放至编译产物的目录中。如果其所处目录并不是在 &lt;code&gt;build/&lt;/code&gt; 中，那么需要手动将其移到项目根目录中。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>我最终还是放弃了自己托管邮箱——转为了 Fastmail</title>
        <link>https://cyp0633.com/post/give-up-selfhosted-email/</link>
        <pubDate>Sun, 01 Oct 2023 22:46:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/give-up-selfhosted-email/</guid>
        <description>&lt;p&gt;不可否认的是，&lt;a class=&#34;link&#34; href=&#34;https://github.com/foxcpp/maddy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;maddy&lt;/a&gt; 是一款非常优秀、令人舒适的邮件服务器软件，关于安装，我写过一篇文章&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。在使用它的接近两年内，除了升级，我完全没有动过它，就连升级时也基本是无痛的。如果谁仍然想要自建一个邮件服务器，我还是会推荐maddy。五美元一月的Vultr托管邮件也十分稳定，25端口也只需要开个工单就能开通，同时Maddy占内存极小，跑点儿其他的也不亏。一切都按预期正常工作着，但还是有一些放弃自己托管的理由：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有时会当成spam，这个得怪收件人信箱，但确实是个普遍问题&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;；&lt;/li&gt;
&lt;li&gt;没有一个好用的webmail，之前用的Rainloop总感觉差那么点意思，而且独立的webmail总要多占一份空间；&lt;/li&gt;
&lt;li&gt;担心downtime，所以非常要紧的服务一直都用Gmail &lt;del&gt;（实际上downtime比我梯子挂掉的时间还少）&lt;/del&gt; ；&lt;/li&gt;
&lt;li&gt;每个月得花 $5，虽然不多，但是也不少（手上其他服务器不给开25端口）；&lt;/li&gt;
&lt;li&gt;&lt;del&gt;大四闲得慌。&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Maddy作为部署简单、功能全面的邮件服务器可以说是先行者了，现在也涌现了许多很好的自托管服务，比如 &lt;a class=&#34;link&#34; href=&#34;https://github.com/mjl-/mox&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;mox&lt;/a&gt; 解决了webmail的问题。当然这篇文章写出来不是为了推荐自托管服务的，这个话题可能也不是由我来讨论了。&lt;/p&gt;
&lt;p&gt;之所以想到放弃，缘于前两天看到了&lt;a class=&#34;link&#34; href=&#34;https://v2ex.com/t/990546&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一个 V 站的帖子&lt;/a&gt;，然后看到了最低19美元一年的 &lt;a class=&#34;link&#34; href=&#34;https://migadu.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Migadu&lt;/a&gt;，学生开工单享受半价优惠。这家从文档到服务都非常实诚，只按照使用量（收发量、邮件存储）计费，（几乎）不限制域名和邮箱数量，每个邮箱有自己的收发件箱，ToS里全都是“只有best effort服务，但是真的best effort&amp;quot;，域名数和使用空间等限制都是软限制，稍微超出一点儿也不打紧，甚至还在文档里diss了友商所谓的“加密”&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。当然最重要的原因是我可以省下每年60美元的服务器，一年就能省下350块钱。&lt;/p&gt;
&lt;p&gt;但Micro套餐内仅有5GB空间和每天20封邮件，虽然都是软限制，可以偶尔超过，但考虑到我博客的评论系统有回复自动发邮件提醒，万一评论区两个人对起线来……如果是Migadu，我可能只能选择90美元一年的Mini套餐了。这两个之间差价有点儿大，于是看向了Fastmail。Standard套餐50美元一年，还是能省下70多块钱；空间和发信量的痛点也都解决了，虽然是统一的信箱但是也不影响使用，也能使用不同的地址进行收发。如果不想用自己的域名了，还可以再添加一些Fastmail提供的后缀结尾的邮箱（甚至有 @fastmail.cn）。&lt;/p&gt;
&lt;p&gt;如果抛开套餐用量比较两家的服务，我认为它们走了两条不同的路：Migadu为本就是tech-savvy的用户服务，将尽可能多的技术细节提供给用户，只做最纯粹的电子邮件，推荐的也是开源邮件客户端和开源迁移方案；而Fastmail更多的面向普通用户，可以直接导入Gmail等服务，针对每个IMAP客户端有应用专用密码，甚至连域名都可以在它那里买。&lt;/p&gt;
&lt;p&gt;整理一个表格，对比Fastmail和Migadu套餐的区别：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;套餐&lt;/th&gt;
&lt;th&gt;Fastmail&lt;/th&gt;
&lt;th&gt;Migadu&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;年付价格 (USD)&lt;/td&gt;
&lt;td&gt;50&lt;/td&gt;
&lt;td&gt;19 (Micro) / 90 (Mini)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;每天收/发限制&lt;/td&gt;
&lt;td&gt;/&lt;/td&gt;
&lt;td&gt;200/20 (Micro) / 1000/100 (Mini)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;存储空间&lt;/td&gt;
&lt;td&gt;30GB&lt;/td&gt;
&lt;td&gt;5GB (Micro) / 30GB (Mini)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;多地址/域名处理&lt;/td&gt;
&lt;td&gt;单个域名；可添加邮箱地址，共用一个信箱&lt;/td&gt;
&lt;td&gt;无限邮箱，无限域名，各有单独信箱&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;其他服务&lt;/td&gt;
&lt;td&gt;日历、联系人、记事本&lt;/td&gt;
&lt;td&gt;日历、联系人（beta）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果Migadu能够以50美元一年以下的价格提供一个存储&amp;amp;发信多一点儿的套餐，我决策时一定会选择它；然而没有，所以还是投奔了Fastmail。&lt;/p&gt;
&lt;p&gt;如果只有中国手机号，Fastmail的注册会卡在手机验证码的一关，开工单就能解决；如果使用其他人的referral，也需要在工单里说明，客服会手动加上首年10% 的优惠。Fastmail和Migadu两者应该是都不支持支付宝和微信的，但支持PayPal（中国版支持不明）和Stripe（理论上支持银联卡）。&lt;/p&gt;
&lt;p&gt;Fastmail有一个迁移向导，输入原来的IMAP服务器、账户名称和密码，就能把信箱搬过来了，功能倒是很像IMAPSync，只不过在它的服务器上运行。效果不错，迁移也很快，非常舒服。&lt;/p&gt;
&lt;p&gt;不得不说，国内的访问体验确实有点慢，远比不上国内的服务 &lt;del&gt;（废话）&lt;/del&gt; ，但相对之前自建的速度其实快多了。说真的，只要不被墙就很好了。&lt;/p&gt;
&lt;p&gt;尴尬的是，迁过来的消息总共只用了0.1GB；又翻了翻一直以来用的QQ邮箱和Gmail，分别用了146MB和420MB，这么看的话5GB的空间还是长期够用的。又转念一想，我博客这个鸟不拉屎的地方也基本没人发评论，每天20封其实也够用了。意识到这个问题后，再次反思放弃自托管的五个理由，发现只有最后一个最真切。别说了，几年前那股折腾劲儿又上来了。&lt;/p&gt;
&lt;p&gt;最后，如果你也想找个邮件托管商，我推荐Migadu的Micro套餐，完全够用；如果你订了Fastmail，可以使用&lt;a class=&#34;link&#34; href=&#34;https://ref.fm/u30369112&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;我的 referral&lt;/a&gt; 注册，你享受首年10% 优惠，我也可以每月得到约0.5美元的余额。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/post/self-hosting-mail-maddy-rainloop/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://cyp0633.icu/post/self-hosting-mail-maddy-rainloop/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://news.ycombinator.com/item?id=32715437&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://news.ycombinator.com/item?id=32715437&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://migadu.com/procon/#not-encrypted&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://migadu.com/procon/#not-encrypted&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Armbian &#43; R2S 番外篇：透明代理</title>
        <link>https://cyp0633.com/post/armbian-r2s-tproxy/</link>
        <pubDate>Sun, 17 Sep 2023 20:46:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/armbian-r2s-tproxy/</guid>
        <description>&lt;p&gt;透明代理这个东西说起来很容易理解，就是设备感知不到有的流量被代理，却有开了代理的效果。这个东西对于学习境外内容的体验提升很大，因为部分应用并不遵循系统代理设置，或设置很麻烦。避免将代理配置文件存放在电脑上，也可以防止电脑上的应用窃取代理信息。&lt;/p&gt;
&lt;p&gt;透明代理本身在中文互联网已经是聊烂了的话题，但使用Nftables实现的透明代理很少，在主路由上实现透明代理的更少。我的网络拓扑大概是：外部网络 - R2S - 无线AP - 其他设备。本文将基于这个拓扑，实现在R2S上使用Nftables实现透明代理。&lt;/p&gt;
&lt;p&gt;这个东西作为&lt;a class=&#34;link&#34; href=&#34;https://cyp0633.com/post/armbian-r2s/&#34; &gt;上篇文章&lt;/a&gt;的一个小节显得有点喧宾夺主了，所以就单独写一篇文章吧。&lt;/p&gt;
&lt;h2 id=&#34;前置知识&#34;&gt;前置知识
&lt;/h2&gt;&lt;p&gt;只需要基础的计网知识，以及初步了解Nftables（起码能看懂规则）。&lt;/p&gt;
&lt;p&gt;另外丢掉那张老旧的（you know what）Netfilter数据包流向图吧，由于Nftables的链是可以自由添加、自定义优先级的，现在它应该是这样&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;armbian-r2s-tproxy/nftables-hooks.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Netfilter 数据包流向图&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Netfilter 数据包流向图&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;思路&#34;&gt;思路
&lt;/h2&gt;&lt;p&gt;要达到的效果是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DHCP服务器将默认DNS服务器指向本机的Telescope DNS，由其负责解析&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;，直连DoH&lt;/li&gt;
&lt;li&gt;局域网内通信不经过代理工具，包括DHCP等特殊服务&lt;/li&gt;
&lt;li&gt;其他来自局域网内的TCP/UDP流量都经过代理工具，由代理工具分流&lt;/li&gt;
&lt;li&gt;不代理路由本身流量，暂时没需求&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说流量会经过Nftables和代理工具两次分流。对于较为固定、不高于三层的分流规则，交给Nftables效率更高；而对于按站点分流之类的规则，则交给代理工具，更灵活。&lt;/p&gt;
&lt;p&gt;对于第一条，局域网内机器发送数据包的路径为：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;局域网内客户端发出DNS请求&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;prerouting&lt;/code&gt; 对目的为局域网内的请求进行直连，不代理&lt;/li&gt;
&lt;li&gt;Telescope DNS接收到请求（此处设未缓存）&lt;/li&gt;
&lt;li&gt;Telescope DNS向上游发出请求，不带任何meta mark&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;postrouting&lt;/code&gt; 进行NAT&lt;/li&gt;
&lt;li&gt;远程DNS服务器收到请求，返回结果&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;prerouting&lt;/code&gt; 对来自局域网外的请求直连&lt;/li&gt;
&lt;li&gt;Telescope DNS收到上游回复&lt;/li&gt;
&lt;li&gt;Telescope DNS将结果返回给客户端&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;postrouting&lt;/code&gt; 进行NAT&lt;/li&gt;
&lt;li&gt;客户端收到回复&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对内网的包：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;局域网内客户端发出请求&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;prerouting&lt;/code&gt; 对目的为局域网内的请求进行直连，不代理&lt;/li&gt;
&lt;li&gt;进入 &lt;code&gt;forward&lt;/code&gt; 链，转发给目标机器
或/同时被本机处理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对分流决定代理的正常TCP/UDP流量：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;局域网内客户端发出请求&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;prerouting&lt;/code&gt; 对于来自局域网、目标为外网的请求，进行 &lt;code&gt;tproxy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;代理工具接收并封装请求，并发送到代理服务器，带有meta mark 2&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;postrouting&lt;/code&gt; 进行NAT&lt;/li&gt;
&lt;li&gt;代理服务器处理代理请求，返回结果&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;prerouting&lt;/code&gt; 对于来自外网的请求，不代理（直接发往代理工具）&lt;/li&gt;
&lt;li&gt;代理工具接收并解封装请求，将结果返回给客户端&lt;/li&gt;
&lt;li&gt;Nftables &lt;code&gt;postrouting&lt;/code&gt; 进行NAT&lt;/li&gt;
&lt;li&gt;客户端收到回复&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对于决定不分流的正常TCP/UDP流量，其实也和上面相似，只不过代理工具直接将请求发往目标服务器，目标服务器也直接把结果返回给代理工具。&lt;/p&gt;
&lt;h2 id=&#34;实现&#34;&gt;实现
&lt;/h2&gt;&lt;p&gt;类似于 &lt;a class=&#34;link&#34; href=&#34;https://xtls.github.io/document/level-2/tproxy.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Xray TProxy 透明代理&lt;/a&gt; 之类的本机透明代理方案很多，一般也适用于旁路由。核心的规则其实就两条，也就是在 &lt;code&gt;prerouting&lt;/code&gt; 的链上加入（&lt;code&gt;tproxy&lt;/code&gt; 仅支持 &lt;code&gt;prerouting&lt;/code&gt;）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;ip protocol tcp tproxy to 127.0.0.1:12345 meta mark set 1
ip protocol udp tproxy to 127.0.0.1:12345 meta mark set 1&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tproxy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tproxy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然而就以上面链接中这篇教程的配置为例，它包含如下三行规则，通过跳过目的为本地IP的代理，同时避免了&lt;strong&gt;远程服务器发回的流量被重新代理&lt;/strong&gt;和&lt;strong&gt;局域网内主机间流量被代理&lt;/strong&gt;的问题：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;ip daddr $RESERVED_IP return
ip daddr 192.168.0.0/16 tcp dport != 53 return
ip daddr 192.168.0.0/16 udp dport != 53 return&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RESERVED_IP&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;第二个问题很好理解。而这些规则能解决第一个问题，主要原因在于主路由已经做好了NAT，看起来已经是从远程主机IP发往代理客户端主机IP的流量了，也就是有了目的IP在上述范围内的特征。同样的方法却不能套到主路由上，因为NAT一般在 &lt;code&gt;postrouting&lt;/code&gt; 阶段去做，而 &lt;code&gt;tproxy&lt;/code&gt; 一般在 &lt;code&gt;prerouting&lt;/code&gt; 阶段进行&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。此时，网络层的目的IP仍然是本机的外网IP，而非192.168.0.1这样的局域网IP。&lt;/p&gt;
&lt;p&gt;然而，出于某些原因，我们并不能在 &lt;code&gt;postrouting&lt;/code&gt; 阶段等待NAT完成后再更改目的IP&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;，也就是说这个阶段已经不能把数据包拐到代理上面了。考虑到 &lt;code&gt;tproxy&lt;/code&gt; 的作用阶段，实际上在 &lt;code&gt;prerouting&lt;/code&gt; 中同时进行Nftables阶段的分流和 &lt;code&gt;tproxy&lt;/code&gt; 更为合适。相应的，为了识别远程服务器发回流量，我们要添加一条规则，也就是&lt;strong&gt;源IP不在内网IP段中&lt;/strong&gt;，则不代理。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;另外不管是上面的教程还是Linux kernel文档&lt;sup id=&#34;fnref1:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;，都指出 &lt;code&gt;tproxy&lt;/code&gt; 应搭配自定义IP route使用，以让透明代理的包正确地传输到本地。在进行透明代理的同时为数据包附上meta mark 1，这样就可以被以下两条命令定义的路由规则捕获，然后被传输到本地：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;ip rule add fwmark 1 lookup 100 # 对于带标记 1 的包，使用编号为 100 的路由表（100 没有什么特殊含义）
ip route add local 0.0.0.0/0 dev lo table 100 # 对于路由表 100，经过 lo 设备发送到 0.0.0.0&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip rule add fwmark &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; lookup &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 对于带标记 1 的包，使用编号为 100 的路由表（100 没有什么特殊含义）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip route add &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; 0.0.0.0/0 dev lo table &lt;span class=&#34;m&#34;&gt;100&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 对于路由表 100，经过 lo 设备发送到 0.0.0.0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;实验表明去掉这两条规则后，无法正确进行透明代理。由于 &lt;code&gt;tproxy&lt;/code&gt; 并不会修改数据包本身的内容，所以我猜测该数据包可能会按照默认策略路由，不会进入本地回环为代理工具所接收。&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;接下来就该配置代理软件了。我个人建议使用Xray-core，需要添加入站：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;inbounds&amp;#34;: [
    {
      &amp;#34;tag&amp;#34;: &amp;#34;all-in&amp;#34;,
      &amp;#34;port&amp;#34;: 12345,
      &amp;#34;listen&amp;#34;: &amp;#34;127.0.0.1&amp;#34;,
      &amp;#34;protocol&amp;#34;: &amp;#34;dokodemo-door&amp;#34;,
      &amp;#34;settings&amp;#34;: {
        &amp;#34;network&amp;#34;: &amp;#34;tcp,udp&amp;#34;,
        &amp;#34;followRedirect&amp;#34;: true
      },
      &amp;#34;sniffing&amp;#34;: {
        &amp;#34;enabled&amp;#34;: true,
        &amp;#34;destOverride&amp;#34;: [
          &amp;#34;http&amp;#34;,
          &amp;#34;tls&amp;#34;
        ]
      },
      &amp;#34;streamSettings&amp;#34;: {
        &amp;#34;sockopt&amp;#34;: {
          &amp;#34;tproxy&amp;#34;: &amp;#34;tproxy&amp;#34;
        }
      }
    },
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;inbounds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;tag&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;all-in&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;port&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;listen&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;protocol&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;dokodemo-door&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;settings&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;network&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tcp,udp&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;followRedirect&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;sniffing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;enabled&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;destOverride&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s2&#34;&gt;&amp;#34;http&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s2&#34;&gt;&amp;#34;tls&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;streamSettings&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;sockopt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;tproxy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tproxy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;并且建议为每个出站都设定meta mark不为1：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;outbounds&amp;#34;: [
    {
      &amp;#34;streamSettings&amp;#34;:{        
        &amp;#34;sockopt&amp;#34;: {
          &amp;#34;mark&amp;#34;: 2
        },
      },
    },
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;outbounds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;streamSettings&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:{&lt;/span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;sockopt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;mark&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt; &lt;/p&gt;
&lt;p&gt;在添加了上面的规则后，发现连不上新设备了，查找DHCP服务器的日志也并未发现端倪。发现由于DHCP的Discover目标为广播IP，并未被排除代理，所以被代理工具截留。我使用的workaround为添加一条规则，对目标为udp/67端口的数据包不代理，DHCP恢复正常。&lt;/p&gt;
&lt;p&gt;宿舍的网络竟然有外界可以直接访问的公网IP（震惊），所以个人还加了 &lt;code&gt;filter&lt;/code&gt; 表，用于防止外界白嫖代理。这个看一下下面的配置文件就明白，我不多讲。&lt;/p&gt;
&lt;h2 id=&#34;配置&#34;&gt;配置
&lt;/h2&gt;&lt;p&gt;如果你希望使用此配置文件，请根据你路由器的接口分配、网段分配、代理工具等情况进行修改。另外也不要忘了添加 &lt;code&gt;ip&lt;/code&gt; 路由规则。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;#!/usr/sbin/nft -f

flush ruleset

define RESERVED_IP = {
    192.168.0.0/24,
    0.0.0.0/8,
}

define WANLINK = lan0
define LANLINK = eth0

table ip nat {
    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname $WANLINK masquerade
    }
}

table ip filter {
    chain input {
        type filter hook input priority 0; policy accept;
        # only accept local/LAN traffic to tproxy
        ip saddr != $RESERVED_IP tcp dport 12345 drop
    }
}

table ip xray {
    chain prerouting {
        type filter hook prerouting priority mangle; policy accept;
        # source not from LAN (e.g. server reply), don&amp;#39;t proxy
        ip saddr != $RESERVED_IP return
        # dest loopback or local traffic, don&amp;#39;t proxy
        ip daddr $RESERVED_IP return
        # allow dhcp traffic (daddr may be 255.255.255.0)
        udp dport 67 return
        # tproxy traffic
        ip protocol {tcp,udp} tproxy to 127.0.0.1:12345 meta mark set 1
    }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ch&#34;&gt;#!/usr/sbin/nft -f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;flush&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ruleset&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;define&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RESERVED_IP&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;mf&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;24&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;mf&#34;&gt;0.0.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;define&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WANLINK&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lan0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;define&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LANLINK&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eth0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;postrouting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nat&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;postrouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;oifname&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$WANLINK&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;masquerade&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# only accept local/LAN traffic to tproxy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;saddr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RESERVED_IP&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;drop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xray&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mangle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# source not from LAN (e.g. server reply), don&amp;#39;t proxy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;saddr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RESERVED_IP&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# dest loopback or local traffic, don&amp;#39;t proxy&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RESERVED_IP&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# allow dhcp traffic (daddr may be 255.255.255.0)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;67&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# tproxy traffic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tproxy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&#34;ipv6&#34;&gt;IPv6
&lt;/h2&gt;&lt;p&gt;&lt;em&gt;本节参考&lt;/em&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;IPv6透明代理的实现与上面相似，甚至可以不用建新表，而是修改 &lt;code&gt;xray&lt;/code&gt; 表即可。&lt;/p&gt;
&lt;p&gt;IPv6对应的路径设置如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;ip -6 rule add fwmark 1 table 106
ip -6 route add local ::/0 dev lo table 106&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip -6 rule add fwmark &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; table &lt;span class=&#34;m&#34;&gt;106&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ip -6 route add &lt;span class=&#34;nb&#34;&gt;local&lt;/span&gt; ::/0 dev lo table &lt;span class=&#34;m&#34;&gt;106&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这里我直接将修改后的 &lt;code&gt;xray&lt;/code&gt; 表列在下面：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;table inet xray {
    chain prerouting {
        type filter hook prerouting priority filter; policy accept;
        ip daddr { 127.0.0.0/8, 224.0.0.0/4, 255.255.255.255 } return
        ip6 daddr 2408::/16 return
        meta l4proto tcp ip daddr 192.168.0.0/16 return
        ip daddr 192.168.0.0/16 udp dport != 53 return
        ip6 daddr { ::1, fe80::/10 } return
        meta l4proto tcp ip6 daddr fd00::/8 return
        ip6 daddr fd00::/8 udp dport != 53 return

        # tailscale
        udp sport 41641 return
        udp dport 41641 return
        udp dport 3478 return
        udp sport 3478 return

        meta mark 2 return
        meta l4proto { tcp, udp } meta mark set 1 tproxy ip to 127.0.0.1:12345 accept
        meta l4proto { tcp, udp } meta mark set 1 tproxy ip6 to [::1]:12345 accept
    }

    chain divert {
        type filter hook prerouting priority mangle; policy accept;
        meta l4proto tcp socket transparent 1 meta mark set 1 accept
    }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inet&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xray&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;127.0.0.0&lt;/span&gt;&lt;span class=&#34;sr&#34;&gt;/8, 224.0.0.0/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;255.255.255.255&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2408&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l4proto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;192.168.0.0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;16&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;fe80::&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l4proto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;fd00::&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;ip6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;daddr&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;fd00::&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;# tailscale&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;41641&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;41641&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3478&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;sport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3478&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l4proto&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tproxy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;127.0.0.1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l4proto&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tproxy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip6&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12345&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;divert&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mangle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;l4proto&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;socket&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;transparent&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mark&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果你的代理工具只监听了IPv4地址，那么需要同时监听IPv6 [::1]:12345。&lt;/p&gt;
&lt;h2 id=&#34;优化&#34;&gt;优化
&lt;/h2&gt;&lt;h3 id=&#34;nftables数据包追踪&#34;&gt;Nftables数据包追踪
&lt;/h3&gt;&lt;p&gt;在编写Nftables配置的时候，经常可能有疑问，这个数据包到哪里去了。可以使用 &lt;code&gt;nft monitor trace&lt;/code&gt; 监视特定数据包的流向和规则判定过程，详细使用方法见 &lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;h3 id=&#34;米家设备无法连网&#34;&gt;米家设备无法连网
&lt;/h3&gt;&lt;p&gt;如果开启透明代理的情况下，发现米家设备无法联网（或者无法绑定到App），而关闭透明代理又恢复，那么可能是因为米家设备需要连接域名 &lt;code&gt;mijia cloud&lt;/code&gt;（是的你没看错，中间一个空格），代理工具嗅探到了这个域名并尝试解析以分流，但其无法正常处理&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;，于是走默认。可以通过查看代理工具的日志来验证这个情况，Xray-core和Clash都可能会有这个问题。&lt;/p&gt;
&lt;p&gt;解决方法是跳过这个域名的嗅探分流，如Xray-core加上这一段：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-8&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-8&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;inbounds&amp;#34;: [
    {
      &amp;#34;sniffing&amp;#34;: {
        &amp;#34;domainsExcluded&amp;#34;: [
          &amp;#34;mijia cloud&amp;#34;
        ]
      }
    }
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;inbounds&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;sniffing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;domainsExcluded&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;s2&#34;&gt;&amp;#34;mijia cloud&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;干出这个事的小米工程师真该拉出去祭天。&lt;/p&gt;
&lt;h3 id=&#34;境内流量完全直连&#34;&gt;境内流量完全直连
&lt;/h3&gt;&lt;p&gt;上述的配置会令境内外流量均经过代理工具，最直接的问题就是访问速度变慢。但可能也有些其他后果。&lt;/p&gt;
&lt;p&gt;曾遇到一个非常玄学的问题，如国服原神“连接超时”，国服星穹铁道错误“1001_1”等。即使设置了正确的分流规则和DNS解析，也可能无法登录。抓包发现有许多和米哈游的TCP连接被reset掉，暂时不知道根本原因。&lt;/p&gt;
&lt;p&gt;个人的解决办法是使用Nftables进行国内IP分流，具体可见 &lt;a class=&#34;link&#34; href=&#34;https://a-wing.top/network/2020/03/06/bypass_gateway-3_nftables&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文章&lt;/a&gt;。实测使用该措施后，由于不需要回到用户态过代理软件，日常上网也会快一点。不过若依赖于特定代理软件的附加功能，如Xray-core的Full Cone NAT，则对于绕过的流量，也会一并失去这些功能。&lt;/p&gt;
&lt;p&gt;此处附一个适用于IPv4和IPv6的转换脚本，将APNIC的数据转换为nftables格式，并输出到标准输出：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;python&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-9&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-9&#34; style=&#34;display:none;&#34;&gt;import re

# Function to calculate subnet mask from number of IPs
def get_cidr_from_size(size):
    import math
    return 32 - int(math.log2(size))

def parse_ip_ranges(file_path):
    v4_list = []
    v6_list = []

    # Regular expressions for extracting IPv4 and IPv6 ranges
    ipv4_regex = r&amp;#39;apnic\|CN\|ipv4\|([0-9]&amp;#43;\.[0-9]&amp;#43;\.[0-9]&amp;#43;\.[0-9]&amp;#43;)\|(\d&amp;#43;)\|&amp;#39;
    ipv6_regex = r&amp;#39;apnic\|CN\|ipv6\|([0-9a-fA-F:]&amp;#43;)\|(\d&amp;#43;)\|&amp;#39;

    with open(file_path, &amp;#39;r&amp;#39;) as file:
        for line in file:
            # Check for IPv4
            match_v4 = re.search(ipv4_regex, line)
            if match_v4:
                ip = match_v4.group(1)
                size = int(match_v4.group(2))
                # Calculate CIDR from the size
                cidr = get_cidr_from_size(size)
                subnet = f&amp;#34;{ip}/{cidr},&amp;#34;
                v4_list.append(subnet)

            # Check for IPv6
            match_v6 = re.search(ipv6_regex, line)
            if match_v6:
                ip = match_v6.group(1)
                prefix_length = int(match_v6.group(2))
                # Construct the subnet
                subnet = f&amp;#34;{ip}/{prefix_length},&amp;#34;
                v6_list.append(subnet)

    return v4_list, v6_list


def generate_nftables_rule(file_path):
    v4_list, v6_list = parse_ip_ranges(file_path)

    # Format the output in nftables style
    v4_rules = &amp;#34;define chnroute_list_v4 = {\n&amp;#34; &amp;#43; &amp;#34;\n    &amp;#34;.join(v4_list) &amp;#43; &amp;#34;\n}&amp;#34;
    v6_rules = &amp;#34;define chnroute_list_v6 = {\n&amp;#34; &amp;#43; &amp;#34;\n    &amp;#34;.join(v6_list) &amp;#43; &amp;#34;\n}&amp;#34;

    return v4_rules, v6_rules


if __name__ == &amp;#34;__main__&amp;#34;:
    file_path = &amp;#39;delegated-apnic-latest&amp;#39;  # Replace with your actual file path

    v4_rules, v6_rules = generate_nftables_rule(file_path)

    # Print the results
    print(v4_rules)
    print(v6_rules)&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;49
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;50
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;51
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;52
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;53
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;54
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;55
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;56
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;57
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;re&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Function to calculate subnet mask from number of IPs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;get_cidr_from_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;math&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;32&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;math&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;log2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;parse_ip_ranges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v4_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v6_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Regular expressions for extracting IPv4 and IPv6 ranges&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ipv4_regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;apnic\|CN\|ipv4\|([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\|(\d+)\|&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;ipv6_regex&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;apnic\|CN\|ipv6\|([0-9a-fA-F:]+)\|(\d+)\|&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;with&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;r&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt; &lt;span class=&#34;ow&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;# Check for IPv4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;match_v4&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ipv4_regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match_v4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match_v4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;match_v4&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;c1&#34;&gt;# Calculate CIDR from the size&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;cidr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;get_cidr_from_size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;size&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;subnet&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;cidr&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;,&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;v4_list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subnet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;# Check for IPv6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;match_v6&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;re&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ipv6_regex&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match_v6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;match_v6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;prefix_length&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;match_v6&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;c1&#34;&gt;# Construct the subnet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;subnet&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;sa&#34;&gt;f&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;prefix_length&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;,&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;v6_list&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;append&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;subnet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v4_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v6_list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;generate_nftables_rule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v4_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v6_list&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;parse_ip_ranges&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Format the output in nftables style&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v4_rules&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;define chnroute_list_v4 = {&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v4_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v6_rules&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;define chnroute_list_v6 = {&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;    &amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;join&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v6_list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;se&#34;&gt;\n&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v4_rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v6_rules&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;vm&#34;&gt;__name__&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;delegated-apnic-latest&amp;#39;&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;# Replace with your actual file path&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;v4_rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v6_rules&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;generate_nftables_rule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file_path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;# Print the results&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v4_rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;v6_rules&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://thermalcircle.de/doku.php?id=blog:linux:nftables_packet_flow_netfilter_hooks_detail&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://thermalcircle.de/doku.php?id=blog:linux:nftables_packet_flow_netfilter_hooks_detail&lt;/a&gt; 另外这也是一篇极佳的Nftables入门文章，推荐阅读。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;或许有人担心这会影响Xray-core的域名分流，但其域名分流是依靠sniffing头中的SNI实现的，即使Xray-core得不到解析前的域名，也不会受到影响。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.kernel.org/doc/Documentation/networking/tproxy.txt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.kernel.org/doc/Documentation/networking/tproxy.txt&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://serverfault.com/a/125913&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://serverfault.com/a/125913&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://xtls.github.io/document/level-2/tproxy_ipv4_and_ipv6.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://xtls.github.io/document/level-2/tproxy_ipv4_and_ipv6.html&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://wiki.nftables.org/wiki-nftables/index.php/Ruleset_debug/tracing&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/XTLS/Xray-core/issues/293&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/XTLS/Xray-core/issues/293&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>启用 AMD P-State EPP 调频驱动</title>
        <link>https://cyp0633.com/post/amd-pstate-epp/</link>
        <pubDate>Tue, 12 Sep 2023 23:05:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/amd-pstate-epp/</guid>
        <description>&lt;p&gt;Arch Linux的Linux 6.5内核终于在前几天进入了 &lt;code&gt;core&lt;/code&gt; 软件库，其中一个重要的特性就是默认启用了P-State EPP (Active) 调频驱动&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;。调频驱动不同于调速器，前者与特定的CPU有关；而后者与电源方案有关，如 &lt;code&gt;powersave&lt;/code&gt; 就是一直运行在最低频率。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;amd-pstate&lt;/code&gt; 是AMD CPU性能调频驱动，它在Linux内核中的现代AMD APU和CPU系列上引入了新的CPU频率控制机制。新机制基于协作处理器性能控制 (CPPC)，它提供比传统ACPI硬件P-state更精细的频率管理。当前的AMD CPU/APU平台使用ACPI P-State驱动程序来管理CPU频率和时钟，仅在3个P-state下进行切换。CPPC取代了ACPI P-state控制，并为Linux内核提供了灵活、低延迟的接口，以直接向硬件传达性能提示。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;amd_pstate&lt;/code&gt; CPPC有3种操作模式：自主（active）模式、非自主（passive）模式和引导自主（guided）模式。通过不同的内核参数可以选择active/passive/guided模式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在自主模式下，平台会忽略所需的性能级别请求，并仅考虑设置为最小、最大和能量性能首选项寄存器的值。&lt;/li&gt;
&lt;li&gt;在非自主模式下，平台直接通过所需性能寄存器从操作系统获取所需的性能水平。&lt;/li&gt;
&lt;li&gt;在引导自主模式下，平台根据当前工作负载并在操作系统通过最小和最大性能寄存器设置的限制内自主设置操作性能级别。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;amd_pstate=active&lt;/code&gt; 是低级固件控制模式，由amd_pstate_epp驱动程序实现，并在命令行中将amd_pstate=active传递给内核。在此模式下，如果软件想要偏向CPPC固件的性能 (0x0) 或能效 (0xff)，amd_pstate_epp驱动程序会向硬件提供提示。然后CPPC功耗算法将计算运行时工作负载，并根据电源和热量、核心电压和其他一些硬件条件调整实时核心频率。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简而言之，相比默认的 &lt;code&gt;acpi_cpufreq&lt;/code&gt;，P-State能够让CPU从操作系统处直接获得性能需求hint，并进行更细粒度的频率控制。P-State EPP（active模式）响应更快，并能自定义hint，达到类似于调速器的效果。&lt;/p&gt;
&lt;p&gt;P-State EPP支持Zen 2或更新的AMD CPU。本人使用的是联想R7000 2020，AMD Ryzen 7 4800H，也算是喝到了一大口汤吧。&lt;/p&gt;
&lt;h2 id=&#34;启用cppc&#34;&gt;启用CPPC
&lt;/h2&gt;&lt;p&gt;P-State EPP依赖于CPPC（Collaborative Processor Performance Control），所以首先要在BIOS中启用CPPC。请自查BIOS内是否有此选项，如果没有，需要使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/DavidS95/Smokeless_UMAF&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Smokeless_UMAF&lt;/a&gt; 访问BIOS中的隐藏选项，步骤如下。&lt;strong&gt;本文作者与插件作者不对任何损坏负责。&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载仓库中的 &lt;code&gt;UMAF_BETA.zip&lt;/code&gt;，解压到一个空的FAT32格式的U盘中&lt;/li&gt;
&lt;li&gt;用此U盘引导启动&lt;/li&gt;
&lt;li&gt;进入Device Manager - AMD CBS - NBIO - SMU&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在这里应该就可以看到CPPC选项。即使已经显示Auto或者Default，也需要手动Enable。设置完成后按保存重启即可。&lt;/p&gt;
&lt;h2 id=&#34;启用p-state-epp&#34;&gt;启用P-State EPP
&lt;/h2&gt;&lt;p&gt;可以直接运行上图中的 &lt;code&gt;cpupower&lt;/code&gt; 工具来查看当前的调频驱动。如果你和我一样已经在运行Linux 6.5，那么可能什么都不用做了。&lt;/p&gt;
&lt;p&gt;不同内核版本对P-State EPP的支持如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;6.5起，默认启用P-State EPP&lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;6.4起，支持Guided Autonomous模式&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;6.3起，支持EPP，但默认不启用&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;5.17起，支持P-State&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果在使用6.3或6.4，开启EPP的方法就是添加内核参数，&lt;code&gt;amd_pstate=[active|passive|guided]&lt;/code&gt;。关于如何修改内核参数，可参见 &lt;a class=&#34;link&#34; href=&#34;https://wiki.archlinux.org/title/kernel_parameters&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ArchWiki: kernel parameters&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;其他优化&#34;&gt;其他优化
&lt;/h2&gt;&lt;p&gt;可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/jothi-prasath/auto-epp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;auto-epp&lt;/a&gt; 来自动传递EPP hint，以在离电情况下功耗更低，或接入电源时性能释放更强。&lt;/p&gt;
&lt;p&gt;在启用EPP的情况下，也可以直接将调速器设为 &lt;code&gt;powersave&lt;/code&gt;，完全靠调频驱动进行调频&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;h2 id=&#34;体验&#34;&gt;体验
&lt;/h2&gt;&lt;p&gt;在启用P-State EPP调频驱动后，CPU各内核的频率能够在适当的时候（如浏览网页等场景）降低至400 MHz（见下图的频率范围），在有需求时也能快速拉起频率。相比于之前最低频率仅能低至1.3GHz，此举有望能大幅降低低负载的package功耗。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;amd-pstate-epp/pstate-epp.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;启用 P-State EPP 后的效果&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;启用 P-State EPP 后的效果&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在进行简单的浏览网页和编写代码时，使用 &lt;code&gt;balance_performance&lt;/code&gt; hint，流畅度完全没有问题。笔记本离电时使用 &lt;code&gt;power&lt;/code&gt; hint，提频更消极，跑不满笔记本的高刷新率，但功耗更低；使用独显混合模式，续航大约4小时，遥遥领先于Windows，比同样60Wh电池的MBP13 2020（Intel）更强；若关闭独显，可能对续航有更大的提升。&lt;/p&gt;
&lt;p&gt;此外也有网友称出现了重启的问题，反正我没遇到。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.phoronix.com/news/Linux-6.5-Power-Management&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Linux 6.5 Now Defaults To AMD P-State &amp;ldquo;Active&amp;rdquo; EPP For Modern Ryzen Systems&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.kernel.org/admin-guide/pm/amd-pstate.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;amd-pstate CPU Performance Scaling Driver&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/DaidS95/Smokeless_UMAF/discussions/29&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Empty Custom Core Pstates&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.phoronix.com/news/AMD-Guided-Auto-Mode-Linux-6.4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AMD Guided Autonomous Mode Submitted For Linux 6.4&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/Fedora/comments/12d2vs8/amd_pstate_epp_can_be_enabled_in_fedora_38_kernel/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AMD P-State EPP can be enabled in Fedora 38 (Kernel 6.3)&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.phoronix.com/news/Linux-6.3-Power-Management&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AMD P-State EPP Submitted For Linux 6.3 To Improve CPU Performance/Power&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/linux_gaming/comments/13by61l/amd_pstateactive/jjdhi58/?utm_source=share&amp;amp;utm_medium=web3x&amp;amp;utm_name=web3xcss&amp;amp;utm_term=1&amp;amp;utm_content=share_button&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.reddit.com/r/linux_gaming/comments/13by61l/amd_pstateactive/jjdhi58/?utm_source=share&amp;utm_medium=web3x&amp;utm_name=web3xcss&amp;utm_term=1&amp;utm_content=share_button&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>Armbian，更适合 R2S 软路由的系统</title>
        <link>https://cyp0633.com/post/armbian-r2s/</link>
        <pubDate>Fri, 14 Jul 2023 14:54:00 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/armbian-r2s/</guid>
        <description>&lt;h2 id=&#34;openwrt的困境&#34;&gt;OpenWrt的困境
&lt;/h2&gt;&lt;blockquote&gt;
&lt;p&gt;人们安装OpenWrt，是因为他们觉得它比路由器或者嵌入式设备的原厂固件更好用。&lt;/p&gt;
&lt;p&gt;——&lt;a class=&#34;link&#34; href=&#34;https://openwrt.org/reasons_to_use_openwrt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;《使用 OpenWrt 的理由》&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;不错，作为一个路由器系统来说OpenWrt确实实现了相对官方固件更好的可玩性。实际用久了自然会发现OpenWrt作为一个Linux来说是非常难用的，这点突出体现在其包管理上。官方软件源各种残缺，第三方软件源也充斥着野包，让我想起了用CentOS的时候。开发者倾向于为传统大发行版打包，相比较而言极少看到过opkg。OpenWrt官方甚至不建议升级软件包 &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;，因为包管理器并没有能力升级OpenWrt本身……这对Tailscale和Xray-core等需要经常更新的软件来说很致命。&lt;/p&gt;
&lt;p&gt;整个OpenWrt给人的印象也是能省则省，因为它需要照顾到大量低性能的设备，甚至低至8MB Flash、32M RAM的设备；前文提到的包管理器区别是因为opkg不支持ABI兼容性监测；对于普通的Linux发行版也有诸多其他不同。而对于R2S这种1GB RAM的设备来说，倒没必要这么节省。更何况即使在Armbian上，日常占用RAM也仅有300MB，这里面还有100MB以上是Xray-core的缓存。&lt;/p&gt;
&lt;p&gt;我并没有说OpenWrt不适合路由器使用，它的大部分配置都能点几下就完成设置，也有更多的中文资料，还有很多开箱即用的网络优化，在社区活跃开发者的帮助下，它十分适合路由器使用。但若是想要跳出插件开发者设定的笼子，尝试稍高级一点的玩法，OpenWrt就会显得各种别扭。而Armbian基于Debian或者Ubuntu，都是许多Linux用户再熟悉不过的发行版，因此使用Armbian不是找罪受，反而能够利用已有的其他Linux使用习惯和资料，是一个偷懒的选择。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;armbian-r2s/armbian.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;包含 Armbian 信息的 neofetch&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;因此，本文希望为读者提供另一种软路由的思路，&lt;strong&gt;让R2S兼有传统主路由的功能，又有更熟悉的Linux发行版体验&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;我的网络拓扑大概如下（无线路由器连接的各个设备仅为示意）。R2S作为主路由使用，&lt;del&gt;Redmi AC2100&lt;/del&gt; （已升级为小米AX3000）作为AP，不存在旁路由。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;armbian-r2s/topology.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;网络拓扑&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;网络拓扑&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;安装armbian&#34;&gt;安装Armbian
&lt;/h2&gt;&lt;p&gt;安装Armbian的第一步就像OpenWrt一样，从 &lt;a class=&#34;link&#34; href=&#34;https://www.armbian.com/nanopi-r2s/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方网站&lt;/a&gt; 下载对应的img（本文使用基于Ubuntu的Jammy），然后用你的工具烧录进SD卡。将R2S接入电源，指示灯应该闪烁。&lt;/p&gt;
&lt;p&gt;初始设置需要将其WAN或LAN口接到另一台 &lt;strong&gt;已经启用DHCP&lt;/strong&gt; 的路由器上，想办法找到其IP地址（比如进管理员后台），然后使用SSH登录，初始用户名和密码分别为 &lt;code&gt;root&lt;/code&gt; 和 &lt;code&gt;1234&lt;/code&gt;。注意其此时不能作为一个开箱即用的路由器，也就是说不能直接接入电脑。&lt;/p&gt;
&lt;p&gt;登入后有一个初始引导，跟着做就行了，没什么好说的。然后这就是一个标准的Linux系统了，基本可以直接遵循其他Linux的操作方法。但国内许多用户会到手换源，由于Armbian是基于其他发行版做的，所以换源不完全一样。其软件源有两个位置，均需要更改：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/etc/apt/sources.list&lt;/code&gt; 与你安装的版本所基于的发行版有关，如Armbian Jammy基于Ubuntu Jammy，就换对应的源（如 &lt;a class=&#34;link&#34; href=&#34;https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu-ports/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;清华源&lt;/a&gt;，注意Ubuntu使用Ports源）；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/apt/sources.list.d/armbian.list&lt;/code&gt; 是Armbian专属软件源，也要换（仍然如 &lt;a class=&#34;link&#34; href=&#34;https://mirrors.tuna.tsinghua.edu.cn/help/armbian/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;清华源&lt;/a&gt;）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;配置路由器功能&#34;&gt;配置路由器功能
&lt;/h2&gt;&lt;p&gt;OpenWRT说白了也是个Linux，作为一个路由器所需要的功能也有许多方案可以通过后期手动安装实现。&lt;/p&gt;
&lt;p&gt;顺着走到这一步，执行 &lt;code&gt;ip l&lt;/code&gt;，一台R2S的显示应该类似于下面这样：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plaintext&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: eth0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff
4: lan0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2: eth0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500 qdisc mq state DOWN mode DEFAULT group default qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;4: lan0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    link/ether aa:aa:aa:aa:aa:aa brd ff:ff:ff:ff:ff:ff&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;此处我把外部网络（相对，如上层路由器）插到了 &lt;code&gt;lan0&lt;/code&gt; 上，局域网设备则均连接至 &lt;code&gt;eth0&lt;/code&gt;，相当于许多OpenWRT包所做的反转WAN和LAN口。如无特别说明，后面的操作均按照这个来。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;R2S的LAN是USB 3.0转接的网卡，而WAN是PCIe网卡。进行高速传输时，USB造成的中断会大量消耗性能，所以对于内网流量，将其扔给性能更高的WAN口。R2S在小包较多时速度明显下降，也是基于同样的原因。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;dns&#34;&gt;DNS
&lt;/h3&gt;&lt;p&gt;DNS用于将主机名解析为IP地址。由于传统DNS查询是明文的，可以被中间人任意截留修改，部分运营商会进行DNS污染，以达到加广告或封锁境外网站的目的。因此，使用DoH（DHS-over-HTTPS）和DoT（DNS-over-TLS），并对国内和国外域名进行分流，就有其意义。&lt;/p&gt;
&lt;p&gt;下文介绍了几种DNS转发器的的配置方案。其中，EasyMosdns自带了较完善的方案，而TelescopeDNS的配置文件较为简明，都能有效对抗DNS污染。&lt;/p&gt;
&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;TelescopeDNS&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;p&gt;此处使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/wolf-joe/ts-dns&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Telescope DNS&lt;/a&gt; 负责监听53端口，为局域网内设备进行解析，并根据条件将其发送至不同的DNS服务器。&lt;/p&gt;
&lt;p&gt;虽然我有透明代理的需求，但是本着解耦的原则（说白了就是怕Xray-core挂掉全都上不了网），还是由单独的DNS转发器处理局域网查询吧。&lt;/p&gt;
&lt;p&gt;Armbian默认使用systemd-resolved解析DNS并占用25端口，由于其仅能监听本机请求而不能接受局域网内其他机器的请求[^7]，需要将其禁用。此外需要将 &lt;code&gt;/etc/resolv.conf&lt;/code&gt; 指向127.0.0.1以将本机的DNS查询转发至Telescope DNS。&lt;/p&gt;
&lt;p&gt;以下是我的配置文件，读者可以参考。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;toml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;listen = &amp;#34;192.168.0.1:53&amp;#34;
disable_qtypes = [&amp;#34;AAAA&amp;#34;] # 禁用 IPv6 解析

[cache]
size = 4096

[hosts] # 为 DoH 域名指定 IP 地址，防止回环解析（指解析所必需的 DoH 域名本身也需要解析）
&amp;#34;doh.pub&amp;#34; = &amp;#34;1.12.12.12&amp;#34;
&amp;#34;cloudflare-dns.com&amp;#34; = &amp;#34;1.0.0.1&amp;#34;

[groups]
  [groups.clean] # 境内域名
  doh = [&amp;#34;https://doh.pub/dns-query&amp;#34;] # 腾讯 DNSPod DoH
  dns = [&amp;#34;114.114.114.114&amp;#34;]
  concurrent = true
  no_cookie = true # DNSPod 可能需要
  redirector = &amp;#34;oversea_ip2dirty&amp;#34; # 按照下方同名 redirector 设置重定向

  [groups.dirty] # 境外域名
  dns = [&amp;#34;208.67.222.222:5353&amp;#34;, &amp;#34;176.103.130.130:5353&amp;#34;]
  doh = [&amp;#34;https://cloudflare-dns.com/dns-query&amp;#34;] # Cloudflare DoH
  gfwlist_file = &amp;#34;/etc/ts-dns/gfwlist.txt&amp;#34;

[redirectors]
  [redirectors.oversea_ip2dirty]
  # 解析后如发现ip地址不匹配cnip，则重定向到dirty组解析
  type = &amp;#34;mismatch_cidr&amp;#34;
  rules_file = &amp;#34;/etc/ts-dns/cnip.txt&amp;#34;
  dst_group = &amp;#34;dirty&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;192.168.0.1:53&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;disable_qtypes&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;AAAA&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 禁用 IPv6 解析&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cache&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;size&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;4096&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hosts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 为 DoH 域名指定 IP 地址，防止回环解析（指解析所必需的 DoH 域名本身也需要解析）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;doh.pub&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.12.12.12&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;cloudflare-dns.com&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.0.0.1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;clean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 境内域名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;doh&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://doh.pub/dns-query&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 腾讯 DNSPod DoH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;dns&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;114.114.114.114&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;concurrent&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;no_cookie&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# DNSPod 可能需要&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;redirector&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;oversea_ip2dirty&amp;#34;&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 按照下方同名 redirector 设置重定向&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;groups&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dirty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# 境外域名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;dns&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;208.67.222.222:5353&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;176.103.130.130:5353&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;doh&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;https://cloudflare-dns.com/dns-query&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;# Cloudflare DoH&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;gfwlist_file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/ts-dns/gfwlist.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;redirectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;redirectors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;oversea_ip2dirty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c&#34;&gt;# 解析后如发现ip地址不匹配cnip，则重定向到dirty组解析&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;mismatch_cidr&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;rules_file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/etc/ts-dns/cnip.txt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;dst_group&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;dirty&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;为了让本机的DNS解析通过本机的服务器，需要更改默认的DNS解析器。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;EasyMosdns&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;p&gt;Mosdns以强大的功能而闻名，但对于不想花时间配置的人来说，使用别人配好的方案也能十分舒适，比如 &lt;a class=&#34;link&#34; href=&#34;https://github.com/pmkol/easymosdns&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EasyMosdns&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;因为它和Mosdns都没有被大部分发行版打包，所以在Armbian上，需要先手动安装对应版本的Mosdns，然后将上述repo内的文件丢进对应目录。至于Systemd单元等文件，可以参见 &lt;a class=&#34;link&#34; href=&#34;https://aur.archlinux.org/packages/easymosdns-bin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AUR&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;默认监听53端口，可以在 &lt;code&gt;/etc/mosdns/config.yaml&lt;/code&gt; 中设置。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;dnsmasq 整合&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;p&gt;确实dnsmasq可以当DNS转发器啊，但因为它对DNS污染抗性比较差，所以我肯定不会单独用它的。不过可以把它套娃，在本机上做两层转发。&lt;/p&gt;
&lt;p&gt;如果你希望做两层转发，那么需要将嵌套的转发器监听端口改一下，比如5353，将这个地址改为dnsmasq的上游DNS，并且把dnsmasq的cache size设为0（否则第一次查询大概率失败）；如果你希望把dnsmasq的DNS禁掉，那么这三个设置都不用动，然后给dnsmasq加个 &lt;code&gt;-p0&lt;/code&gt; 启动参数就可以了。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;h3 id=&#34;dhcp&#34;&gt;DHCP
&lt;/h3&gt;&lt;p&gt;DHCP用于为局域网内的设备分配各自的IP地址，同时也会传递网关、默认DNS等信息。在我的网络拓扑中，由软路由充当DHCP服务器，其他设备则仅需自带的DHCP客户端。&lt;/p&gt;
&lt;p&gt;一般来说Linux的网络连接由systemd-networkd或NetworkManager之类的东西管理（包含DHCP客户端），而在基于Ubuntu的系统上有个好东西叫做Netplan，用于在前述两者等一系列工具之上再构建一层抽象，以求简化其配置。&lt;/p&gt;
&lt;p&gt;该机型Armbian的Netplan配置文件位于 &lt;code&gt;/etc/netplan/armbian-default.yaml&lt;/code&gt;。未经修改的文件类似于：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;network:
  version: 2
  renderer: NetworkManager&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;renderer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;NetworkManager&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;要将软路由作为DHCP服务器，需要先将对应接口的DHCP客户端关掉（路由器一般当然不能从局域网其他主机取得IP地址了），然后再为其单独安排一个IP地址。再次提醒，我计划把局域网设备插在 &lt;code&gt;eth0&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;network:
  version: 2
  renderer: NetworkManager
  ethernets:
    eth0:
      dhcp4: false # 这个 false 是关掉 DHCP 客户端
      addresses: [192.168.0.1/24] # 网段自定，后面对应修改&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;renderer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;NetworkManager&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ethernets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;eth0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dhcp4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 这个 false 是关掉 DHCP 客户端&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;addresses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192.168.0.1&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/24]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 网段自定，后面对应修改&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;保存后不要忘了使用 &lt;code&gt;sudo netplan try&lt;/code&gt; 测试配置文件是不是写对了，没问题的话就确认。&lt;/p&gt;
&lt;p&gt;至于DHCP服务器，我起初选择了 &lt;a class=&#34;link&#34; href=&#34;https://github.com/coredhcp/coredhcp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;coredhcp&lt;/a&gt;。其并不支持SLAAC宣告，故对IPv6环境并不友好；而dnsmasq虽然看起来麻烦，但实际上只需要动几个配置项就行了，而且对IPv6比较友好。&lt;/p&gt;
&lt;p&gt;照例是配置文件：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;server4:
    listen:
        - &amp;#34;%eth0&amp;#34; # 只监听 eth0 接口的请求
    plugins:
        - lease_time: 3600s
        - server_id: 192.168.0.1 # 填路由器 IP 就行
        - dns: 192.168.0.1 # 重要，设置为路由器 IP 以指向路由器上的 DNS
        - router: 192.168.0.1 # 网关，主路由兼具代理功能，所以这里也是路由器 IP
        - netmask: 255.255.255.0 # 子网掩码
        - range: /etc/coredhcp/leases.txt 192.168.0.2 192.168.0.254 12h # 分配地址文件，起始地址，结束地址，租约时间&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;server4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;listen&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;%eth0&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 只监听 eth0 接口的请求&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;plugins&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;lease_time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;3600s&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;server_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192.168.0.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 填路由器 IP 就行&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;dns&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192.168.0.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 重要，设置为路由器 IP 以指向路由器上的 DNS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;router&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;192.168.0.1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 网关，主路由兼具代理功能，所以这里也是路由器 IP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;netmask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;255.255.255.0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 子网掩码&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;- &lt;span class=&#34;nt&#34;&gt;range&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;/etc/coredhcp/leases.txt 192.168.0.2 192.168.0.254 12h&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 分配地址文件，起始地址，结束地址，租约时间&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&#34;nat&#34;&gt;NAT
&lt;/h3&gt;&lt;p&gt;NAT对局域网内IP和端口号二元组与外网IP和端口号二元组之间建立联系，并进行转换。此处使用的工具是 &lt;code&gt;nftables&lt;/code&gt;。依托其强大的规则体系，我们可以自由选择转发暴露的端口，以及内外能访问的服务等。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;nftables&lt;/code&gt; 官方文档 &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; 给了我们一个很好的基础配置，我也知道其他高级用途也需要依托 &lt;code&gt;nftables&lt;/code&gt;，此处按下不表。但要做到NAT，只需要用一张 &lt;code&gt;nat&lt;/code&gt; 表的 &lt;code&gt;masquerade&lt;/code&gt; 规则。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;#!/usr/sbin/nft -f

flush ruleset

define WANLINK = lan0

table ip nat {
        chain  prerouting {
                type nat hook prerouting priority -100;
        }
        chain postrouting {
                type nat hook postrouting priority 100; policy accept;
                oif $WANLINK masquerade
        }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;ch&#34;&gt;#!/usr/sbin/nft -f&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;flush&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ruleset&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;define&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WANLINK&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lan0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nat&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt;  &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nat&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prerouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;postrouting&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;nat&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;postrouting&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;oif&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$WANLINK&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;masquerade&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;要暂时应用Nftables规则，可以使用 &lt;code&gt;sudo nft -f &amp;lt;filename&amp;gt;&lt;/code&gt;，永久应用则需要将其保存到 &lt;code&gt;/etc/nftables.conf&lt;/code&gt;，并设置权限755。&lt;/p&gt;
&lt;h3 id=&#34;启用ip转发&#34;&gt;启用IP转发
&lt;/h3&gt;&lt;p&gt;只有启用代理转发，流量才能进入Netfilter的 &lt;code&gt;forward&lt;/code&gt; 链，从而不经本地用户程序而向外转发。&lt;/p&gt;
&lt;p&gt;在 &lt;code&gt;/etc/sysctl.d/&lt;/code&gt; 下新建一个文件，名字随意（如 &lt;code&gt;98-ip-forwarding.conf&lt;/code&gt;），内容为：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plaintext&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;net.ipv4.ip_forward=1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;net.ipv6.conf.all.forwarding=1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后运行 &lt;code&gt;sudo sysctl -p&lt;/code&gt; 使其生效。这样，软路由就有了将不属于它的包转发出去的能力。&lt;/p&gt;
&lt;h3 id=&#34;pppoe&#34;&gt;PPPoE
&lt;/h3&gt;&lt;p&gt;安装 &lt;code&gt;pppoeconf&lt;/code&gt;，然后运行它就可以了。它的底层是 &lt;code&gt;pppd&lt;/code&gt;，所以修改配置也需要到 &lt;code&gt;/etc/ppp/&lt;/code&gt; 里面修改。&lt;/p&gt;
&lt;p&gt;使用PPPoE上网后，会生成一个 &lt;code&gt;ppp0&lt;/code&gt; 虚拟网卡，它充当了WAN口的作用；使用原来的WAN接口是无法直接联网的。使用透明代理等需要指定接口的应用时请务必注意。&lt;/p&gt;
&lt;h2 id=&#34;进阶应用&#34;&gt;进阶应用
&lt;/h2&gt;&lt;p&gt;按照上面的步骤配置完毕后，如无意外，软路由本身和接入其的设备应该已经可以上网了。然后是一些相比OpenWrt，Armbian没有out-of-box支持的。&lt;/p&gt;
&lt;h3 id=&#34;透明代理&#34;&gt;透明代理
&lt;/h3&gt;&lt;p&gt;请阅读 &lt;a class=&#34;link&#34; href=&#34;https://cyp0633.com/post/armbian-r2s-tproxy/&#34; &gt;Armbian + R2S 番外篇：透明代理&lt;/a&gt; 一文。&lt;/p&gt;
&lt;p&gt;另外，如果使用Tailscale，实测透明代理可能会与Tailscale规则冲突（实测23/8/26有此现象），从而导致上不了网的严重问题，所幸1.48.0开始Tailscale增加了Nftables支持，将其启用似乎可以解决这个问题。在 /etc/default/tailscaled中加入 &lt;code&gt;TS_DEBUG_FIREWALL_MODE=nftables&lt;/code&gt; 即可&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;h3 id=&#34;基本防火墙&#34;&gt;基本防火墙
&lt;/h3&gt;&lt;p&gt;将这些规则加入之前的 &lt;code&gt;nftables&lt;/code&gt; 配置，可以对内外网进行基本的隔离。修改自 &lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;table inet filter {
        chain inbound {
                type filter hook input priority 0; policy drop;
                ct state vmap { established : accept, related : accept, invalid : accept } counter
                ip protocol icmp icmp type { destination-unreachable, echo-reply, echo-request, source-quench, time-exceeded } limit rate 5/second accept
                tcp dport 22 accept
                iifname vmap { lo: accept, $WANLINK : jump inbound_world, $LANLINK : jump inbound_private }
        }
        chain inbound_world {
                ip saddr { $RESERVED_IP } drop
        }
        chain inbound_private {
                ip protocol . th dport vmap { tcp . 22 : accept, udp . 53 : accept, tcp . 53 : accept, udp . 67 : accept }
        }
        chain forward {
                type filter hook forward priority 0; policy accept;
        }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inet&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inbound&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;input&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;drop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ct&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;state&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vmap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;established&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;related&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;invalid&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;counter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;icmp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;icmp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;destination&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;unreachable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;reply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;echo&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;quench&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;time&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exceeded&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;limit&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rate&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;second&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;iifname&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vmap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;lo:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$WANLINK&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;jump&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inbound_world&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$LANLINK&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;jump&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inbound_private&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inbound_world&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;saddr&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$RESERVED_IP&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;drop&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inbound_private&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;ip&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;protocol&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;th&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dport&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;vmap&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;22&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;53&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;udp&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;67&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&#34;upnp--nat-pmp&#34;&gt;UPnP / NAT-PMP
&lt;/h3&gt;&lt;p&gt;UPnP和NAT-PMP本质上是类似的东西，类似于一个自动的路由器端口映射。可以使用 &lt;a class=&#34;link&#34; href=&#34;http://miniupnp.free.fr/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MiniUPnPd&lt;/a&gt; 来实现。&lt;/p&gt;
&lt;p&gt;Ubuntu和Debian已经打包了 &lt;code&gt;miniupnpd&lt;/code&gt; 和 &lt;code&gt;miniupnpd-nftables&lt;/code&gt; 两个包，安装时会自动进入向导，分别填入内网接口（&lt;code&gt;eth0&lt;/code&gt;）和外网接口（&lt;code&gt;lan0&lt;/code&gt;），并选择启用即可。&lt;/p&gt;
&lt;h3 id=&#34;full-cone-nat&#34;&gt;Full Cone NAT
&lt;/h3&gt;&lt;p&gt;Nftables的NAT行为 &lt;code&gt;masquerade&lt;/code&gt; 是Symmetric NAT。打游戏的应该会需要Full Cone NAT，可以参考一下 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Chion82/netfilter-full-cone-nat/issues/42&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个实现&lt;/a&gt;。需要编译对应的 &lt;code&gt;libnftnl&lt;/code&gt;、&lt;code&gt;nftables&lt;/code&gt; 和 &lt;code&gt;nft&lt;/code&gt;，以及内核模块。&lt;/p&gt;
&lt;p&gt;如果你使用Xray-core透明代理，那么它已经帮你用神奇的方式实现了Full Cone NAT&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;。但在实现透明代理时，需要将所有流量转发至Xray-core进行分流，以防不同分流规则下NAT行为出现不同。&lt;/p&gt;
&lt;p&gt;另外还可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/EHfive/einat-ebpf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;einat-ebpf&lt;/a&gt;，使用时需禁用上述NAT Nftables规则中的 &lt;code&gt;MASQUERADE&lt;/code&gt; 链，实测Armbian内核支持该程序eBPF所需的内核选项，性能良好，较为易用，无需重新编译内核模块或使用第三方代理工具。&lt;/p&gt;
&lt;h3 id=&#34;mss-clamping&#34;&gt;MSS Clamping
&lt;/h3&gt;&lt;blockquote&gt;
&lt;p&gt;我不只一次见网友说自己搭的软路由访问某些网站非常慢，而换回硬路由就正常。这是因为多数家用路由器默认对IPv4下的TCP开启了MSS (maximum segment size) Clamping。&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.v2ex.com/t/800024&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;《开启 IPv6 后网速变得很慢？可能是 PMTU 黑洞的问题》&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;简而言之就是家用硬路由会自动帮你设置MSS，而软路由不会，造成被路径上丢包只能重传。进行MSS Clamping后，终于能跑满300M宽带了。&lt;/p&gt;
&lt;p&gt;在Nftables中添加以下内容：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;table inet filter {
    chain forward {
        type filter hook forward priority 0; policy accept;
        tcp flags syn tcp option maxseg size set rt mtu
    }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;table&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;inet&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;chain&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;hook&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;forward&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;priority&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;policy&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;accept&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;flags&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;syn&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;tcp&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;maxseg&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;size&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;rt&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mtu&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&#34;ipv6&#34;&gt;IPv6
&lt;/h2&gt;&lt;p&gt;以网上资料的细碎程度，IPv6其实也是一个进阶应用；但是感觉对自己来说，即使没有全局梯也不能没有IPv6，所以就挺拧巴的，这也是我把它放在最后的原因。如果你对IPv6没有那么熟悉，我强烈建议你展开下面的内容看点更拧巴的现象和我的理解，防止配完黑人问号。&lt;/p&gt;
&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;常用的路由器 IPv6 部署方案解析&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;p&gt;IPv6的情况与IPv4不同，路由器较少使用DHCPv6来为局域网设备分配IP地址（而且支持也像屎一样 [^13]），更常用的叫做无状态地址自动配置（SLAAC，StateLess Address Auto Configuration），一般来说路由器会选择LAN上前缀的一个 /64地址块，向局域网内进行宣告，然后各个主机通过某种方式，自己在这个 /64里选择一个地址（并非一个设备直接分走一个 /64，所以运营商只给 /60而不是 /56并没有什么问题；感谢 &lt;a class=&#34;link&#34; href=&#34;https://www.v2ex.com/t/1090037?p=1#r_15543774&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;V2EX @dalaoshu 的纠正&lt;/a&gt;）。因为一个 /64实在是太巨大了，所以一般也不会冲突。&lt;/p&gt;
&lt;p&gt;诶，看起来拧巴的事情来了：本人使用的长沙联通宽带，光猫已改为桥接路由器拨号；而对于PPPoE，协议本身会给路由器 &lt;code&gt;ppp0&lt;/code&gt; 指定一个 /64的地址 [^14]。不知细心的你是否发现了， 我们没说过 &lt;code&gt;ppp0&lt;/code&gt; 在委托的那个子网里面——事实上也确实不在。当执行 &lt;code&gt;ip -6 addr&lt;/code&gt; 时，就会得到以下看起来十分抽象实际上却又合理的输出（节选）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;$ ip -6 addr
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 state UP qlen 1000
    inet6 2408:aaaa:450:3650:4c43:81ff:fe4d:9cac/60 scope global
       valid_lft forever preferred_lft forever
    inet6 fe80::4c43:81ff:fe4d:9cac/64 scope link
       valid_lft forever preferred_lft forever
6: ppp0: &amp;lt;POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP&amp;gt; mtu 1492 state UNKNOWN qlen 3
    inet6 2408:bbbb:451:50b6:7a88:efdb:db94:4b77/64 scope global temporary dynamic
       valid_lft 259001sec preferred_lft 85804sec
    inet6 2408:bbbb:451:50b6:4e43:81ff:fe4d:9cac/64 scope global dynamic mngtmpaddr
       valid_lft 259001sec preferred_lft 172601sec
    inet6 fe80::4e43:81ff:fe4d:9cac peer fe80::16eb:8ff:feb2:b27d/128 scope link
       valid_lft forever preferred_lft forever&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ ip -6 addr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu &lt;span class=&#34;m&#34;&gt;65536&lt;/span&gt; state UNKNOWN qlen &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 ::1/128 scope host
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu &lt;span class=&#34;m&#34;&gt;1500&lt;/span&gt; state UP qlen &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 2408:aaaa:450:3650:4c43:81ff:fe4d:9cac/60 scope global
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 fe80::4c43:81ff:fe4d:9cac/64 scope link
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft forever preferred_lft forever
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;6: ppp0: &amp;lt;POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP&amp;gt; mtu &lt;span class=&#34;m&#34;&gt;1492&lt;/span&gt; state UNKNOWN qlen &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 2408:bbbb:451:50b6:7a88:efdb:db94:4b77/64 scope global temporary dynamic
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft 259001sec preferred_lft 85804sec
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 2408:bbbb:451:50b6:4e43:81ff:fe4d:9cac/64 scope global dynamic mngtmpaddr
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft 259001sec preferred_lft 172601sec
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    inet6 fe80::4e43:81ff:fe4d:9cac peer fe80::16eb:8ff:feb2:b27d/128 scope link
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;       valid_lft forever preferred_lft forever&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;说它抽象吧，是因为在我的直觉里，似乎IPv6不会分配私有IP，所以大家都是平等的设备，也理所应当属于一个子网；说它合理吧，是既然IP转发启用了，那么路由器就可以将其送达该有的目的地，路径也并不需要跟着网段走。事实上，WAN口的 /64是通过PPPoE的SLAAC获得的，这与LAN口的DHCPv6-PD获得的前缀来源不同，所以才会出现两个地址不在同一网段的情况。&lt;/p&gt;
&lt;p&gt;其实类比IPv4也是很好理解的：运营商给一个普通路由器的WAN口分配了一个公网IP；同时路由器通过DHCP将内网的私有地址分配给各个主机，LAN口也获得了一个该网段下的私有地址。IPv6情况其实差不多，只是上面的私有地址段变成了通过DHCPv6-PD获得的公网地址段，通过某个公网地址能够直接路由到特定的主机，无需经过NAT而已；子网内的DHCPv4也变成了SLAAC，不过结果上没区别，都是主机获得了自己的IP。&lt;/p&gt;
&lt;p&gt;评论区有人提到了IPv6的一些奇怪情况；此外关于PD和SLAAC，也可以多阅读 &lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/ipv6/comments/18z4xw8/comment/kgiraat&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文章&lt;/a&gt; 作为参考。&lt;/p&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;好的，逼叨完了，结果很明了了：我们需要配置的有&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;一个能进行DHCPv6-PD的客户端，&lt;/li&gt;
&lt;li&gt;一个能进行SLAAC宣告的程序，和&lt;/li&gt;
&lt;li&gt;让路由器本身获得IPv6。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一个事好说，用得很广泛的是 &lt;code&gt;wide-dhcpv6-client&lt;/code&gt;$^包$。安装后编辑 &lt;code&gt;/etc/wide-dhcpv6/dhcp6c.conf&lt;/code&gt;。以下给出一个示例，它从运营商请求一个非临时的前缀，然后将这个前缀委托给 &lt;code&gt;eth0&lt;/code&gt;，让 &lt;code&gt;eth0&lt;/code&gt; 获得一个 /64地址。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;perl&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-8&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-8&#34; style=&#34;display:none;&#34;&gt;interface ppp0 { # 通过 ppp0 进行 DHCPv6
    send ia-pd 0; # 发送 Prefix Delegation 消息
    send ia-na 0; # 请求非临时地址（non-temporary address）
    script &amp;#34;/etc/wide-dhcpv6/dhcp6c-script&amp;#34;;
};

id-assoc pd 0 { # PD 0 的配置
    prefix-interface eth0 { # 将前缀委托给 eth0
        sla-id 0; # SLA ID，即网段编号
        sla-len 0; # SLA 长度，即用掉整个 PD
    };
};

id-assoc na 0 {}; # NA 0 的配置，留空就行&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-perl&#34; data-lang=&#34;perl&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ppp0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 通过 ppp0 进行 DHCPv6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;send&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 发送 Prefix Delegation 消息&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;send&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ia&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;na&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 请求非临时地址（non-temporary address）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;script&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;/etc/wide-dhcpv6/dhcp6c-script&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;pd&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# PD 0 的配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;prefix&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;interface&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;eth0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 将前缀委托给 eth0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;sla&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# SLA ID，即网段编号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;sla&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;len&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# SLA 长度，即用掉整个 PD&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;assoc&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;na&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{};&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# NA 0 的配置，留空就行&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这是一个很基础的配置，如果想整更多花活，建议读 &lt;a class=&#34;link&#34; href=&#34;https://manpages.debian.org/testing/wide-dhcpv6-client/dhcp6c.conf.5.en.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;manual&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;重启一下服务，如果看到 &lt;code&gt;eth0&lt;/code&gt;（或自己定义的LAN）上有了一个大于 /64的非私有IP，那么就是成功了，不出意外的话route也会为你配好；否则可以自行使用 &lt;code&gt;dhcp6c -Df -c /path/to/conf &amp;lt;interface&amp;gt;&lt;/code&gt; 进行debug。&lt;/p&gt;
&lt;p&gt;现在连上设备并不能用SLAAC，因为我们还没有配置路由宣告。如果你已经使用 &lt;code&gt;dnsmasq&lt;/code&gt; 作为DHCP服务器，那么宣告非常简单：仅需要在配置文件中加类似下面这一行。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plaintext&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-9&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-9&#34; style=&#34;display:none;&#34;&gt;dhcp-range=::1000,::1fff,constructor:eth0,slaac,ra-names&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;dhcp-range=::1000,::1fff,constructor:eth0,slaac,ra-names&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;我来详细解释一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;即使向运营商申请了非临时前缀，也可能变，所以前缀不能写死，要自动从接口获取&lt;/li&gt;
&lt;li&gt;&lt;code&gt;constructor:eth0&lt;/code&gt; 指的是分配给 &lt;code&gt;eth0&lt;/code&gt; 的IP段&lt;/li&gt;
&lt;li&gt;&lt;code&gt;::1000,::1fff&lt;/code&gt; 指的是所有IPv6地址，当然不能给IPv4做SLAAC不是嘛&lt;/li&gt;
&lt;li&gt;&lt;code&gt;slaac&lt;/code&gt; 指的是选择外部分配的前缀，而非 &lt;code&gt;fe80&lt;/code&gt; 开头的内网IP段&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ra-names&lt;/code&gt; 代表进行SLAAC宣告，不进行DHCPv6，并将主机添加到DNS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第三个事情看起来很玄学。在远古的Linux内核中，当开启IPv6 forwarding的时候，即使 &lt;code&gt;net.ipv6.conf.all.accept_ra&lt;/code&gt; 不为0，其也会自作主张地停止进行SLAAC，导致路由器WAN（&lt;code&gt;eth0&lt;/code&gt;）接口无法获取IPv6地址；而在不那么老的内核上，将其设为2，就可以同时开启IPv6 forwarding和进行SLAAC&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;。&lt;/p&gt;
&lt;p&gt;这样，局域网下的设备就可以通过IPv6上网了，没有邪道DHCPv6。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://openwrt.org/meta/infobox/upgrade_packages_warning&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[OpenWrt Wiki] Upgrading packages may cause serious problems, including soft-bricking your device!&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://wiki.nftables.org/wiki-nftables/index.php/Simple_ruleset_for_a_home_router&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Simple ruleset for a home router&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1294/firewall-mode/#examples&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Firewall mode in tailscaled&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://oxcrag.net/2021/12/25/build-your-own-router-with-nftables-part-1/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Build your own router with nftables – Part 1&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/XTLS/Xray-core/discussions/252&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;XUDP：VLESS &amp;amp; VMess &amp;amp; Mux UDP FullCone NAT&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://strugglers.net/posts/2011/linux-ipv6-router-advertisements-and-forwarding/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://strugglers.net/posts/2011/linux-ipv6-router-advertisements-and-forwarding/&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>同步 iCloud （云上贵州）日历</title>
        <link>https://cyp0633.com/post/icloud-calendar-sync/</link>
        <pubDate>Mon, 10 Jul 2023 21:52:50 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/icloud-calendar-sync/</guid>
        <description>&lt;p&gt;作为一个Android + Apple + Windows用户，寻找跨平台数据同步方案一直是一大难题，日历也不例外。纵观全局，日历同步服务倒也不少，比如Google、Outlook和iCloud等，但Google国内根本连不上，Outlook托微软的尿性也不稳定，我这次又懒得自己部署一个，此时iCloud就成为了一个好选择。&lt;/p&gt;
&lt;p&gt;iCloud使用的也是通用的CalDAV协议，然而iCloud并没有一个开放的CalDAV配置指引，甚至连服务器都不给。手动配置也不难，要配置一个CalDAV客户端，一般需要服务器地址、用户名和密码。用户名就是你的iCloud邮箱地址，即xxx@icloud.com。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;icloud-calendar-sync/macos-icloud.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;macOS 上并不支持授权 CalDAV&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;macOS 上并不支持授权 CalDAV&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;客户端支持情况&#34;&gt;客户端支持情况
&lt;/h2&gt;&lt;p&gt;有的日历客户端需要手动配置服务器地址，但有的不用。但除了iOS和macOS系统自带的日历客户端，其他大部分都需要获取App专用密码。&lt;/p&gt;
&lt;p&gt;以下是我使用过的几个客户端，以及它们对手动配置服务器地址的需求情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;iOS、macOS等苹果第一方客户端&lt;/strong&gt;：当然不需要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MIUI日历&lt;/strong&gt;：不需要（不含HyperOS）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows日历&lt;/strong&gt;：不需要&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Thunderbird&lt;/strong&gt;：需要*&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;* 可以使用TbSync插件同步国际版iCloud，但不适用于云上贵州&lt;/p&gt;
&lt;p&gt;如下图，需要手动填入“位置”的即为需要获取服务器地址。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;icloud-calendar-sync/thunderbird-new-calendar.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Thunderbird 创建新日历&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Thunderbird 创建新日历&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;获取密码&#34;&gt;获取密码
&lt;/h2&gt;&lt;p&gt;众所周知，仅凭Apple ID和其密码当然过不了二步验证，验证码都没地方输。好在可以创建App专用密码。&lt;/p&gt;
&lt;p&gt;在 &lt;a class=&#34;link&#34; href=&#34;https://appleid.apple.com/account/manage&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Apple ID 管理页面&lt;/a&gt; 的下方找到 “App专用密码”，创建一个，然后暂存下来，这个密码之后不会再出现。每个专用密码都等效，所以建议对每个应用使用不同的专用密码。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;icloud-calendar-sync/app-specific-password.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;App 专用密码&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;App 专用密码&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;获取服务器地址&#34;&gt;获取服务器地址
&lt;/h2&gt;&lt;h3 id=&#34;方法一分析请求&#34;&gt;方法一：分析请求
&lt;/h3&gt;&lt;p&gt;苹果没有给服务器地址，但网络上有现成的获取方法，如 &lt;a class=&#34;link&#34; href=&#34;https://frightanic.com/apple-mac/thunderbird-icloud-calendar-sync/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个&lt;/a&gt;。但是已经过去了五年，在云上贵州的环境中又有点不同。长话短说，就是把icloud.com换成icloud.com.cn，然后自己摸索起来应该也不难。&lt;/p&gt;
&lt;p&gt;仿照那个教程的获取方法，iCloud云上贵州的CalDAV服务器地址格式为：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;https://&amp;lt;server-id&amp;gt;-caldav.icloud.com.cn/&amp;lt;user-id&amp;gt;/calendars/&amp;lt;calendar-id&amp;gt;/&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://&amp;lt;server-id&amp;gt;-caldav.icloud.com.cn/&amp;lt;user-id&amp;gt;/calendars/&amp;lt;calendar-id&amp;gt;/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;server-id&amp;gt;&lt;/code&gt; 是数字和字母混合的字符串，我的是4位；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;user-id&amp;gt;&lt;/code&gt; 是一串数字，我的是11位；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;calendar-id&amp;gt;&lt;/code&gt; 是一个用 &lt;code&gt;-&lt;/code&gt; 分隔的、全部大写的UUID。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;需要注意，一个CalDAV地址对应一个日历，如果有多个日历必须在下面的步骤中重复操作。&lt;/p&gt;
&lt;p&gt;现在打开你的iCloud网页版，打开浏览器的开发者选项-网络，然后在日历页面双击任意一个事件，进入详情。&lt;/p&gt;
&lt;p&gt;在开发者选项中过滤“XHR”请求，然后找到传输这个事件详细信息的GET请求，例如下图：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;icloud-calendar-sync/request.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;对应请求&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;找到这个请求URL，它大概是以下格式：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;https://&amp;lt;server-id&amp;gt;-calendarws.icloud.com.cn/ca/eventdetail/&amp;lt;calendar-id&amp;gt;/&amp;lt;event-id&amp;gt;?clientBuildNumber=&amp;lt;some-random-text&amp;gt;&amp;amp;clientId=&amp;lt;some-random-text&amp;gt;&amp;amp;clientMasteringNumber=&amp;lt;some-random-text&amp;gt;&amp;amp;clientVersion=&amp;lt;some-random-text&amp;gt;&amp;amp;dsid=&amp;lt;user-id&amp;gt;&amp;amp;lang=&amp;lt;some-random-text&amp;gt;&amp;amp;requestID=&amp;lt;some-random-text&amp;gt;&amp;amp;usertz=&amp;lt;some-random-text&amp;gt;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;https://&amp;lt;server-id&amp;gt;-calendarws.icloud.com.cn/ca/eventdetail/&amp;lt;calendar-id&amp;gt;/&amp;lt;event-id&amp;gt;?clientBuildNumber=&amp;lt;some-random-text&amp;gt;&amp;amp;clientId=&amp;lt;some-random-text&amp;gt;&amp;amp;clientMasteringNumber=&amp;lt;some-random-text&amp;gt;&amp;amp;clientVersion=&amp;lt;some-random-text&amp;gt;&amp;amp;dsid=&amp;lt;user-id&amp;gt;&amp;amp;lang=&amp;lt;some-random-text&amp;gt;&amp;amp;requestID=&amp;lt;some-random-text&amp;gt;&amp;amp;usertz=&amp;lt;some-random-text&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;或许你得到的request param会有所不同，但只要能找出你链接中的对应位置，提取出上面提到的三个ID就行了。如果发现提取不出来，请评论。&lt;/p&gt;
&lt;p&gt;将上面三个ID填入上面的CalDAV服务器地址中，就可以得到你的CalDAV服务器地址了。&lt;/p&gt;
&lt;h3 id=&#34;方法二miui日历&#34;&gt;方法二：MIUI日历
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;更新&lt;/strong&gt;：HyperOS的日历已经去掉iCloud登录功能。&lt;/p&gt;
&lt;p&gt;如果你恰好有一台小米手机，那么可以直接在MIUI日历中添加iCloud日历，MIUI会自动获取服务器地址，也能正确处理云上贵州链接。在日历详细信息页面，你就可以提取出对应的日历地址。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;icloud-calendar-sync/xiaomi-icloud-integration.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;MIUI 日历可以正确提取链接&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;MIUI 日历可以正确提取链接&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;方法三工具提取&#34;&gt;方法三：工具提取
&lt;/h3&gt;&lt;p&gt;可以试一下以下的工具（未经验证）：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/midnightmonster/icloud-calendar-urls&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;midnightmonster/icloud-calendar-urls&lt;/a&gt;（需要macOS环境）&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/muhlba91/icloud-caldav-urls&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;muhlba91/icloud-caldav-urls&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>写一个 WordPress 评论转换工具</title>
        <link>https://cyp0633.com/post/wp-comment-converter/</link>
        <pubDate>Thu, 15 Jun 2023 21:43:40 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/wp-comment-converter/</guid>
        <description>&lt;p&gt;在把博客迁出WordPress的时候难免要一块儿把评论迁出来。怪了，全网常用的评论系统，Valine，Twikoo，怎么就没有WordPress导入呢？另一个评论系统，Artalk，倒是有个Artransfer工具，通过WordPress全部的导出文件解析评论，导出Artrans格式。但sadly, it simply didn&amp;rsquo;t work. 它也并不能很好地处理重定向。&lt;/p&gt;
&lt;p&gt;那总不能把评论一个一个输到Twikoo里面吧，那未免太不优雅了。何况即使五分钟手工能干成的事情，也要花两个小时去自动化完成（狗头）。&lt;/p&gt;
&lt;h2 id=&#34;导出方法&#34;&gt;导出方法
&lt;/h2&gt;&lt;p&gt;WordPress备份文件的组织形式我觉得挺麻的，幸好还有另一种获取评论的方式，即REST API。该接口虽然是公开的，但是在进行认证之后，可以读取到评论的全部信息，包括发送者邮箱、IP和user-agent等。而在以前使用的全部资料导出方式中，根本没办法导出UA。&lt;/p&gt;
&lt;p&gt;读出来某条评论大概是这个样子：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;    {
        &amp;#34;id&amp;#34;: 123, // 评论 ID
        &amp;#34;post&amp;#34;: 2345, // 文章 ID，即代表 /archives/2345 的那篇文章
        &amp;#34;parent&amp;#34;: 0, // 父评论 ID，0 代表没有父评论
        &amp;#34;author&amp;#34;: 0, // 作者 ID，0 代表未登录用户
        &amp;#34;author_name&amp;#34;: &amp;#34;AuthorName&amp;#34;, // 作者名
        &amp;#34;author_email&amp;#34;: &amp;#34;author@example.com&amp;#34;, // 作者邮箱
        &amp;#34;author_url&amp;#34;: &amp;#34;https:\/\/example.com&amp;#34;, // 作者网站
        &amp;#34;author_ip&amp;#34;: &amp;#34;1.1.1.1&amp;#34;, // 发送 IP
        &amp;#34;author_user_agent&amp;#34;: &amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0&amp;#34;, // 发送者浏览器 UA
        &amp;#34;date&amp;#34;: &amp;#34;2000-00-00T00:00:00&amp;#34;, // 本地和 GMT 发送时间
        &amp;#34;date_gmt&amp;#34;: &amp;#34;2000-00-00T00:00:00&amp;#34;,
        &amp;#34;content&amp;#34;: {
            &amp;#34;rendered&amp;#34;: &amp;#34;content&amp;#34;, // HTML 评论内容
            &amp;#34;raw&amp;#34;: &amp;#34;&amp;#34; // 纯文字评论内容
        },
        &amp;#34;link&amp;#34;: &amp;#34;&amp;#34;, // 评论链接，指向对应文章的对应评论
        &amp;#34;status&amp;#34;: &amp;#34;approved&amp;#34;, // 是否过审
        &amp;#34;type&amp;#34;: &amp;#34;comment&amp;#34;, // 好像只有 comment
        &amp;#34;author_avatar_urls&amp;#34;: { // 三种尺寸的头像链接。很难想象 WordPress 会直接预存三种链接，虽然都是 Gravatar 的
            &amp;#34;24&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;48&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;96&amp;#34;: &amp;#34;&amp;#34;
        },
        &amp;#34;meta&amp;#34;: [], // 用于存放一些额外的 metadata
        &amp;#34;_links&amp;#34;: { // 相关 API endpoint
            &amp;#34;self&amp;#34;: [
                {
                    &amp;#34;href&amp;#34;: &amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments\/123&amp;#34;
                }
            ],
            &amp;#34;collection&amp;#34;: [
                {
                    &amp;#34;href&amp;#34;: &amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments&amp;#34;
                }
            ],
            &amp;#34;children&amp;#34;: [
                {
                    &amp;#34;embeddable&amp;#34;: true,
                    &amp;#34;href&amp;#34;: &amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments?parent=123&amp;#34;
                }
            ]
        }
    },&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;123&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 评论 ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;post&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;2345&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 文章 ID，即代表 /archives/2345 的那篇文章
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 父评论 ID，0 代表没有父评论
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 作者 ID，0 代表未登录用户
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AuthorName&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 作者名
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_email&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;author@example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 作者邮箱
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_url&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https:\/\/example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 作者网站
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;1.1.1.1&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 发送 IP
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_user_agent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:89.0) Gecko/20100101 Firefox/89.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 发送者浏览器 UA
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2000-00-00T00:00:00&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 本地和 GMT 发送时间
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;date_gmt&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2000-00-00T00:00:00&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;rendered&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// HTML 评论内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;raw&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 纯文字评论内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;link&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 评论链接，指向对应文章的对应评论
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;approved&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 是否过审
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;comment&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 好像只有 comment
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;author_avatar_urls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 三种尺寸的头像链接。很难想象 WordPress 会直接预存三种链接，虽然都是 Gravatar 的
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;24&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;48&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;96&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;meta&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 用于存放一些额外的 metadata
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;_links&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;// 相关 API endpoint
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;self&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nt&#34;&gt;&amp;#34;href&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments\/123&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;collection&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nt&#34;&gt;&amp;#34;href&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;children&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nt&#34;&gt;&amp;#34;embeddable&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;nt&#34;&gt;&amp;#34;href&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https:\/\/example.com\/wp-json\/wp\/v2\/comments?parent=123&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;详细解析见 &lt;a class=&#34;link&#34; href=&#34;https://developer.wordpress.org/rest-api/reference/comments/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WordPress REST API Handbook&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;要获取完整内容，需要在WordPress后台-用户-个人资料中生成一个“应用程序密码”（或使用 &lt;a class=&#34;link&#34; href=&#34;https://developer.wordpress.org/rest-api/using-the-rest-api/authentication&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;其他认证方式&lt;/a&gt;），然后在请求中加入对应的认证信息，并将 &lt;code&gt;context&lt;/code&gt; 设为 &lt;code&gt;edit&lt;/code&gt;。比如使用cURL：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;curl --user &amp;#34;username:password&amp;#34; -X GET https://example.com/wp-json/wp/v2/comments?context=edit&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl --user &lt;span class=&#34;s2&#34;&gt;&amp;#34;username:password&amp;#34;&lt;/span&gt; -X GET https://example.com/wp-json/wp/v2/comments?context&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;edit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&#34;输出格式&#34;&gt;输出格式
&lt;/h2&gt;&lt;p&gt;作为一个Twikoo用户，为什么不输出为Twikoo JSON呢，是因为不想用吗？&lt;/p&gt;
&lt;p&gt;想啊，很想啊，但只有Artalk的 &lt;a class=&#34;link&#34; href=&#34;https://artalk.js.org/guide/transfer.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Artran&lt;/a&gt; 有现成的格式定义，而且数据定义也相对简单，起码比逆向Twikoo JSON简单得多。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;{
    &amp;#34;id&amp;#34;: &amp;#34;123&amp;#34;, 
    &amp;#34;rid&amp;#34;: &amp;#34;233&amp;#34;, 
    &amp;#34;content&amp;#34;: &amp;#34;Hello Artalk&amp;#34;, 
    &amp;#34;ua&amp;#34;: &amp;#34;Artalk/6.6&amp;#34;, 
    &amp;#34;ip&amp;#34;: &amp;#34;233.233.233.233&amp;#34;,
    &amp;#34;created_at&amp;#34;: &amp;#34;2021-10-28 20:50:15 &amp;#43;0800 &amp;#43;0800&amp;#34;, 
    &amp;#34;updated_at&amp;#34;: &amp;#34;2021-10-28 20:50:15 &amp;#43;0800 &amp;#43;0800&amp;#34;, 
    &amp;#34;is_collapsed&amp;#34;: &amp;#34;false&amp;#34;, 
    &amp;#34;is_pending&amp;#34;: &amp;#34;false&amp;#34;, 
    &amp;#34;vote_up&amp;#34;: &amp;#34;666&amp;#34;, 
    &amp;#34;vote_down&amp;#34;: &amp;#34;0&amp;#34;, 
    &amp;#34;nick&amp;#34;: &amp;#34;qwqcode&amp;#34;, 
    &amp;#34;email&amp;#34;: &amp;#34;qwqcode@github.com&amp;#34;, 
    &amp;#34;link&amp;#34;: &amp;#34;https://qwqaq.com&amp;#34;, 
    &amp;#34;password&amp;#34;: &amp;#34;&amp;#34;, 
    &amp;#34;badge_name&amp;#34;: &amp;#34;管理员&amp;#34;, 
    &amp;#34;badge_color&amp;#34;: &amp;#34;#FF716D&amp;#34;, 
    &amp;#34;page_key&amp;#34;: &amp;#34;https://artalk.js.org/guide/transfer.html&amp;#34;, 
    &amp;#34;page_title&amp;#34;: &amp;#34;数据迁移&amp;#34;, 
    &amp;#34;page_admin_only&amp;#34;: &amp;#34;false&amp;#34;, 
    &amp;#34;site_name&amp;#34;: &amp;#34;Artalk&amp;#34;,
    &amp;#34;site_urls&amp;#34;: &amp;#34;http://localhost:3000/demo/,https://artalk.js.org&amp;#34;
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;123&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;rid&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;233&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Hello Artalk&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ua&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Artalk/6.6&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;233.233.233.233&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;created_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2021-10-28 20:50:15 +0800 +0800&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;updated_at&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2021-10-28 20:50:15 +0800 +0800&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;is_collapsed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;is_pending&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;vote_up&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;666&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;vote_down&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;nick&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;qwqcode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;email&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;qwqcode@github.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;link&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://qwqaq.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;password&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;badge_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;管理员&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;badge_color&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;#FF716D&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;page_key&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://artalk.js.org/guide/transfer.html&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;page_title&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;数据迁移&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;page_admin_only&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;false&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;site_name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Artalk&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;site_urls&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://localhost:3000/demo/,https://artalk.js.org&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;文档示例，简单易懂，对吧？唯一需要解释的就是 &lt;code&gt;rid&lt;/code&gt;，即父评论ID。在不存在父评论的时候，可以直接设为0。&lt;/p&gt;
&lt;p&gt;实际上只含有下面的这些字段的话，也能用：&lt;code&gt;id&lt;/code&gt;、&lt;code&gt;rid&lt;/code&gt;、&lt;code&gt;content&lt;/code&gt;、&lt;code&gt;ua&lt;/code&gt;、&lt;code&gt;ip&lt;/code&gt;、&lt;code&gt;is_collapsed&lt;/code&gt;、&lt;code&gt;created_at&lt;/code&gt;、&lt;code&gt;updated_at&lt;/code&gt;、&lt;code&gt;nick&lt;/code&gt;、&lt;code&gt;email&lt;/code&gt;、&lt;code&gt;link&lt;/code&gt;、&lt;code&gt;page_key&lt;/code&gt;。在不太复杂的情况下，&lt;code&gt;page_key&lt;/code&gt; 可以仅写作 &lt;code&gt;/guide/transfer.html&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;链接重定向&#34;&gt;链接重定向
&lt;/h2&gt;&lt;p&gt;如果迁移前后的评论系统附属网站permalink的格式不一样，那么评论的 &lt;code&gt;page_key&lt;/code&gt; 也要做相应的修改。个人迁移前后的博客站点暂时是同时开放的，而迁移后Hugo也可以方便地设立重定向页面。&lt;/p&gt;
&lt;p&gt;举个例子吧，假设原页面为old.example.com/archives/2345，对应新页面为new.example.com/post/new-post，则Hugo设立alias之后会在new.example.com/archives/2345生成一个重定向页面，内容为：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;html&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;#34;zh-cn&amp;#34;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;https://new.example.com/post/new-post/&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&amp;#34;canonical&amp;#34; href=&amp;#34;https://new.example.com/post/new-post/&amp;#34;&amp;gt;
    &amp;lt;meta name=&amp;#34;robots&amp;#34; content=&amp;#34;noindex&amp;#34;&amp;gt;
    &amp;lt;meta charset=&amp;#34;utf-8&amp;#34;&amp;gt;
    &amp;lt;meta http-equiv=&amp;#34;refresh&amp;#34; content=&amp;#34;0; url=https://new.example.com/post/new-post/&amp;#34;&amp;gt;
  &amp;lt;/head&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;html&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;lang&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;zh-cn&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;https://new.example.com/post/new-post/&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;title&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;link&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;rel&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;canonical&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;href&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;https://new.example.com/post/new-post/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;robots&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;noindex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;charset&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;meta&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;http-equiv&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;refresh&amp;#34;&lt;/span&gt; &lt;span class=&#34;na&#34;&gt;content&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;0; url=https://new.example.com/post/new-post/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;head&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;html&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;假设我们在之前的WordPress REST API中已经获取到旧WordPress网站中某条评论的 &lt;code&gt;post&lt;/code&gt; 字段值为2345，那么只需要访问new.example.com/archives/2345，运用正则表达式提取refresh URL即可提取到新的 &lt;code&gt;page_key&lt;/code&gt;，即 &lt;code&gt;/post/new-post&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;代码实现&#34;&gt;代码实现
&lt;/h2&gt;&lt;p&gt;见 &lt;a class=&#34;link&#34; href=&#34;https://github.com/cyp0633/WP2Artran&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub repo&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;后记&#34;&gt;后记
&lt;/h2&gt;&lt;p&gt;写完程序之后，我变成了一个Artalk用户。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>逃离 WordPress</title>
        <link>https://cyp0633.com/post/escape-from-wordpress/</link>
        <pubDate>Sat, 10 Jun 2023 20:08:14 +0800</pubDate>
        
        <guid>https://cyp0633.com/post/escape-from-wordpress/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;迁移博客或许是每一个Blogger的宿命。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;动机&#34;&gt;动机
&lt;/h2&gt;&lt;p&gt;如你所见，这是一个Hugo站点。而在这个域名中，曾经运行着WordPress。&lt;/p&gt;
&lt;p&gt;你或许知道我的博客本来是WordPress的，而WordPress虽然大而全，但作为一个博客来说确实有点太重了。这倒不是“我可以不用你不能没有”的问题，而是不用就要关掉的问题，留着就会有各种漏洞，虽然网站没啥真正有价值的东西，但怪烦的。基于维护性和可移植性的优势，我早就想用静态网站生成器代替WP了（这个在&lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/archives/2141&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;两周年的文章&lt;/a&gt;中有提到），但苦于重定向做起来怪麻烦的，便一直拖着没有做。&lt;/p&gt;
&lt;p&gt;那为什么下定决心了呢？还是因为WordPress的可维护性。当初我将网站从Vultr迁到腾讯云，一部分也是因为承载的网站越来越多，天天干爆内存，然后每次 &lt;code&gt;mariadbd&lt;/code&gt; 就会当炮灰被杀掉。腾讯云轻量香港确实爽，2G RAM随便造……了一年。就在前两天，这个现象又出现了。很快，服务器的硬盘也不知道怎么回事就满了（不是swap的锅），这次死的又是 &lt;code&gt;mariadbd&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;之所以迁移起来困难，一直没干，一方面是因为目录结构不同，需要逐个手动重定向；而另一方面是WordPress上还有很多条评论，我不想丢掉。和这两者比起来，把文章扒下来转成Markdown反而成了相对容易的工作。&lt;/p&gt;
&lt;h2 id=&#34;托管生成器和主题&#34;&gt;托管、生成器和主题
&lt;/h2&gt;&lt;p&gt;虽然静态网站可以直接用Caddy去serve，但本着 &lt;del&gt;“用自己的不如用别人的”&lt;/del&gt; 尽量减少故障的原则，选择一般人使用的第三方托管方案，而这意味着又要经历常见的服务商选择问题了。老实说，Netlify、Vercel和GitHub Pages用户群都挺多，体验也都不错；微软的新服务Azure Static Web App也还可以，甚至有香港数据中心，但它是依托GitHub Actions的，build起来有点慢，最重要的原因是Azure那令人发指的控制台。看起来Netlify在中国大陆的速度比Vercel快一点，又没有GH Pages被墙得那么多，试了试几种网络环境发现没有什么访问问题，所以就选了Netlify。&lt;/p&gt;
&lt;p&gt;没有选择Azure还有一个重要的原因。头抬起，这是Azure的控制面板，可看到为粗糙的边缘，请坐和放宽：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;escape-from-wordpress/azure-dashboard.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Azure 控制面板&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;至于网站生成器的选择，老实说，考虑到我稀烂的前端水平，我的选择有点跟着主题走，顶多对主题进行一点魔改。做出这个决定时，有hexo-theme-icarus和hugo-theme-stack两个选择摆在我面前，最终因为我对Go的喜爱（以及前者带有jQuery）而选择了后者。&lt;/p&gt;
&lt;p&gt;加载首页只需要200KB出头，相比之前去掉图片还有2MB，很香啊！还能细粒度控制KaTeX加载，这么久终于体会到了抠流量的快感（误）。&lt;/p&gt;
&lt;p&gt;Hugo的主题有一个好，就是不用学PHP就可以魔改，我 &lt;del&gt;大概可能也许&lt;/del&gt; 有能力按照自己的需求改一改 &lt;del&gt;吧&lt;/del&gt;。&lt;/p&gt;
&lt;p&gt;当前进度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 选择托管平台：Netlify&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 选择生成器：Hugo&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 选择主题：hugo-theme-stack&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 魔改主题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;文章&#34;&gt;文章
&lt;/h2&gt;&lt;p&gt;Markdown导出WordPress文章这件事，&lt;a class=&#34;link&#34; href=&#34;https://kevquirk.com/how-to-convert-wordpress-to-markdown/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;有人做过解决方案了&lt;/a&gt;，导出的Markdown有front matter，看起来交给Hugo基本没有什么阻碍。但是实际操作起来坑还是很多的，光是把文章导出再导入，就花了我三天时间 &lt;del&gt;（一边摸鱼）&lt;/del&gt;。&lt;/p&gt;
&lt;p&gt;其一是图片的存储必须要整个移走，之前WordPress历经了三种存储图片方式，分别是WordPress自带图片存储、Cloudreve + OneDrive存储，最后是阿里云对象存储。自己铲屎山的时候才意识到，这三种方式实质上混杂在文章之中，而且由于WordPress问题，内部图片也是通过指向网站的链接管理的，也就是说WordPress存储的图片还要分IP+端口、域名+端口和域名访问。一不做二不休，干脆直接换个存储桶吧，路径正好也跟页面的slug对应，折腾起来也会容易很多。顺便推荐一波Cyberduck，比阿里的OSS Browser好用多了。&lt;/p&gt;
&lt;p&gt;其二是各种复杂样式问题，包括但不限于分栏、复杂表格等，不可否认用WordPress的可视化编辑器确实很方便，但如文字颜色等属性是基于自定义CSS class实现的，&lt;/p&gt;
&lt;p&gt;当前进度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 导出WordPress文章&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 导入文章&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 设定分类&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 设定标签&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; i18n&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 友链&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;评论&#34;&gt;评论
&lt;/h2&gt;&lt;p&gt;评论是博客重要的内容，我的计划是写个小工具，从WordPress的REST API导出评论，然后导入第三方评论工具。这个事情会在所有文章都搬过来之后去做。&lt;/p&gt;
&lt;p&gt;基于上面好线路服务器资源紧缺的现状，我挑选评论系统时将资源消耗放在了较重要的地位，也就自然盯上了无Node.js后端的Commento和Remark42。然而前者需要PostgreSQL，后者文档不太明白不说，还需要额外的注册登录才能评论，这与之前填入基本信息即可评论的初衷不符，于是转向了Twikoo。其使用Docker自行搭建的情况下，仅占用了70MB内存，文章详情页也仅需多加载150KB左右，算下来还是比较节省资源的。&lt;/p&gt;
&lt;p&gt;果然，用的人多是有原因的……&lt;/p&gt;
&lt;p&gt;当然也不是用的人少就一定不好用，毕竟我最后还是反复横跳到了Artalk。可选的多站点支持，50KB额外开销，Go后端，完善的文档……该给的确实都给了。折腾这么多，现在应该能安心了吧。&lt;/p&gt;
&lt;p&gt;如果你对我做的转换工具感兴趣，可以查看下方链接。&lt;/p&gt;
&lt;p&gt;当前进度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 部署新评论系统：Artalk&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 写转换工具：&lt;a class=&#34;link&#34; href=&#34;https://github.com/cyp0633/WP2Artran&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/cyp0633/WP2Artran&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 导出，再导入&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;重定向&#34;&gt;重定向
&lt;/h2&gt;&lt;p&gt;把评论都搬过来后，WordPress站点基本就没有值得留意的东西了，这个时候就可以把WordPress的permalink重定向到Hugo来了。&lt;/p&gt;
&lt;p&gt;最后发现RSS倒是做了重定向，但是某些固定页面没做，就直接把DNS改了。之前那些页面就寄掉了。还好筛选过，也没有太大损失。&lt;/p&gt;
&lt;p&gt;当前进度：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 设置文章重定向：Hugo aliases已经做好了&lt;/li&gt;
&lt;li&gt;&lt;input checked=&#34;&#34; disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; 设置RSS、友链等固定链接重定向&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;后记&lt;/strong&gt; 熟悉Netlify的读者应该知道，同一个站点可以分配多个domain。在上面的一切都做完之后，我将新博客放在了 &amp;lt;next.cyp0633.icu&amp;gt;，让它跟旧博客共存了一段时间。再确认运行正常之后，我将 &amp;lt;cyp0633.icu&amp;gt; 也指向了新博客，就此宣告了旧站的结局。然而Google搜索认为 &amp;lt;next.cyp0633.icu&amp;gt; 是规范网址，换言之不再索引 &amp;lt;cyp0633.icu&amp;gt;。可以在 &lt;code&gt;netlify.toml&lt;/code&gt; 中添加如下的重定向规则，以直接将 &amp;lt;next.cyp0633.icu&amp;gt; 重定向到 &amp;lt;cyp0633.icu&amp;gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;toml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[[redirects]]
  from = &amp;#34;https://next.cyp0633.icu/*&amp;#34;
  to = &amp;#34;https://cyp0633.icu/:splat&amp;#34;
  status = 301
  force = true&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;[[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;redirects&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://next.cyp0633.icu/*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;to&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;https://cyp0633.icu/:splat&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;301&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;force&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
</description>
        </item>
        <item>
        <title>用 Rust uutils 替换 Windows PowerShell 内置 cmdlet</title>
        <link>https://cyp0633.com/post/%E7%94%A8-rust-uutils-%E6%9B%BF%E6%8D%A2-windows-powershell-%E5%86%85%E7%BD%AE-cmdlet/</link>
        <pubDate>Sat, 20 May 2023 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/%E7%94%A8-rust-uutils-%E6%9B%BF%E6%8D%A2-windows-powershell-%E5%86%85%E7%BD%AE-cmdlet/</guid>
        <description>&lt;p&gt;&lt;strong&gt;更新&lt;/strong&gt;：适用于Linux的Windows子系统（WSL2）&lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/WSL/releases/tag/2.0.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;已更新 2.0 版本&lt;/a&gt;，一定程度上解决了之前占用端口等弊病。再加上之前更新的许多实用功能，个人已经使用WSL2的zsh基本代替了Windows下的PowerShell，故本文的意义不再像以前那么大。&lt;/p&gt;
&lt;p&gt;uutils是一个用Rust重写的GNU Coreutils，也就是Linux上的 &lt;code&gt;cp&lt;/code&gt;、&lt;code&gt;mv&lt;/code&gt;、&lt;code&gt;touch&lt;/code&gt; 等程序的一个实现。虽然在Windows的PowerShell中执行这些命令也能得到类似于Linux的结果，但实际上是一个PowerShell内置cmdlet的alias，在某些情况下的兼容性并不是那么好。本文探索一种用uutils的命令替代PowerShell内置cmdlet的方法，以让Windows的命令行体验更加Unix化（虽然还是没那么Unix就是了）。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/uutils/coreutils&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;uutils/coreutils&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;安装uutils&#34;&gt;安装uutils
&lt;/h2&gt;&lt;p&gt;可以使用预编译的二进制安装，也可以使用源代码编译安装。由于后面添加自动补全还需要源代码，所以我选择后者。&lt;/p&gt;
&lt;p&gt;如果不需要shell自动补全，那么可以直接从上面GitHub仓库的releases下载对应的压缩包（coreutils-version-x86_64-pc-windows-{msvc|gnu}.zip），将解压后的coreutils.exe放在任何一个PATH下的目录下即可。至于如何添加PATH，此处不再赘述，很容易搜到。&lt;/p&gt;
&lt;p&gt;默认编译或下载到的是multi-call binary，即调用方式为 &lt;code&gt;coreutils.exe &amp;lt;command&amp;gt;&lt;/code&gt;，本文也按照这个情况书写。也可以编译为分离的二进制文件，具体请参考上面的GitHub Readme。&lt;/p&gt;
&lt;p&gt;编译源代码需要先 &lt;a class=&#34;link&#34; href=&#34;https://www.rust-lang.org/tools/install&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;安装 Rust 工具链&lt;/a&gt;，未安装的请移步教程。&lt;/p&gt;
&lt;p&gt;在你认为合适的位置，使用以下命令将其安装到Rust存放二进制文件的地方：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;git clone https://github.com/uutils/coreutils
cd coreutils
cargo install --path . --features windows&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;git&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clone&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;//&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;github&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;com&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;uutils&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;coreutils&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;coreutils&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;cargo&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;-features&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;windows&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;编译出的二进制文件一般在 %HomePath%/.cargo/bin里面，应该是默认添加到PATH的。安装完成后可以开一个新的PowerShell，运行 &lt;code&gt;coreutils&lt;/code&gt; 以验证是否安装完成。&lt;/p&gt;
&lt;h2 id=&#34;为powershell添加自动补全&#34;&gt;为PowerShell添加自动补全
&lt;/h2&gt;&lt;p&gt;自动补全的主要用处大概是输入参数的时候能够按tab补全，如 &lt;code&gt;ls --di&lt;/code&gt; 按下tab可以补全为 &lt;code&gt;ls --directory&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;有点类似于Bash的. bashrc初始化脚本，PowerShell的自定义设置由profile管理。用户profile的路径内置于PowerShell的 $profile环境变量，可以直接在PowerShell中运行 &lt;code&gt;notepad $profile&lt;/code&gt; 来编辑。&lt;/p&gt;
&lt;p&gt;但自动补全文本量很大，可以将每个命令的补全各自写入一个文件，然后在profile中引用。对于把补全文件放在同一个文件夹内的情况，可以在profile中添加以下内容：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;$completionsPath = &amp;#34;C:\path\to\completions&amp;#34;  # Replace with the path to your completions directory

# Get all completion script files in the specified directory
$completionScripts = Get-ChildItem -Path $completionsPath -Filter &amp;#34;*.ps1&amp;#34; -File

# Load each completion script
foreach ($script in $completionScripts) {
    . $script.FullName
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$completionsPath&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C:\path\to\completions&amp;#34;&lt;/span&gt;  &lt;span class=&#34;c&#34;&gt;# Replace with the path to your completions directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Get all completion script files in the specified directory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$completionScripts&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Get-ChildItem&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$completionsPath&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Filter&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;*.ps1&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-File&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c&#34;&gt;# Load each completion script&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$script&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$completionScripts&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$script&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;FullName&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这样就可以加载C:\path\to\completions（自己定义）里的补全预设了。&lt;/p&gt;
&lt;p&gt;然后回到coreutils的源代码文件夹中，用PowerShell执行以下命令：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;foreach($cmd in&amp;#39;b2sum&amp;#39;,&amp;#39;b3sum&amp;#39;,&amp;#39;base32&amp;#39;,&amp;#39;base64&amp;#39;,&amp;#39;basename&amp;#39;,&amp;#39;basenc&amp;#39;,&amp;#39;cat&amp;#39;,&amp;#39;cksum&amp;#39;,&amp;#39;comm&amp;#39;,&amp;#39;cp&amp;#39;,&amp;#39;csplit&amp;#39;,&amp;#39;cut&amp;#39;,&amp;#39;date&amp;#39;,&amp;#39;dd&amp;#39;,&amp;#39;df&amp;#39;,&amp;#39;dir&amp;#39;,&amp;#39;dircolors&amp;#39;,&amp;#39;dirname&amp;#39;,&amp;#39;du&amp;#39;,&amp;#39;echo&amp;#39;,&amp;#39;env&amp;#39;,&amp;#39;expand&amp;#39;,&amp;#39;expr&amp;#39;,&amp;#39;factor&amp;#39;,&amp;#39;false&amp;#39;,&amp;#39;fmt&amp;#39;,&amp;#39;fold&amp;#39;,&amp;#39;hashsum&amp;#39;,&amp;#39;head&amp;#39;,&amp;#39;join&amp;#39;,&amp;#39;link&amp;#39;,&amp;#39;ln&amp;#39;,&amp;#39;ls&amp;#39;,&amp;#39;md5sum&amp;#39;,&amp;#39;mkdir&amp;#39;,&amp;#39;mktemp&amp;#39;,&amp;#39;more&amp;#39;,&amp;#39;mv&amp;#39;,&amp;#39;nl&amp;#39;,&amp;#39;numfmt&amp;#39;,&amp;#39;od&amp;#39;,&amp;#39;paste&amp;#39;,&amp;#39;pr&amp;#39;,&amp;#39;printenv&amp;#39;,&amp;#39;printf&amp;#39;,&amp;#39;ptx&amp;#39;,&amp;#39;pwd&amp;#39;,&amp;#39;readlink&amp;#39;,&amp;#39;realpath&amp;#39;,&amp;#39;relpath&amp;#39;,&amp;#39;rm&amp;#39;,&amp;#39;rmdir&amp;#39;,&amp;#39;seq&amp;#39;,&amp;#39;sha1sum&amp;#39;,&amp;#39;sha224sum&amp;#39;,&amp;#39;sha256sum&amp;#39;,&amp;#39;sha3-224sum&amp;#39;,&amp;#39;sha3-256sum&amp;#39;,&amp;#39;sha3-384sum&amp;#39;,&amp;#39;sha3-512sum&amp;#39;,&amp;#39;sha384sum&amp;#39;,&amp;#39;sha3sum&amp;#39;,&amp;#39;sha512sum&amp;#39;,&amp;#39;shake128sum&amp;#39;,&amp;#39;shake256sum&amp;#39;,&amp;#39;shred&amp;#39;,&amp;#39;shuf&amp;#39;,&amp;#39;sleep&amp;#39;,&amp;#39;sort&amp;#39;,&amp;#39;split&amp;#39;,&amp;#39;sum&amp;#39;,&amp;#39;tac&amp;#39;,&amp;#39;tail&amp;#39;,&amp;#39;tee&amp;#39;,&amp;#39;test&amp;#39;,&amp;#39;touch&amp;#39;,&amp;#39;tr&amp;#39;,&amp;#39;true&amp;#39;,&amp;#39;truncate&amp;#39;,&amp;#39;tsort&amp;#39;,&amp;#39;unexpand&amp;#39;,&amp;#39;uniq&amp;#39;,&amp;#39;unlink&amp;#39;,&amp;#39;vdir&amp;#39;,&amp;#39;wc&amp;#39;,&amp;#39;yes&amp;#39;) {
    cargo run completion $cmd powershell &amp;gt; &amp;#34;C:\path\to\completions\$cmd.ps1&amp;#34;
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;b2sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;b3sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;base32&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;basename&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;basenc&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cat&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cksum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;comm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cp&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;csplit&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cut&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dd&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;df&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dircolors&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dirname&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;du&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;echo&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;env&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;expand&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;expr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;factor&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fmt&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fold&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;hashsum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;head&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;join&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ln&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ls&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;md5sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mkdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mktemp&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;more&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mv&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;nl&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;numfmt&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;od&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;paste&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;printenv&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;printf&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ptx&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pwd&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;readlink&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;realpath&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;relpath&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;rm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;rmdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;seq&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha1sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha224sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-224sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-384sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-512sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha384sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha512sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shake128sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shake256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shred&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shuf&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sleep&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sort&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;split&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tac&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tail&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tee&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;touch&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;truncate&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tsort&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;unexpand&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;uniq&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;unlink&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;vdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;wc&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;yes&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;cargo&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;run&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;completion&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;powershell&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C:\path\to\completions\&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;.ps1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这样就可以把自动补全输出到你自定义的补全预设目录（还是别忘了替换路径）。&lt;/p&gt;
&lt;h2 id=&#34;取代powershell自带cmdlet-alias&#34;&gt;取代PowerShell自带cmdlet alias
&lt;/h2&gt;&lt;p&gt;现在每次都要先输一个 &lt;code&gt;coreutils&lt;/code&gt; 命令才能调用，既不方便也没法用自动补全，干脆直接把命令映射过来。&lt;/p&gt;
&lt;p&gt;直接 &lt;code&gt;Set-Alias&lt;/code&gt; 是不成功的，因为PowerShell自带alias。在profile中再添加以下内容：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;foreach($cmd in&amp;#39;b2sum&amp;#39;,&amp;#39;b3sum&amp;#39;,&amp;#39;base32&amp;#39;,&amp;#39;base64&amp;#39;,&amp;#39;basename&amp;#39;,&amp;#39;basenc&amp;#39;,&amp;#39;cat&amp;#39;,&amp;#39;cksum&amp;#39;,&amp;#39;comm&amp;#39;,&amp;#39;cp&amp;#39;,&amp;#39;csplit&amp;#39;,&amp;#39;cut&amp;#39;,&amp;#39;date&amp;#39;,&amp;#39;dd&amp;#39;,&amp;#39;df&amp;#39;,&amp;#39;dir&amp;#39;,&amp;#39;dircolors&amp;#39;,&amp;#39;dirname&amp;#39;,&amp;#39;du&amp;#39;,&amp;#39;echo&amp;#39;,&amp;#39;env&amp;#39;,&amp;#39;expand&amp;#39;,&amp;#39;expr&amp;#39;,&amp;#39;factor&amp;#39;,&amp;#39;false&amp;#39;,&amp;#39;fmt&amp;#39;,&amp;#39;fold&amp;#39;,&amp;#39;hashsum&amp;#39;,&amp;#39;head&amp;#39;,&amp;#39;join&amp;#39;,&amp;#39;link&amp;#39;,&amp;#39;ln&amp;#39;,&amp;#39;ls&amp;#39;,&amp;#39;md5sum&amp;#39;,&amp;#39;mkdir&amp;#39;,&amp;#39;mktemp&amp;#39;,&amp;#39;more&amp;#39;,&amp;#39;mv&amp;#39;,&amp;#39;nl&amp;#39;,&amp;#39;numfmt&amp;#39;,&amp;#39;od&amp;#39;,&amp;#39;paste&amp;#39;,&amp;#39;pr&amp;#39;,&amp;#39;printenv&amp;#39;,&amp;#39;printf&amp;#39;,&amp;#39;ptx&amp;#39;,&amp;#39;pwd&amp;#39;,&amp;#39;readlink&amp;#39;,&amp;#39;realpath&amp;#39;,&amp;#39;relpath&amp;#39;,&amp;#39;rm&amp;#39;,&amp;#39;rmdir&amp;#39;,&amp;#39;seq&amp;#39;,&amp;#39;sha1sum&amp;#39;,&amp;#39;sha224sum&amp;#39;,&amp;#39;sha256sum&amp;#39;,&amp;#39;sha3-224sum&amp;#39;,&amp;#39;sha3-256sum&amp;#39;,&amp;#39;sha3-384sum&amp;#39;,&amp;#39;sha3-512sum&amp;#39;,&amp;#39;sha384sum&amp;#39;,&amp;#39;sha3sum&amp;#39;,&amp;#39;sha512sum&amp;#39;,&amp;#39;shake128sum&amp;#39;,&amp;#39;shake256sum&amp;#39;,&amp;#39;shred&amp;#39;,&amp;#39;shuf&amp;#39;,&amp;#39;split&amp;#39;,&amp;#39;sum&amp;#39;,&amp;#39;tac&amp;#39;,&amp;#39;tail&amp;#39;,&amp;#39;test&amp;#39;,&amp;#39;touch&amp;#39;,&amp;#39;tr&amp;#39;,&amp;#39;true&amp;#39;,&amp;#39;truncate&amp;#39;,&amp;#39;tsort&amp;#39;,&amp;#39;unexpand&amp;#39;,&amp;#39;uniq&amp;#39;,&amp;#39;unlink&amp;#39;,&amp;#39;vdir&amp;#39;,&amp;#39;wc&amp;#39;,&amp;#39;yes&amp;#39;) {
    Remove-Alias $cmd -ErrorAction SilentlyContinue
    Set-Item function:$cmd -Value {coreutils $cmd $args}.GetNewClosure()
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;b2sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;b3sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;base32&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;base64&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;basename&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;basenc&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cat&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cksum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;comm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cp&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;csplit&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;cut&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;date&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dd&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;df&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dircolors&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;dirname&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;du&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;echo&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;env&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;expand&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;expr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;factor&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;false&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fmt&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;fold&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;hashsum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;head&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;join&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;link&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ln&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ls&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;md5sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mkdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mktemp&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;more&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;mv&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;nl&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;numfmt&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;od&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;paste&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;printenv&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;printf&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ptx&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pwd&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;readlink&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;realpath&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;relpath&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;rm&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;rmdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;seq&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha1sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha224sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-224sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-384sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3-512sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha384sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha3sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sha512sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shake128sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shake256sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shred&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;shuf&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;split&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;sum&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tac&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tail&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;test&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;touch&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tr&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;truncate&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;tsort&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;unexpand&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;uniq&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;unlink&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;vdir&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;wc&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;yes&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;Remove-Alias&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ErrorAction&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SilentlyContinue&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;Set-Item&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Value&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;coreutils&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$cmd&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$args&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;GetNewClosure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;（修改自 &lt;a class=&#34;link&#34; href=&#34;https://gist.github.com/zett42/72fe42c418d53ad03d5e17ffd7fd8104&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个 Gist&lt;/a&gt;）&lt;/p&gt;
&lt;p&gt;因为 &lt;code&gt;sleep&lt;/code&gt;、&lt;code&gt;tee&lt;/code&gt; 和 &lt;code&gt;sort&lt;/code&gt; 不允许修改，所以只好删掉了。&lt;/p&gt;
&lt;p&gt;如果没有意外的话，再打开一个PowerShell，就可以使用新的uutils了。&lt;/p&gt;
&lt;p&gt;参考资料：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/75563303/how-to-set-an-alias-of-a-command-and-its-argument-in-windows-powershell&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://stackoverflow.com/questions/75563303/how-to-set-an-alias-of-a-command-and-its-argument-in-windows-powershell&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ChatGPT&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>从 Docker 到 Podman</title>
        <link>https://cyp0633.com/post/from-docker-to-podman/</link>
        <pubDate>Tue, 07 Mar 2023 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/from-docker-to-podman/</guid>
        <description>&lt;p&gt;我烦Docker很久了。倒不如说我烦 “屁大点事都要容器化” 很久了，但在不得不用的时候，与其用自成一体的Docker，不如用同样遵守OCI的Podman。&lt;/p&gt;
&lt;p&gt;由于Docker和Podman基本能够兼容，这里是一些个人碰到可能比较有意思的用法。我也不知道会不会继续写，什么时候会写。&lt;/p&gt;
&lt;h2 id=&#34;与systemd结合&#34;&gt;与systemd结合
&lt;/h2&gt;&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;&lt;em&gt;&lt;strong&gt;PROTECTED_0&lt;/strong&gt;&lt;/em&gt; 已被弃用，请参考使用 Quadlet 的新方法&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;hr&gt;
&lt;p&gt;现在使用 &lt;code&gt;podman generate systemd&lt;/code&gt;，会提示 &lt;code&gt;DEPRECATED command: It is recommended to use Quadlets for running containers and pods under systemd.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://access.redhat.com/documentation/zh-cn/red_hat_enterprise_linux/8/html/building_running_and_managing_containers/proc_auto-generating-a-systemd-unit-file-using-podman_assembly_porting-containers-to-systemd-using-podman&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Red Hat 文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Docker有 &lt;code&gt;dockerd&lt;/code&gt;，能自主控制容器的启动与停止，Podman没有。相比Docker，Podman的特点之一就是与systemd的融合，毕竟两个玩意全都是Red Hat自家的，他们大概也不想再做一个daemon。&lt;/p&gt;
&lt;p&gt;解决办法就是，Podman容器可以使用systemd单元来控制启停等功能。举个例子，如果是root用户的容器，可以直接运行下面的命令，生成一个systemd单元：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;podman generate systemd --new &amp;lt;container_name&amp;gt; &amp;gt; /etc/systemd/system/&amp;lt;service_name&amp;gt;.service&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;podman generate systemd --new &amp;lt;container_name&amp;gt; &amp;gt; /etc/systemd/system/&amp;lt;service_name&amp;gt;.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;记得替换你自己的容器名称和单元名称。虽然前后两个名字不统一又不是不能用，但个人强烈建议统一一下，可能能免去一些玄学问题。然后就可以用平常管理systemd单元的方法来管理它了。&lt;/p&gt;
&lt;hr&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;Podman推荐的用systemd管理容器的方式是Quadlet。一个Quadlet形似systemd unit，但又神似docker-compose YAML。相比于已经弃用的 &lt;code&gt;podman-systemd&lt;/code&gt; ，Quadlet表现能力更强，更容易编辑。看一眼 &lt;code&gt;redis.container&lt;/code&gt; 示例&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;就明白了：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[Unit]
Description=Redis container

[Container]
Image=docker.io/redis
PublishPort=6379:6379
User=999

[Service]
Restart=always

[Install]
WantedBy=local.target&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Redis container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Container]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;docker.io/redis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;PublishPort&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;6379:6379&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;local.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;详细的文件结构在 &lt;a class=&#34;link&#34; href=&#34;https://docs.podman.io/en/latest/markdown/podman-systemd.unit.5.html#container-units-container&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Podman 的文档&lt;/a&gt; 中有说明。除上面的 &lt;code&gt;.container&lt;/code&gt; 示例外，还有&lt;code&gt;.kube&lt;/code&gt;、&lt;code&gt;.network&lt;/code&gt; 和 &lt;code&gt;.volume&lt;/code&gt; 文件分别描述基于K8S的服务、容器网络设备和卷。&lt;/p&gt;
&lt;p&gt;编辑完成后，要将上面的文件放进下面的目录之一&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$HOME/.config/containers/systemd/&lt;/code&gt;（rootless container）&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/share/containers/systemd/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/containers/systemd/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;然后运行 &lt;code&gt;systemd daemon-reload&lt;/code&gt;，就可以自动生成对应的systemd unit。比如在我的设备上，刚刚的 &lt;code&gt;redis.container&lt;/code&gt; 生成的systemd unit就在 &lt;code&gt;/run/systemd/generator/redis.service&lt;/code&gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;# Automatically generated by /usr/lib/systemd/system-generators/podman-system-generator
#
[Unit]
Description=Redis container
SourcePath=/etc/containers/systemd/redis.container
RequiresMountsFor=%t/containers

[X-Container]
Image=docker.io/redis
PublishPort=6379:6379
User=999

[Service]
Restart=always
Environment=PODMAN_SYSTEMD_UNIT=%n
KillMode=mixed
ExecStop=/usr/bin/podman rm -f -i --cidfile=%t/%N.cid
ExecStopPost=-/usr/bin/podman rm -f -i --cidfile=%t/%N.cid
Delegate=yes
Type=notify
NotifyAccess=all
SyslogIdentifier=%N
ExecStart=/usr/bin/podman run --name=systemd-%N --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d --user 999 --publish 6379:6379 docker.io/redis

[Install]
WantedBy=local.target&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Automatically generated by /usr/lib/systemd/system-generators/podman-system-generator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Description&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;Redis container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;SourcePath&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/etc/containers/systemd/redis.container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;RequiresMountsFor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;%t/containers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[X-Container]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;docker.io/redis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;PublishPort&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;6379:6379&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;always&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Environment&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;PODMAN_SYSTEMD_UNIT=%n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;KillMode&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;mixed&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;ExecStop&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/podman rm -f -i --cidfile=%t/%N.cid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;ExecStopPost&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;-/usr/bin/podman rm -f -i --cidfile=%t/%N.cid&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Delegate&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;yes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;notify&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;NotifyAccess&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;all&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;SyslogIdentifier&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;%N&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;ExecStart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;/usr/bin/podman run --name=systemd-%N --cidfile=%t/%N.cid --replace --rm --cgroups=split --sdnotify=conmon -d --user 999 --publish 6379:6379 docker.io/redis&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;local.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;当然，放出来的目的只是展示会生成一个怎样的文件，实际有需要时都是编辑Quadlet的。&lt;/p&gt;
&lt;h3 id=&#34;从其他格式生成&#34;&gt;从其他格式生成
&lt;/h3&gt;&lt;p&gt;坏消息是似乎无法直接为一个已经存在的容器生成Quadlet了；但也有好消息，只要能搞来 &lt;code&gt;podman run&lt;/code&gt; 命令（或docker-compose YAML），就可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/k9withabone/podlet&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;em&gt;&lt;strong&gt;PROTECTED_1&lt;/strong&gt;&lt;/em&gt; 工具&lt;/a&gt; 生成Quadlet。比如：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;$ podlet podman run --name redis -p 6379:6379 --restart always --user 999 docker.io/redis
# redis.container
[Container]
Image=docker.io/redis
ContainerName=redis
PublishPort=6379:6379
User=999

[Service]
Restart=always&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;$ podlet podman run --name redis -p 6379:6379 --restart always --user &lt;span class=&#34;m&#34;&gt;999&lt;/span&gt; docker.io/redis
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# redis.container&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Container&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Image&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;docker.io/redis
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;ContainerName&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;redis
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;PublishPort&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;6379:6379
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;User&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;999&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;[&lt;/span&gt;Service&lt;span class=&#34;o&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;Restart&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;always&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&#34;开机启动&#34;&gt;开机启动
&lt;/h3&gt;&lt;p&gt;截至编写本文时，由于Quadlet生成的systemd unit是自动生成、可能改变的，所以无法enable&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;（会提示 &lt;code&gt;Failed to enable unit: Unit is transient or generated&lt;/code&gt;）。&lt;/p&gt;
&lt;p&gt;解决办法是在Quadlet中添加任何 &lt;code&gt;[Install]&lt;/code&gt; 栏的内容，比如之前的 &lt;code&gt;redis.container&lt;/code&gt;，或者参考官方文档的做法：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;[Install]
WantedBy=multi-user.target default.target&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;WantedBy&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;multi-user.target default.target&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后就可以自动开机启动了。&lt;/p&gt;
&lt;h2 id=&#34;自动更新镜像&#34;&gt;自动更新镜像
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.redhat.com/sysadmin/podman-auto-updates-rollbacks&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Red Hat 文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;手动重新找到同样的参数更新，不仅麻烦还不安全。Podman自带了一个 &lt;code&gt;auto-update&lt;/code&gt; 工具，可以自动更新镜像，但依赖systemd unit。&lt;/p&gt;
&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;适用于 &lt;em&gt;&lt;strong&gt;PROTECTED_0&lt;/strong&gt;&lt;/em&gt; 的方法（已弃用）&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;hr&gt;
&lt;p&gt;先创建个新容器，至于用 &lt;code&gt;run&lt;/code&gt; 还是 &lt;code&gt;create&lt;/code&gt; 其实都没什么关系。但不要忘了指定 &lt;code&gt;io.containers.autoupdate&lt;/code&gt; label。属性可以为 &lt;code&gt;registry&lt;/code&gt; 或者 &lt;code&gt;local&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;podman create --label io.containers.autoupdate=registry --name &amp;lt;container_name&amp;gt; &amp;lt;image_name&amp;gt;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;podman create --label io.containers.autoupdate&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;registry --name &amp;lt;container_name&amp;gt; &amp;lt;image_name&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后还要创建一下systemd单元，方法如上，这里再次建议单元名为容器友好名称，或者那个64位的随机hex值。&lt;/p&gt;
&lt;hr&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;p&gt;在上文容器Quadlet中的 &lt;code&gt;[Container]&lt;/code&gt; 一栏中，添加一行 &lt;code&gt;AutoUpdate=&lt;/code&gt;，后面的值从下面的选项中选一个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;registry&lt;/code&gt;：更新的时候会pull一下&lt;/li&gt;
&lt;li&gt;&lt;code&gt;local&lt;/code&gt;：有需要的时候得手动pull，如果本地镜像更新，用本地的替换&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;启用systemd单元后，建议先试一下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;podman auto-update --dry-run&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;podman auto-update --dry-run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;看名字也知道不会真的更新，只不过看看是不是配置对了。真正更新的时候把 &lt;code&gt;--dry-run&lt;/code&gt; 去掉就行。&lt;/p&gt;
&lt;p&gt;这玩意看起来更像是 &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt; 或者 &lt;code&gt;pacman -Syu&lt;/code&gt; 之类的工具。如果更新失败，它也会自动进行回滚。&lt;/p&gt;
&lt;h2 id=&#34;netavark和nftables&#34;&gt;Netavark和Nftables
&lt;/h2&gt;&lt;p&gt;Netavark是Podman依赖的网络组件，后者需要前者创建虚拟网络等。而Nftables是iptables的替代品，依托Netfilter，用于创建防火墙规则或重定向等操作。&lt;/p&gt;
&lt;p&gt;Netavark的默认后端是iptables。当Podman涉及到创建Pod等与虚拟网络有关的操作时，iptables-nft会操作Nftables创建一个链，而这个链的名字常常因为各种原因已经使用，于是会出现以下错误信息：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plaintext&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;Error: starting container xxxxx: netavark: code: 1, msg: iptables: Chain already exists.&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plaintext&#34; data-lang=&#34;plaintext&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Error: starting container xxxxx: netavark: code: 1, msg: iptables: Chain already exists.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这时需要在 &lt;code&gt;/etc/containers/containers.conf&lt;/code&gt; 里，将后端替换为Nftables&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;[network]
firewall_driver = &amp;#34;nftables&amp;#34;&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[network]
firewall_driver = &amp;#34;nftables&amp;#34;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果版本比较老，可以改成 &lt;code&gt;&amp;quot;none&amp;quot;&lt;/code&gt;。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/containers/quadlet/blob/main/examples/quadlet-redis.container&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/containers/quadlet/blob/main/examples/quadlet-redis.container&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.redhat.com/sysadmin/quadlet-podman&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.redhat.com/sysadmin/quadlet-podman&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/containers/podman/discussions/17744&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/containers/podman/discussions/17744&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/containers/netavark/issues/339&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/containers/netavark/issues/339&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
        </item>
        <item>
        <title>该如何安放你，我的照片</title>
        <link>https://cyp0633.com/post/personal-gallery/</link>
        <pubDate>Wed, 11 Jan 2023 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/personal-gallery/</guid>
        <description>&lt;p&gt;一个自行部署的照片托管解决方案伪横评（真水文）。&lt;/p&gt;
&lt;p&gt;使用设备：Celeron N5105（无AVX指令集），16G RAM，512G SSD；Arch Linux，容器环境Podman&lt;/p&gt;
&lt;p&gt;&lt;del&gt;个人的需求其实很简单，只是一个相册分类 + 照片时间线预览。要说特殊需求大概就是有大量的HEIC图片，毕竟谁的空间也不是大风刮来的，另外最好能够用类MySQL。&lt;/del&gt; 要说人还是闲不住，后面实测了Photoprism、Photoview和Immich，所以不知不觉变成真横评了。对于其他服务，可以看&lt;a class=&#34;link&#34; href=&#34;https://meichthys.github.io/foss_photo_libraries/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这个非常直观的表格&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;以下依据为个人2024/06的照片库，约10000张照片，40GB。&lt;/p&gt;
&lt;h2 id=&#34;photoprism&#34;&gt;Photoprism
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/photoprism/photoprism&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;photoprism/photoprism&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;算是比较早的开源相册方案了，基本功能令人安心，但使用略有不便，且设置界面可设置的项较少。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;personal-gallery/photoprism-tags.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Photoprism 会直接生成标签&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;Photoprism 会直接生成标签&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据库支持：MariaDB（MySQL）和SQLite，比较友好。&lt;/li&gt;
&lt;li&gt;部署：方式为容器，需要设置大量环境变量作为配置，而不能在网页上直接修改，较为繁琐。&lt;/li&gt;
&lt;li&gt;资源占用：不索引时（不含数据库）占用内存42MB左右，索引时约为220MB；数据库中数据65MB，缩略图等数据15GB；容器镜像1.88GB。&lt;/li&gt;
&lt;li&gt;文件管理：支持导入和外部资料库，后者不改变原有文件结构；HEIC等格式图片会自动转换为JPEG。&lt;/li&gt;
&lt;li&gt;人脸识别：识别不出几个人，水平不大行。&lt;/li&gt;
&lt;li&gt;搜索：提前给图片生成标签，可以搜索，也可以自行添加标签。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;photoview&#34;&gt;Photoview
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/photoview/photoview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;photoview/photoview&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://aur.archlinux.org/packages/photoview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方认可 AUR&lt;/a&gt;，好耶！相对来说，手动安装过程是最简单而且符合直觉的。托打包者和开发者的福，在安装AUR后，只需要修改一下配置文件里的MySQL连接参数（或者直接改成SQLite），然后启动systemd服务即可。功能相对来说简单，不过对我来说够用。人脸识别的准确度很一般，但对我来说也是锦上添花的功能。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;personal-gallery/librephoto-install.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;AUR 安装后的配置指引&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;提示：如果不想或不能改变文件所有权，建议使用文件ACL &lt;code&gt;setfacl -Rdm&lt;/code&gt; 命令为photoview用户授予循环继承权限。&lt;/p&gt;
&lt;p&gt;用下来几天发现了两个主要的问题，一个是一次导入过多照片的时候会卡住（假完成），阈值大约100张，另一个是HEIC图片的EXIF可能不能正确识别（提了 &lt;a class=&#34;link&#34; href=&#34;https://github.com/photoview/photoview/issues/787&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;issue&lt;/a&gt;）。自从作者不太积极开发这个项目之后，感觉基本停滞了。&lt;/p&gt;
&lt;p&gt;虽然这个占用是真的小，但需要声明的是，索引的时候仍然会消耗较多CPU，除非每次都大半夜索引，否则还是没有想象中那么省性能的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据库支持：MySQL或PostgreSQL。&lt;/li&gt;
&lt;li&gt;部署：有AUR，有Systemd部署文档，但个人建议直接用容器。&lt;/li&gt;
&lt;li&gt;资源占用：索引时250MB，日常10MB；缩略图等数据占用存储4.5GB，数据库20MB，镜像1.38GB。&lt;/li&gt;
&lt;li&gt;文件管理：完全尊重外部文件结构，不会改变。但索引有些小bug，见上。&lt;/li&gt;
&lt;li&gt;人脸识别：聊胜于无吧，精度不大行。&lt;/li&gt;
&lt;li&gt;搜索：基于文件名的搜索，别的都没有。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;immich&#34;&gt;Immich
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/immich-app/immich&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;immich-app/immich&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Immich也是后起之秀了，现在Star比前辈Photoprism还多。它相对来说就比较复杂了，占用资源也多很多，算上数据库下来五个容器（但看起来&lt;a class=&#34;link&#34; href=&#34;https://github.com/immich-app/immich/pull/9551&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;不久之后会变成 4 个&lt;/a&gt;）。但是相对的，可自定义度也高很多，尤其是机器学习的部分。&lt;/p&gt;
&lt;p&gt;上述机器学习指的是人脸识别和图像搜索，均可以远程进行，即在性能强的机器上单独运行ML容器，然后通过API通信。这对人脸来说十分方便，因为较大的人脸识别模型占用很大，但对于基于CLIP的图像搜索来说就是另一回事了：不光在索引时需要机器学习模块，搜索时也需要。所幸CLIP搜索的原理为对图片和检索词分别生成向量，然后将两者进行对比，而消耗资源比较多的部分是生成图片向量，所以可以先用较强的远程机器生成图片向量，我NUC上的弱鸡CPU只用来跑检索。还算可以接受。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;数据库支持：PostgreSQL+Redis，需同时运行。&lt;/li&gt;
&lt;li&gt;部署：似乎十分复杂，个人建议直接用容器。Docker Compose好说，Podman的话会非常麻烦。&lt;/li&gt;
&lt;li&gt;资源占用：索引时内存基本上吃完（这是我的NUC头一次吃SWAP），如果使用NVIDIA硬件加速机器学习，还会占用约5-8GB显存（因为我卡只有8GB）；平时内存占用约400+200MB；缩略图等数据占用5.7GB（可使用WEBP，降低了占用），数据库563MB，镜像1.6GB+790MB（若使用CUDA则为4.55GB）。&lt;/li&gt;
&lt;li&gt;文件管理：同时支持导入和外部资料库。&lt;/li&gt;
&lt;li&gt;人脸识别：用较大模型的时候准确度蛮高的。&lt;/li&gt;
&lt;li&gt;搜索：基于CLIP的自然语言搜索，遥遥领先，但缺点见上。也可以根据人脸、设备等条件筛选。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;结语&#34;&gt;结语
&lt;/h2&gt;&lt;p&gt;很缺资源的选Photoview，性能足够的选Immich，嫌Photoview还不够强的选Photoprism。&lt;/p&gt;
&lt;details class=&#34;article-details-fold&#34;&gt;
    &lt;summary class=&#34;article-details-fold__summary&#34;&gt;
        &lt;span&gt;附录：将 Immich 部署为 Podman Pod&lt;/span&gt;
    &lt;/summary&gt;
    &lt;div class=&#34;article-details-fold__content&#34;&gt;
        &lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/jbtrystram/immich-podman-systemd&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;来源&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;默认以rootful方式部署，将文件放在 &lt;code&gt;/etc/containers/systemd&lt;/code&gt; 或其子目录下，&lt;code&gt;systemctl daemon reload&lt;/code&gt; 后 &lt;code&gt;systemctl start immich-server.service&lt;/code&gt; 即可。&lt;/p&gt;
&lt;p&gt;不要忘记修改下面的目录映射和环境变量。两个目录映射中，一个是内部存储（由Immich决定文件结构），一个是外部存储（保留用户的文件结构）。&lt;/p&gt;
&lt;p&gt;Pod声明 &lt;code&gt;immich.pod&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[Pod]
PodName=immich
PublishPort=2283:3001&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Pod]
PodName=immich
PublishPort=2283:3001&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code&gt;immich.env&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables

# Connection secret for postgres. You should change it to a random password.
# The two values should match
DB_PASSWORD=ZWEuFZHcEyuJJoR6
POSTGRES_PASSWORD=ZWEuFZHcEyuJJoR6

# The values below this line do not need to be changed
###################################################################################

DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
POSTGRES_USER=postgres

DB_DATABASE_NAME=immich
POSTGRES_DB=immich

REDIS_HOSTNAME=immich_redis

IMMICH_MACHINE_LEARNING_URL=http://immich_machine_learning:3003&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables

# Connection secret for postgres. You should change it to a random password.
# The two values should match
DB_PASSWORD=ZWEuFZHcEyuJJoR6
POSTGRES_PASSWORD=ZWEuFZHcEyuJJoR6

# The values below this line do not need to be changed
###################################################################################

DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
POSTGRES_USER=postgres

DB_DATABASE_NAME=immich
POSTGRES_DB=immich

REDIS_HOSTNAME=immich_redis

IMMICH_MACHINE_LEARNING_URL=http://immich_machine_learning:3003&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;数据库容器 &lt;code&gt;immich-postgres.container&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_postgres
EnvironmentFile=immich.env
Image=docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
Volume=pgdata:/var/lib/postgresql/data
HealthCmd=[&amp;#34;/usr/bin/pg_isready&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_postgres
EnvironmentFile=immich.env
Image=docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
Volume=pgdata:/var/lib/postgresql/data
HealthCmd=[&amp;#34;/usr/bin/pg_isready&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;缓存容器 &lt;code&gt;immich-redis.container&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_redis
Image=docker.io/redis:6.2-alpine@sha256:51d6c56749a4243096327e3fb964a48ed92254357108449cb6e23999c37773c5
HealthCmd=[&amp;#34;/usr/local/bin/redis-cli&amp;#34;, &amp;#34;ping&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_redis
Image=docker.io/redis:6.2-alpine@sha256:51d6c56749a4243096327e3fb964a48ed92254357108449cb6e23999c37773c5
HealthCmd=[&amp;#34;/usr/local/bin/redis-cli&amp;#34;, &amp;#34;ping&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always

[Install]
WantedBy=multi-user.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;机器学习容器 &lt;code&gt;immich-machine-learning.container&lt;/code&gt;（本地，无硬件加速）&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_machine_learning
EnvironmentFile=immich.env
Environment=HF_ENDPOINT=https://hf-mirror.com
Environment=LOG_LEVEL=debug
Image=ghcr.io/immich-app/immich-machine-learning:release
AutoUpdate=registry
Volume=model-cache:/cache
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3003&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Container]
Pod=immich.pod
ContainerName=immich_machine_learning
EnvironmentFile=immich.env
Environment=HF_ENDPOINT=https://hf-mirror.com
Environment=LOG_LEVEL=debug
Image=ghcr.io/immich-app/immich-machine-learning:release
AutoUpdate=registry
Volume=model-cache:/cache
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3003&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;机器学习容器 &lt;code&gt;immich-machine-learning.container&lt;/code&gt;（远程，CUDA加速）&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;[Container]
ContainerName=immich_machine_learning
Image=ghcr.io/immich-app/immich-machine-learning:release-cuda
Volume=model-cache:/cache
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3003&amp;#34;]
HealthStartPeriod=30s
AutoUpdate=registry
PublishPort=3003:3003
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy
Environment=LOG_LEVEL=debug
Environment=HF_ENDPOINT=https://hf-mirror.com
AddDevice=nvidia.com/gpu=all

[Service]
Restart=always&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Container]
ContainerName=immich_machine_learning
Image=ghcr.io/immich-app/immich-machine-learning:release-cuda
Volume=model-cache:/cache
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3003&amp;#34;]
HealthStartPeriod=30s
AutoUpdate=registry
PublishPort=3003:3003
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy
Environment=LOG_LEVEL=debug
Environment=HF_ENDPOINT=https://hf-mirror.com
AddDevice=nvidia.com/gpu=all

[Service]
Restart=always&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;微服务（如索引等）容器 &lt;code&gt;immich-microservices.container&lt;/code&gt;（带有Intel QSV支持）&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;[Unit]
Requires=immich-redis.service immich-database.service
After=immich-redis.service immich-database.service

[Container]
Pod=immich.pod
ContainerName=immich_microservices
EnvironmentFile=immich.env
Exec=start.sh microservices
Image=ghcr.io/immich-app/immich-server:release
Volume=/path/to/internal/storage:/usr/src/app/upload:z
Volume=/etc/localtime:/etc/localtime:ro
Volume=/path/to/external/storage:/usr/src/app/external:z
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3002&amp;#34;]
HealthStartPeriod=30s
AddDevice=/dev/dri
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Unit]
Requires=immich-redis.service immich-database.service
After=immich-redis.service immich-database.service

[Container]
Pod=immich.pod
ContainerName=immich_microservices
EnvironmentFile=immich.env
Exec=start.sh microservices
Image=ghcr.io/immich-app/immich-server:release
Volume=/path/to/internal/storage:/usr/src/app/upload:z
Volume=/etc/localtime:/etc/localtime:ro
Volume=/path/to/external/storage:/usr/src/app/external:z
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3002&amp;#34;]
HealthStartPeriod=30s
AddDevice=/dev/dri
HealthInterval=10s
HealthTimeout=5s
HealthRetries=5
Notify=healthy

[Service]
Restart=always&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;主服务容器 &lt;code&gt;immich-server.container&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;conf&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;[Unit]
Requires=immich-redis.service immich-database.service immich-microservices.service
After=immich-redis.service immich-database.service immich-microservices.service

[Container]
Pod=immich.pod
ContainerName=immich_server
EnvironmentFile=immich.env
Exec=start.sh immich
Image=ghcr.io/immich-app/immich-server:release
AutoUpdate=registry
Volume=/path/to/internal/storage:/usr/src/app/upload:z
Volume=/etc/localtime:/etc/localtime:ro
Volume=/path/to/external/storage:/usr/src/app/external:z
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3001&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=30s
HealthRetries=10
Notify=healthy

[Service]
Restart=always

[Install]
WantedBy=default.target&lt;/code&gt;&lt;pre&gt;&lt;code class=&#34;&#34;&gt;[Unit]
Requires=immich-redis.service immich-database.service immich-microservices.service
After=immich-redis.service immich-database.service immich-microservices.service

[Container]
Pod=immich.pod
ContainerName=immich_server
EnvironmentFile=immich.env
Exec=start.sh immich
Image=ghcr.io/immich-app/immich-server:release
AutoUpdate=registry
Volume=/path/to/internal/storage:/usr/src/app/upload:z
Volume=/etc/localtime:/etc/localtime:ro
Volume=/path/to/external/storage:/usr/src/app/external:z
HealthCmd=[&amp;#34;/bin/bash&amp;#34;, &amp;#34;-c&amp;#34;, &amp;#34;exec 5&amp;lt;&amp;gt;/dev/tcp/127.0.0.1/3001&amp;#34;]
HealthStartPeriod=30s
HealthInterval=10s
HealthTimeout=30s
HealthRetries=10
Notify=healthy

[Service]
Restart=always

[Install]
WantedBy=default.target&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

    &lt;/div&gt;
&lt;/details&gt;

&lt;hr&gt;
&lt;p&gt;网络上的其他讨论可见 &lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/selfhosted/comments/lotc2e/google_photo_alternative_showdown/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Reddit 帖 1&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.reddit.com/r/selfhosted/comments/ky0o40/photoprism_vs_librephotos/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Reddit 帖 2&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>使用 VS Code 实现 LaTeX 便捷编译与预览</title>
        <link>https://cyp0633.com/post/vscode-latex/</link>
        <pubDate>Mon, 28 Nov 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/vscode-latex/</guid>
        <description>&lt;p&gt;好久不见，水一篇文章。&lt;/p&gt;
&lt;p&gt;Overleaf实在是太慢了，编辑器用起来也不爽，既然有轻便的本地发行版和优秀的编辑器，为什么不用呢？&lt;/p&gt;
&lt;p&gt;本人使用Windows和Arch Linux下的MikTeX，对于其他发行版或操作系统，仅供参考。&lt;/p&gt;
&lt;h2 id=&#34;latex安装&#34;&gt;LaTeX安装
&lt;/h2&gt;&lt;p&gt;个人会推荐MiKTeX发行版，仅需下载必要的文件，相比TeXLive 10GB + 的大小大大改善。&lt;/p&gt;
&lt;p&gt;Windows下没什么难度，从 &lt;a class=&#34;link&#34; href=&#34;https://miktex.org/download&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官网&lt;/a&gt; 下载即可。&lt;/p&gt;
&lt;p&gt;Arch Linux等Pacman的Linux发行版建议从 &lt;a class=&#34;link&#34; href=&#34;https://aur.archlinux.org/packages/miktex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AUR&lt;/a&gt; 下载，Arch Linux CN源下了好几遍似乎有点问题；然后打开MiKTeX Console，个人建议为所有用户安装，省事。&lt;/p&gt;
&lt;h2 id=&#34;插件安装&#34;&gt;插件安装
&lt;/h2&gt;&lt;p&gt;首先在VS Code Marketplace下载一个插件，&lt;a class=&#34;link&#34; href=&#34;https://marketplace.visualstudio.com/items?itemName=James-Yu.latex-workshop&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;LaTeX Workshop&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;装完之后，用VS Code打开一个工作区中的. tex文件，主界面就变成了这样。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-latex/vscode-with-extension.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;打开工作区 tex 文件&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;recipe包含了对文件进行的处理步骤。毫无疑问，左边的recipe又要自己配了。马上讲。&lt;/p&gt;
&lt;h2 id=&#34;编译配置&#34;&gt;编译配置
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;此部分主要参考 &lt;a class=&#34;link&#34; href=&#34;https://mingzzx.com/2019/05/14/miktex-vscode/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://mingzzx.com/2019/05/14/miktex-vscode/&lt;/a&gt;&lt;/strong&gt; (CC BY-SA 4.0)。&lt;/p&gt;
&lt;p&gt;recipe的逻辑似乎类似于Linux的pipe，以及VS Code其他语言的调试思想。&lt;/p&gt;
&lt;p&gt;此处我使用 &lt;code&gt;XeLaTeX&lt;/code&gt; 命令，而原帖使用 &lt;code&gt;pdfLaTeX&lt;/code&gt;，区别可看 &lt;a class=&#34;link&#34; href=&#34;https://stackoverflow.com/questions/15796519/what-are-the-differences-between-xelatex-and-pdflatex&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;此帖&lt;/a&gt;。一言以蔽之，前者对中文和自定义字体支持更佳。&lt;/p&gt;
&lt;p&gt;配置属于VS Code首选项的一部分，所以可以填在工作区的. vscode/settings.json内，或用户首选项文件内。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;{
    &amp;#34;latex-workshop.latex.recipes&amp;#34;: [
        {
            &amp;#34;name&amp;#34;:&amp;#34;xelatex&amp;#34;,
            &amp;#34;tools&amp;#34;: [
                &amp;#34;xelatex&amp;#34;,
            ]
        },
        {
            &amp;#34;name&amp;#34;:&amp;#34;xelatex&amp;#43;bibtex&amp;#34;,
            &amp;#34;tools&amp;#34;: [
                &amp;#34;xelatex&amp;#34;,
                &amp;#34;bibtex&amp;#34;,
                &amp;#34;xelatex&amp;#34;,
                &amp;#34;xelatex&amp;#34;
            ]
        }
    ],
    &amp;#34;latex-workshop.latex.tools&amp;#34;: [
        {
            &amp;#34;name&amp;#34;: &amp;#34;bibtex&amp;#34;,
            &amp;#34;command&amp;#34;: &amp;#34;bibtex&amp;#34;,
            &amp;#34;args&amp;#34;: [
                &amp;#34;%DOCFILE%&amp;#34;
            ]
        },
        {
            &amp;#34;name&amp;#34;: &amp;#34;xelatex&amp;#34;,
            &amp;#34;command&amp;#34;:&amp;#34;xelatex&amp;#34;,
            &amp;#34;args&amp;#34;:[
                &amp;#34;%DOCFILE%&amp;#34;
            ]
        }
    ],
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;latex-workshop.latex.recipes&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex+bibtex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;tools&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;bibtex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;latex-workshop.latex.tools&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bibtex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;bibtex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;%DOCFILE%&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;xelatex&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;s2&#34;&gt;&amp;#34;%DOCFILE%&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;基础的配置文件如上，tools部分封装了某个工具的执行方法，并取一个名字，如 &lt;code&gt;xelatex&lt;/code&gt; tool就是 &lt;code&gt;xelatex %DOCFILE%&lt;/code&gt;。recipe则是通过指定不同工具执行的次数和次序，最终取得不同的结果。单独的xelatex适用于不含参考文献的情况，而xelatex+bibtex适用于含参考文献的情况。&lt;/p&gt;
&lt;p&gt;现在，在tex文件编辑界面按下Ctrl+S，就会自动开始编译，然后产生一个PDF文件。&lt;/p&gt;
&lt;h2 id=&#34;优化配置&#34;&gt;优化配置
&lt;/h2&gt;&lt;p&gt;首先，可以在上面的settings.json外层大括号中加入：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;    &amp;#34;latex-workshop.view.pdf.viewer&amp;#34;: &amp;#34;tab&amp;#34;,
    &amp;#34;latex-workshop.latex.autoBuild.interval&amp;#34;:30000,
    &amp;#34;latex-workshop.latex.recipe.default&amp;#34;: &amp;#34;lastUsed&amp;#34;,
    &amp;#34;editor.wordWrap&amp;#34;: &amp;#34;wordWrapColumn&amp;#34;,&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;latex-workshop.view.pdf.viewer&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tab&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;latex-workshop.latex.autoBuild.interval&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;30000&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;latex-workshop.latex.recipe.default&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;lastUsed&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;s2&#34;&gt;&amp;#34;editor.wordWrap&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;wordWrapColumn&amp;#34;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;作用分别为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;编译出的PDF预览显示在另一标签页中&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;间隔30秒内不重新编译&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;默认（即Ctrl+S）编译命令使用上一个使用的recipe&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;启用折行，即某行过长时折成两行显示&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;读者也可以探索更多的编辑器与插件设置。&lt;/p&gt;
&lt;p&gt;自带的PDF预览功能也过于孱弱，可以使用 &lt;a class=&#34;link&#34; href=&#34;https://marketplace.visualstudio.com/items?itemName=tomoki1207.pdf&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vscode-pdf&lt;/a&gt; 插件预览PDF，与Firefox浏览器的PDF预览有基本一致的体验。可以忽视插件的不支持警告，直接把PDF分屏预览，四舍五入就是Overleaf。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;试试Typst吧！可能是语法更简单、更自然的LaTeX，同时也在不断完善中，未来可期。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Markdown 编辑器横评（下篇）</title>
        <link>https://cyp0633.com/post/markdown-editor-review-2/</link>
        <pubDate>Thu, 14 Jul 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/markdown-editor-review-2/</guid>
        <description>&lt;p&gt;我在 &lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/archives/1618&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;横评的上篇&lt;/a&gt; 中，对将近20款编辑器进行了一个初步的探索，然而这种 “快速过一遍，凭主观印象” 的方式不甚准确，故制定一些标准，来对它们进行一个更客观（但也免不了主观因素）的评价。&lt;/p&gt;
&lt;p&gt;此部分横评覆盖了上篇中的所有Markdown编辑器——除了Microsoft Word这个来捣乱的。由于时间原因，测试项难免覆盖不完整，如果还有想了解的，可以在评论区留言，不过系统环境变化可能较大，不能保证结果完全可比较。&lt;/p&gt;
&lt;p&gt;部分测试项在以下仓库开源：&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/cyp0633/markdown-benchmark&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;cyp0633/markdown-benchmark&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TLDR
&lt;/h2&gt;&lt;p&gt;用一个Excel表格直观反映每项得分。没有考虑各项权重分配，并不能简单加和来得到最终结果。&lt;/p&gt;

&lt;iframe src=&#34;https://onedrive.live.com/embed?cid=2DADA3A05AA67F94&amp;amp;resid=2DADA3A05AA67F94%21314004&amp;amp;authkey=AAtL_CHrGb6orXg&amp;amp;em=2&#34;scrolling=&#34;no&#34;width=&#34;402&#34;height=&#34;346&#34;frameborder=&#34;0&#34;&gt;&lt;/iframe&gt;

&lt;h2 id=&#34;基本信息&#34;&gt;基本信息
&lt;/h2&gt;&lt;h3 id=&#34;界面设计&#34;&gt;界面设计
&lt;/h3&gt;&lt;p&gt;首先映入眼帘的就是软件的界面，一个高颜值的界面能够带来愉悦感，而设计得当的交互能够提高使用的效率。当然这方面也和个人的感觉有很大的关系。&lt;/p&gt;
&lt;p&gt;大部分编辑器都采用了较为简约的设计，以白色为主色调，在这方面Typora是当之无愧的标杆，主界面没有过于繁杂的元素，操作均收入顶栏，操作的分类安排也较为合理，能够很快找到想要的部分。但是也有很多编辑器简洁过了头，如Obsidian将很多常用操作都收进了右上角的菜单中，并没有很好的分类。WordMark将选项全都收进了按钮和Alt键菜单，这在macOS下可能无可厚非，但在Windows下十分别扭。VNote和Arya的编辑器界面有一定相似性，但VNote的界面看起来就更杂乱。Joplin的界面相对来说不算简洁，但很高效。&lt;/p&gt;
&lt;p&gt;批判一番Zettlr，按钮布置十分杂乱，学习成本极高；配色奇怪而压抑，没有设计感。不过QOwnNotes才是重量级，乱得实在用不下去。&lt;/p&gt;
&lt;h3 id=&#34;开源&#34;&gt;开源
&lt;/h3&gt;&lt;p&gt;软件开源，就意味着可以审查它的源代码来确保没有危险，对其作出自己的修改以符合自己的需求，或是为这个软件的开发完善贡献自己的力量。&lt;/p&gt;
&lt;p&gt;闭源软件有Typora、Obsidian、马克飞象和WordMark，而VS Code和IntelliJ IDEA只有核心部分开源。&lt;/p&gt;
&lt;h3 id=&#34;费用&#34;&gt;费用
&lt;/h3&gt;&lt;p&gt;大部分是免费的，收费的有整个收费和部分功能收费两种。目前整个收费的只有Typora，而StackEdit、IntelliJ、Obsidian和马克飞象有部分功能收费。StackEdit提供了Docker自托管的选项，同步云服务有一定困难，但导出PDF是免费功能。&lt;/p&gt;
&lt;p&gt;Joplin是一朵奇葩，它的同步服务器也是开源并开放自建的。&lt;/p&gt;
&lt;p&gt;值得注意的是，IntelliJ单作为一个Markdown编辑器的话，是免费的；而如果想获得基础Java支持之外的功能，则需要收费。&lt;/p&gt;
&lt;h3 id=&#34;持续更新&#34;&gt;持续更新
&lt;/h3&gt;&lt;p&gt;持续更新的能力能在一定程度上代表适配系统新特性的能力。比如Linux下，新版本Electron才对Wayland有基本的支持，考虑到Markdown编辑器大量采用Electron，这个特点也很重要。当然，很久不更新不代表表现就会差，一直会更新也不代表表现会好。&lt;/p&gt;
&lt;p&gt;Haroopad和WordMark的最后更新时间停在了数年前，而StackEdit和Notable也已经有一年没更新了。其余的在今年都有更新的记录。&lt;/p&gt;
&lt;h2 id=&#34;跨平台与云同步&#34;&gt;跨平台与云同步
&lt;/h2&gt;&lt;h3 id=&#34;桌面端跨平台&#34;&gt;桌面端跨平台
&lt;/h3&gt;&lt;p&gt;这里的桌面端跨平台，涵盖的是Linux、Windows和macOS。有几款竟然神奇地支持了FreeBSD，但鉴于用户实在太少，不强求。&lt;/p&gt;
&lt;p&gt;有Electron或者Qt加持的应用基本都能够正常支持跨平台，而网页端应用更不必说，凡是有浏览器的地方，就能跑起来。鉴于Windows版本一般没啥兼容性问题，笔者主要装了Linux版本试试。Notable的Linux版本有时候跑不起来，而Wordmark的Linux版遇到了经典依赖问题——装不上（当时使用的是Ubuntu 22.04）。&lt;/p&gt;
&lt;p&gt;另外还有一个异端Marker，仅支持Linux和FreeBSD。由于笔者没有Mac，此处也没有纳入许多Mac独占的优秀编辑器。&lt;/p&gt;
&lt;h3 id=&#34;移动端跨平台&#34;&gt;移动端跨平台
&lt;/h3&gt;&lt;p&gt;这部分网页端应用大获全胜，毕竟Electron又不支持移动端。除了网页端的几个应用之外，就只有VS Code、Joplin和Obsidian做了移动端支持。Obsidian和Joplin在移动端是原生应用，而VS Code用了另一种方案：直接把应用搬上了网页（&lt;a class=&#34;link&#34; href=&#34;https://vscode.dev&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vscode.dev&lt;/a&gt;，或GitHub Codespaces)。&lt;/p&gt;
&lt;p&gt;这三款支持移动端的App一致性都做得很好。&lt;/p&gt;
&lt;h3 id=&#34;云存储接入&#34;&gt;云存储接入
&lt;/h3&gt;&lt;p&gt;少数编辑器有自己的云存储空间，并作为增值服务售卖，如Obsidian；其他的编辑器（如StackEdit）则会依赖第三方的云存储，如OneDrive和Google Drive等。&lt;/p&gt;
&lt;p&gt;LetsMarkdown似乎使用了一种不同的方案。出于协作需求，它会将用户的文档默认保存至服务器。&lt;/p&gt;
&lt;p&gt;WordMark和StackEdit面向的是blogger，也就接入了WordPress、Medium和GitHub平台发表文章，就算它是个同步吧。&lt;/p&gt;
&lt;p&gt;Obsidian、VS Code和IntelliJ还提供了Git插件，但鉴于不是自带Git客户端，此处不算作接入云存储。&lt;/p&gt;
&lt;p&gt;QOwnNotes接入了Nextcloud和ownCloud等云存储服务，对自托管的服务支持较好。&lt;/p&gt;
&lt;p&gt;Joplin支持官方云、自建同步服务、OneDrive等同步服务。&lt;/p&gt;
&lt;h2 id=&#34;编辑体验&#34;&gt;编辑体验
&lt;/h2&gt;&lt;h3 id=&#34;指示功能&#34;&gt;指示功能
&lt;/h3&gt;&lt;p&gt;在主界面上常驻一些字数统计之类的功能是有必要的，而太多了则会适得其反。&lt;/p&gt;
&lt;p&gt;测试中，WordMark的字数统计完全无法正常使用，其目录也因为无法正确识别标题而难以使用。&lt;/p&gt;
&lt;p&gt;有目录的有Typora、Obsidian、MarkText、Notable、Typedown。&lt;/p&gt;
&lt;p&gt;有字数统计的有VS Code、Typora、Obsidian、StackEdit、MarkText、Zettlr、Haroopad、QOwnNotes、Typedown。&lt;/p&gt;
&lt;h3 id=&#34;图片管理&#34;&gt;图片管理
&lt;/h3&gt;&lt;p&gt;Markdown是纯文本格式，无法内嵌图片，所以需要额外的图片解决方案。有的会将图片存放在某个目录下，而有的支持上传至第三方云平台。&lt;/p&gt;
&lt;p&gt;存放于工作区内的有Obsidian、Typora、MarkText、Zettlr、IntelliJ、VNote、Notable、QOwnNotes、Joplin，一般都是粘贴时自动保存到工作区的特定文件夹中。&lt;/p&gt;
&lt;p&gt;能够上传到云端平台的有WordMark、Typora、MarkText。&lt;/p&gt;
&lt;p&gt;剩余的仅能插入外链。&lt;/p&gt;
&lt;h2 id=&#34;导出体验&#34;&gt;导出体验
&lt;/h2&gt;&lt;p&gt;一般来说都是导出PDF，所以此处重点体验PDF导出的质量，对其他格式只作数量要求，反正一般也是Pandoc实现。&lt;/p&gt;
&lt;p&gt;Notable和Marker不知道咋回事导不出，就算了。&lt;/p&gt;
&lt;h3 id=&#34;pdf可自定义度&#34;&gt;PDF可自定义度
&lt;/h3&gt;&lt;p&gt;一些软件可以自定义PDF导出的格式，从单纯的页面设置、页面主题，到可自定义CSS。&lt;/p&gt;
&lt;p&gt;支持多种内置主题的有StackEdit、MarkText、Typora，其中Typora一个非常强大的功能是可以使用CSS完全自定义主题。&lt;/p&gt;
&lt;p&gt;支持设置一些页面参数的有Obsidian和MarkText。&lt;/p&gt;
&lt;h3 id=&#34;pdf渲染质量&#34;&gt;PDF渲染质量
&lt;/h3&gt;&lt;p&gt;对于这一项，一般来说渲染没问题的都会得10分。值得注意的是，一些软件导出的PDF与预览有所不同，比如Zettlr导出后能够支持预览并不支持的规范。&lt;/p&gt;
&lt;p&gt;Obsidian对数学公式的渲染匪夷所思，虽然支持TeX公式，但渲染出来字体竟然是黑体。&lt;/p&gt;
&lt;p&gt;Dilinger虽有导出功能，但大量字符缺失，中文字符更完全无法显示。&lt;/p&gt;
&lt;p&gt;VS Code和IntelliJ在无插件的情况下不支持导出。&lt;/p&gt;
&lt;p&gt;QOwnNotes的情况有点奇怪，它会将Markdown符号一起导出，而非纯净的预览。这方面见仁见智，不过我给扣了分。&lt;/p&gt;
&lt;p&gt;还有的PDF导出后竟然比软件内预览的兼容性更强…… 很怪。&lt;/p&gt;
&lt;h3 id=&#34;其他格式数量&#34;&gt;其他格式数量
&lt;/h3&gt;&lt;p&gt;其实没啥好说的，能调用Pandoc的就有优势呗。&lt;/p&gt;
&lt;h2 id=&#34;commonmark语法&#34;&gt;CommonMark语法
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://spec.commonmark.org/0.30&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CommonMark 标准&lt;/a&gt; 是对原版Markdown规定的细化，内含基础的Markdown语法，更适合作为一个基本的Markdown要求。&lt;/p&gt;
&lt;p&gt;此部分的得分是能正常通过的测试项数量。通过数量多的一定代表好，但通过数量少的也不一定难用，因为其中也包含一些平常不会触及的corner case，而CommonMark也只是其中一个标准，并无强制性。&lt;/p&gt;
&lt;h3 id=&#34;基本&#34;&gt;基本
&lt;/h3&gt;&lt;p&gt;此部分包含 “字符与行”、“制表符”、“转义字符”、“实体和数字字符” 这些方面。&lt;/p&gt;
&lt;p&gt;WordMark最惨，即使是Electron，稍复杂的格式基本无法正常渲染。&lt;/p&gt;
&lt;h3 id=&#34;叶块&#34;&gt;叶块
&lt;/h3&gt;&lt;p&gt;此部分包含”ATX标题”、“设置文本标题”、“缩进代码块”、“围栏代码块”、“HTML块”、“链接引用”、“段落” 等方面。&lt;/p&gt;
&lt;p&gt;这里大部分编辑器没有得分的地方是paragraph部分。CommonMark要求两行之间间隔一行才能算作换行，而大部分编辑器并没有严格遵守，渲染出了5行（本应该是2行）。大部分情况下其实也可以不算一个问题。&lt;/p&gt;
&lt;p&gt;“设置文本标题” 部分出的问题也千奇百怪，有的只能识别一行标题，有的甚至识别不出标题。&lt;/p&gt;
&lt;p&gt;Joplin避过了所有的坑，成为惟一一个全部通过的编辑器。&lt;/p&gt;
&lt;h3 id=&#34;容器块&#34;&gt;容器块
&lt;/h3&gt;&lt;p&gt;此部分包含 “块引用”、“列表项” 两个方面。&lt;/p&gt;
&lt;p&gt;有的编辑器如马克飞象和Marker等，会直接将自定义序号替换成从1开始编号。&lt;/p&gt;
&lt;h3 id=&#34;内联&#34;&gt;内联
&lt;/h3&gt;&lt;p&gt;此部分包含 “代码块”、“强调和特别强调”、“链接”、“自动链接” 和“图片”几个方面。“代码块”部分特增加了几个非传统热门语言。&lt;/p&gt;
&lt;p&gt;此处着重说一下代码块。C的高亮应该是只要支持语法高亮就会包含的，而新兴的如Rust，以及没那么热门的Verilog / 汇编则支持较少。Typora是唯一一个能支持汇编（&lt;code&gt;assembly&lt;/code&gt;）渲染的编辑器，而大部分出现0.5分的编辑器都是因为语法高亮支持不全。&lt;/p&gt;
&lt;h2 id=&#34;gfm语法&#34;&gt;GFM语法
&lt;/h2&gt;&lt;p&gt;GitHub也是使用Markdown语法较多的平台，它在一定程度上扩展了原版Markdown的语法，形成了 &lt;a class=&#34;link&#34; href=&#34;https://docs.github.com/cn/get-started/writing-on-github&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Flavored Markdown 标准&lt;/a&gt;，也有一定的影响力。&lt;/p&gt;
&lt;h3 id=&#34;表格&#34;&gt;表格
&lt;/h3&gt;&lt;p&gt;绝大部分编辑器都不能正常渲染 &lt;code&gt;\|&lt;/code&gt; 的转义符号，虽然不会将其识别为表格分隔符，但显示仍然是 &lt;code&gt;\|&lt;/code&gt; 而不是期望的 &lt;code&gt;|&lt;/code&gt;。&lt;/p&gt;
&lt;h3 id=&#34;待办列表&#34;&gt;待办列表
&lt;/h3&gt;&lt;p&gt;Marker成为了参测编辑器中唯一一个不支持待办语法的编辑器。&lt;/p&gt;
&lt;h3 id=&#34;自动标题&#34;&gt;自动标题
&lt;/h3&gt;&lt;p&gt;GFM的自动标题相比于CommonMark添加了对没有任何外加标记的链接的直接识别。很少有编辑器能够将邮箱地址自动识别为mailto链接，大部分都较为保守，毕竟也有一定的误识别可能性。&lt;/p&gt;
&lt;h3 id=&#34;图表&#34;&gt;图表
&lt;/h3&gt;&lt;p&gt;GFM定义了Mermaid、Geojson、Topjson和STL模型四种图表格式。都是基于代码块定义的。尴尬的是，哪怕表现最好的编辑器也只支持Mermaid，而后三种只有GitHub网页能正常显示。&lt;/p&gt;
&lt;p&gt;后续可能会增加PlantUML等其他图表的测试？等有空再说吧。&lt;/p&gt;
&lt;h3 id=&#34;数学公式&#34;&gt;数学公式
&lt;/h3&gt;&lt;p&gt;GFM定义了使用两个 $ 符号的公式块、使用一个 $ 符号的内联公式，以及使用代码块格式的公式定义。此外还借用了 &lt;a class=&#34;link&#34; href=&#34;https://nschloe.github.io/2022/05/20/math-on-github.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文章&lt;/a&gt; 中GitHub数学公式的一些bug。&lt;/p&gt;
&lt;h2 id=&#34;性能&#34;&gt;性能
&lt;/h2&gt;&lt;p&gt;渲染较大规模文档的能力也是很重要的一个方面。这里使用从Project Gutenberg下载的《战争与和平》英文版（56.5万词，3MB），并转换为Markdown文件用于测试。对于能在Linux安装的编辑器，测试环境是Ubuntu 22.10开发分支，AMD Ryzen 7 4800H，24G内存，GeForce GTX 1650+NVIDIA闭源驱动。如果不能安装，使用Windows 11 22621.160。对于网页版编辑器，这里忽略平台不同的影响，均选择Firefox最新版本，使用浏览器任务管理器查看内存占用。&lt;/p&gt;
&lt;p&gt;StackEdit最大支持打开约250KB的文档，剩余部分被截断，无法完成测试。Typora不支持打开此大小的文件。Zettlr查看时经常卡死无响应。Arya粘贴后直接卡死。Marker完全无响应。&lt;/p&gt;
&lt;h3 id=&#34;打开时间&#34;&gt;打开时间
&lt;/h3&gt;&lt;p&gt;打开软件，从软件中的打开方式打开文档开始计时，到加载出正确渲染的文档内容。&lt;/p&gt;
&lt;p&gt;VS Code的代码加载很快，几乎马上就能加载出来，但预览很慢。类似的情况也在类Typora的所见即所得的编辑器中出现，如果需要将整个文档渲染一遍，就会花很长时间。&lt;/p&gt;
&lt;h3 id=&#34;内存占用&#34;&gt;内存占用
&lt;/h3&gt;&lt;p&gt;需要注意，网页端和原生应用的内存占用不能直接比较。网页本身的内存占用通常很小，许多浏览器本身动辄占用几百兆内存，而大部分Electron应用相当于再开了一个浏览器。&lt;/p&gt;
&lt;h3 id=&#34;流畅度&#34;&gt;流畅度
&lt;/h3&gt;&lt;p&gt;将流畅度从0-10打分，很流畅则得10分，完全无法正常浏览则得0分。&lt;/p&gt;
&lt;p&gt;v2ex网友说MarkText有性能问题似乎是真的，不过能打开也比Typora强了。&lt;/p&gt;
&lt;p&gt;VS Code不知道吃了什么微软神油，编辑和浏览都巨流畅。&lt;/p&gt;
&lt;h2 id=&#34;另记&#34;&gt;另记
&lt;/h2&gt;&lt;p&gt;Typora的数学公式渲染需要手动开启。&lt;/p&gt;
&lt;p&gt;VS Code缺失的部分基本可以使用插件开启，如导出文档、Mermaid图表等。&lt;/p&gt;
&lt;p&gt;哦忘了说了，Electron是真不太行。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Markdown 编辑器横评（上篇）</title>
        <link>https://cyp0633.com/post/markdown-editor-review-1/</link>
        <pubDate>Sat, 11 Jun 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/markdown-editor-review-1/</guid>
        <description>&lt;p&gt;之前曾读到一位友人写的 &lt;a class=&#34;link&#34; href=&#34;https://blog.skywt.cn/posts/seven-notes-and-wiki-systems-evaluation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;私有部署知识库系统横评&lt;/a&gt; 文章，感觉十分的有帮助，认识到除难部署的Outline之外全都不符合自己需求，遂直接把自己的文字笔记全切到了Notion（大雾）。但是Notion本身是一个知识库系统，并不能很好支持Markdown格式，也不够轻量化，对于写一份简单文档的需求，单纯的Markdown编辑器无疑是更好的选择。**如果你找Markdown编辑器是为了记笔记，那么我更建议你读读上面链接中的文章，知识库的方案会更加有优势。**PS：现在我的笔记已经全都在 &lt;a class=&#34;link&#34; href=&#34;https://github.com/siyuan-note/siyuan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;思源&lt;/a&gt; 上面了。&lt;/p&gt;
&lt;p&gt;但很显然我不只有记笔记的需求，所以挑选了几款Markdown编辑器做一个横评。Markdown编辑器没有one size fit all，每款编辑器有自己的哲学，有的追求多而全的功能，有的追求极致的性能，有的坚守 &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/KISS_principle&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;KISS 原则&lt;/a&gt;，有的开发了插件系统，还有的只是顺便做个Markdown编辑功能。为了挑选一款适合自己的编辑器，我还是建议读者通读上下篇。你现在看到的是上篇，包含了我对每一款编辑器的主观大概评价，但无法表现哪个方面谁做得更好；而&lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/archives/1778&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;下篇&lt;/a&gt; 注重量化对比，但对于一些特色功能，无法体现在表格中。&lt;/p&gt;
&lt;p&gt;在这里特别感谢每一位开发者，特别是开源软件贡献者，没有他们，就没有编辑器百花齐放的今天。&lt;/p&gt;
&lt;p&gt;测试环境&lt;/p&gt;
&lt;p&gt;凡是有Linux版的，都会采用Linux版进行测试，使用Wayland显示协议。一般来说这种条件下适配是最不充分的，能暴露一些缺点。&lt;br&gt;
Windows或macOS独占的，当然只能用独占的了。由于不在同一台机器上测试，性能表现难免不同。但是即使硬件性能再强，有的编辑器也一塌糊涂。&lt;/p&gt;
&lt;h2 id=&#34;typora&#34;&gt;Typora
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/typora.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Typora（旧版本）主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://typoraio.cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Typora&lt;/a&gt; 是一款使用Electron开发的Markdown编辑器。可惜Beta结束后收费了，还有点贵，但它还是给我留下了非常好的印象。可以说是Markdown编辑器的标杆之作。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;所见即所得（即所谓WYSIWYG，默认打开效果实时预览）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面简洁干净，使用体验舒适&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持使用CSS自定义模板，还有大量现成第三方模板&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;大量的自定义语法选项‘&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强大的图片管理选项&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;闭源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;收费（国内价格89元）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;obsidian&#34;&gt;Obsidian
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/obsidian.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Obsidian 主界面。我曾用它记笔记&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;据 &lt;a class=&#34;link&#34; href=&#34;https://obsidian.md/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Obsidian&lt;/a&gt; 官方的定义，它其实也算是个知识库软件，但也遵守Markdown语法，还有知识图谱功能。如果你既要记笔记还要写文档，可以选择Obsidian。它也是使用Electron开发的。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS、Android、iOS/iPadOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;知识图谱功能，根据反向链接探寻知识点之间的关系&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;有很多插件，如看板、Git（需要Git客户端，自然不支持移动端）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可选的所见即所得模式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;官方同步服务，$8 / 月&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Windows版自带优雅大方的苹方字体&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;闭源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;菜单有点乱&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;stackedit&#34;&gt;StackEdit
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/stackedit.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;StackEdit 界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/benweet/stackedit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;benweet/stackedit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://stackedit.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;StackEdit&lt;/a&gt; 是一个开源的网页端编辑器，我觉得最大的亮点应该是自带网盘工作区同步，所以移动端也可以。可以使用Docker镜像自行搭建，或者使用作者搭建的公用版本。编辑模式预览不太完全，但有一个带完整格式渲染的预览模式。目前我主要在用这款。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;网络同步（Google Drive、GitHub、Gitlab、Dropbox）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自带Cheatsheet和顶部快捷格式栏&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多种模板支持，但只有导出时可以用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多个工作区可以分别管理同步策略或导出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非常多的导出格式策略可选&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UML图和音符支持&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Service Worker支持的离线编辑&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Docker版不能保存到服务器目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Docker镜像太大了&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;公用版需要订阅制捐赠才能导出文件（考虑到开源，算半个缺点；Docker版可以直接导出）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Google Drive要频繁重新认证&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;zettlr&#34;&gt;Zettlr
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/zettlr.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Zettlr 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Zettlr/Zettlr&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Zettlr/Zettlr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Zettlr又是一个使用Electron开发的编辑器。太丑了，没细用。不过这个Hashtag特性似乎挺有意思，不失为管理知识的另一种方案。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;良好的外部文献管理支持（如Zotero）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非常多的导出格式可选（依赖于Pandoc）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;丑！！！！完全打消了我用的欲望&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有预览模式，不能做到完全的所见即所得&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;工作区加载慢&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;dillinger&#34;&gt;Dillinger
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/dilinger.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Dilinger 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/joemccann/dillinger&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;joemccann/dillinger&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://dillinger.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Dillinger&lt;/a&gt; 是一个开源的网页Markdown编辑器。看起来挺好的，但它有几个致命伤，拳拳到肉，所以我没用它，光是好看还是不能当饭吃啊。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;界面美观&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;语法高亮和分栏实时预览&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;云同步（Dropbox、OneDrive、GitHub……）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不支持TeX公式渲染&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PDF导出无法正确渲染中文&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持内联HTML符号&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;marktext&#34;&gt;MarkText
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/marktext.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;MarkText 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/marktext/marktext&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;marktext/marktext&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://marktext.app/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MarkText&lt;/a&gt;（域名都过期了）是一个使用Electron开发的开源编辑器，很多部分都与Typora相近。我在其开发早期就用过，但bug实在是太多了，于是马上就卸了。最近发现已经改善了不少，或许有希望成为Typora的开源平替。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Typora一样的所见即所得&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Typora一样优雅的外观&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多种主题，但暂时不支持第三方导入&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;多种图表支持（Mermaid、UML等）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;丰富的PDF导出格式选择&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Typora相似的强大图片管理&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;HTML语法和Markdown格式不能混写（带HTML的必须转化为内联HTML块）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;还是有少量bug，但不影响正常使用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;据说有性能问题（见 &lt;a class=&#34;link&#34; href=&#34;https://www.v2ex.com/t/860011#reply38&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;V2EX&lt;/a&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;notable&#34;&gt;Notable
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/notable.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Notable 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/notable/notable&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;notable/notable&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://notable.app&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Notable&lt;/a&gt; 正如名字所示，它设计上仍然是一款笔记管理软件。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;界面简洁美观&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内置Emoji面板和语法Cheatsheet&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用Tag管理笔记&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;将笔记通过网页分享&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;自2020年1月，长期未更新&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不能单独打开Markdown文档，必须以笔记本形式组织&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;闭源（1.5.1后）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;vnote&#34;&gt;VNote
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/vnote.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;VNote 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/vnotex/vnote&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vnotex/vnote&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;VNote是一款国人开发的开源笔记管理软件。管理笔记还算方便，但写普通文档的时候只比Obsidian方便一点。体验不算很优秀，但不用Electron很难得。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;使用Qt开发，不是Electron！！！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PDF导出体验较好&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Linux可能需要使用 &lt;code&gt;--no-sandbox&lt;/code&gt; 选项才能显示预览（见 &lt;a class=&#34;link&#34; href=&#34;https://github.com/vnotex/vnote/issues/2104#issuecomment-1107438016&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;此链接&lt;/a&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面美观度一般&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;预览同步滚动卡顿&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;arya&#34;&gt;Arya
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/arya.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Arya 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/nicejade/markdown-online-editor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;nicejade/markdown-online-editor&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://markdown.lovejade.cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Arya&lt;/a&gt; 是一个轻量级的网页端Markdown编辑器。之所以说它轻量，是因为它连工作区的概念都没有，同时只能编辑一个文件。&lt;/p&gt;
&lt;p&gt;值得一提的是，它是基于 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Vanessa219/vditor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vditor&lt;/a&gt; 的，而Vditor与思源笔记有着千丝万缕的联系。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;十分简洁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持的输入丰富，TeX和Mermaid图表等都有&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;桌面、Pad和手机端视图预览&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;比Typora稍弱的所见即所得&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可以上传图片和录音&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;开发者视图，DOM分层&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;同时只能编辑一个文件（不过有本地暂存）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;滚动预览有点不太同步&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持内联HTML&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;letsmarkdown&#34;&gt;LetsMarkdown
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/letsmarkdown.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Let&amp;rsquo;s Markdown 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/Cveinnt/LetsMarkdown.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cveinnt/LetsMarkdown.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;LetsMarkdown是以协作为主要特点的在线Markdown编辑器。它有着类似VS Code的主界面，以及一些自动补全功能，主界面只有源代码区、预览区和分享链接。是的，除此之外，啥都没有。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;VS Code同款编辑模块，上手难度小，简洁大方&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非常简单的协作体验&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;emoji支持&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;简洁得甚至有些简陋&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;就连同步滚动也没有（画了个饼，会加）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;haroopad&#34;&gt;Haroopad
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/haroopad.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Haroopad 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Haroopad是 “the next document processor”，至于是什么货色，你看一眼上面的图就知道了。不过在我顺着Issue Tracker找到了它的GitHub后（是的，我差点当它闭源了），发现最后一个Issue在四年前，那就解释得通了…… 古早项目，权当怀念。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/rhiokim/haroopad&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;rhiokim/haroopad&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持CommonMark、GFM等多种Markdown标准&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;字体渲染一塌糊涂&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;软件长年不更新&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;滚动源代码可同步滚动预览，但反之不行&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;源代码侧没有语法高亮&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;qownnotes&#34;&gt;QOwnNotes
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/qownnotes.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;QOwnNotes 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.qownnotes.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;QOwnNotes&lt;/a&gt; 是一款使用Qt+C++ 写成的笔记管理软件（是的，又一个非Electron）。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/pbek/QOwnNotes&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pbek/QOwnNotes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS，&lt;strong&gt;居然还有FreeBSD&lt;/strong&gt;）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Qt而非Electron，高效低占用&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;强大的云端同步服务&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;界面非常乱，连对比预览都找不到在哪&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;编辑Markdown文档必须先导入笔记目录&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;对HTML标签支持不佳&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;马克飞象&#34;&gt;马克飞象
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/maxiang.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;马克飞象主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://maxiang.io/#&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;马克飞象&lt;/a&gt; 是为印象笔记定制的网页端Markdown编辑器，比较适合印象笔记用户。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;界面简洁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;流畅的预览和同步滚动&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;印象笔记深度集成&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不支持Markdown文档的导入，只能粘贴&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持导出&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTML标签有点bug&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;wordmark&#34;&gt;WordMark
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/wordmark.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;WordMark 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://wordmarkapp.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WordMark&lt;/a&gt; 是一款为写博客的人而设计的Markdown编辑器，不过作为普通的Markdown编辑器也可以。由于经典的依赖问题，它的Linux版本我死活装不上（不一定是它的原因），闭源也没法自己构建。另外，它似乎和Typora一样在测试期间免费，但照这个更新频率可能永远出不了beta了。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;简洁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;能够直接发布文章到WordPress/Medium/GitHub等平台，或者上传图片到托管服务&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨三大桌面平台&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;闭源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;长期不更新&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;中文字体渲染诡异（上图英文是苹方，中文是宋体…… 开发者甚至似乎是个国人）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTML标签支持差&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持公式渲染&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;marker&#34;&gt;Marker
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/marker.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Marker 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/fabiocolacio/Marker&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;fabiocolacio/Marker&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://fabiocolacio.github.io/Marker/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Marker&lt;/a&gt; 是基于GTK3的Markdown编辑器，得益于此，它有着原生的流畅体验，但支持的平台很少。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不是Electron&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;可自定义的CSS样式和语法&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持Mermaid等组件&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;仅支持Linux和FreeBSD&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;似乎语法支持不太全&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;joplin&#34;&gt;Joplin
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-zoom-src=&#34;https://cyp0633.com/images/joplin.png&#34; src=&#34;https://cyp0633.com/images/joplin.png&#34; loading=&#34;lazy&#34;  alt=&#34;Joplin 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/laurent22/joplin&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;laurent22/joplin&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Joplin是使用Electron开发的开源笔记软件，使用Markdown格式。把它加进来是因为呼声实在是太高了，歪打正着又发现它除了记笔记之外，对Markdown语法的支持也是很不错的。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;广泛的移动端和桌面端设备支持&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;完善的云端同步方案，还可自行托管同步服务端Joplin Server&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;语法支持较为完善且标准&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面比较整洁&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;较好的图片管理&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;必须导入为笔记或笔记本才可编辑&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;typedown&#34;&gt;Typedown
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/typedown.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Typedown&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.microsoft.com/en-us/p/typedown-a-wysiwyg-markdown-editor/9p8tcw4h2hb4&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Typedown&lt;/a&gt; 是一款遵循WinUI规范的Markdown编辑器。logo有点山寨，但对于日常使用来说还是够用的，而且颜值也能令人耳目一新。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Fluent Design规范，外观优秀&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;菜单组织合理&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;仅支持Windows 10及以上，不支持其他平台&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;闭源&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;ghostwriter&#34;&gt;Ghostwriter
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/ghostwriter.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Ghostwriter&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://ghostwriter.kde.org/zh-cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ghostwriter&lt;/a&gt; 是一款来自KDE的开源Markdown编辑器，基于Qt，但名字不含K。在distraction-free这个方面，它做得确实很好，并且对标准执行得也很严格。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;非Electron&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨三大桌面平台（macOS必须自己编译）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面简洁而不失易用性&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;渲染语法非常标准，且能够切换使用多种标准模式&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;写作时间与效率统计、阅读难度分析&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;快&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;代码没有语法高亮&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;默认 &lt;code&gt;cmark-gfm&lt;/code&gt; 模式只支持导出HTML&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;预览与代码不能同时上下翻动&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持数学公式预览&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;仍使用了Qt Web Engine渲染预览，占内存稍大&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;keenwrite&#34;&gt;KeenWrite
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/keenwrite.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;KeenWrite&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/DaveJarvis/keenwrite&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;DaveJarvis/keenwrite&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;KeenWrite是一款以 “&lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/String_interpolation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;string interpolation&lt;/a&gt;&amp;quot;（将某些常用的字符串设为变量，使用时可以直接调用，类似于Kotlin）为特色、基于Java的开源Markdown编辑器。如你所见，由于某些不知名的bug，右边并没有显示出预览。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;非Electron&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;创新性的将string interpolation引入Markdown编辑器&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨三大桌面平台&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;占内存巨大，又卡又慢（Java嘛…… 打开 &lt;code&gt;perf.md&lt;/code&gt; 完全无响应，还吃掉了1G内存）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;存在无法显示预览的bug（可能是暂时性 / 个例；影响了所有依赖于预览的测试项目）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;notepads&#34;&gt;Notepads
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/notepads.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Notepads \* 深色模式&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/0x7c13/Notepads&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;0x7c13/Notepads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.notepadsapp.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Notepads&lt;/a&gt; 是一款Windows下的文本编辑器，支持Markdown渲染。外观还可以，但基本只适合轻度的编辑。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;好看&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;非Electron&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;占用小，非常快&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;仅支持Windows 10及以上，不支持其他平台&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;语法特性支持较差，且无数学公式渲染&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;1MB文件限制&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持导出为其他文档&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;妙言&#34;&gt;妙言
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/miaoyan.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;妙言 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/tw93/MiaoYan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;tw93/MiaoYan&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;http://miaoyan.app&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;妙言&lt;/a&gt; 是一款macOS平台的Markdown编辑器。很轻盈，很好看，唯独可惜不支持其他平台。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;简洁优美，很符合对macOS的印象&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swift原生开发&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;放映模式，将Markdown文档变成演示文稿&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;较好地符合CommonMark标准，预览、导出始终如一&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;罕见地支持Mermaid、PlantUML等图表&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;支持PicGo等图床上传，默认也会将图片保存到本地&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不跨平台&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;似乎不支持分栏显示预览和编辑（似乎是作者有意的），也没有所见即所得（暂时）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;yank-note&#34;&gt;Yank Note
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/yank.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Yank Note 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/purocean/yn&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;purocean/yn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://yanknote.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Yank Note&lt;/a&gt; 是一款扩展性极强的 “面向程序员的”Markdown笔记应用。嗯，确实很程序员（褒义 + 贬义）。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;强大的插件体系，Mermaid、Draw.io、ECharts、Git、Milkdown甚至Code Runner运行代码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;信息多而全&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;完善的图片处理逻辑，本地保存 + PicGo&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;宏替换（付费功能）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;提供少见的在线demo&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;配色有点死板，不够灵动&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;拖动预览，代码却不能一块儿拖动&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;markedit&#34;&gt;MarkEdit
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/markedit.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;MarkEdit 主界面 \* 深色模式&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/MarkEdit-app/MarkEdit&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MarkEdit-app/MarkEdit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MarkEdit是一款在贯彻自己哲学的Markdown编辑器，从里到外地简洁（也简陋）。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;轻快，非常小&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;性能强，完全不卡，占用最小（甚至比网页端的几个还小）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面没有什么多余的元素&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;内置Grammarly&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Swift原生开发，支持触控板重按手势等macOS特性&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不跨平台（仅macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有预览也没有所见即所得，只有代码高亮和一定的格式（&lt;a class=&#34;link&#34; href=&#34;https://github.com/MarkEdit-app/MarkEdit/wiki/Philosophy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;有意而为之&lt;/a&gt;，但这造成了数学公式和图片预览等一些方面吃了亏）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没有直接的导出、图片管理等功能（&lt;a class=&#34;link&#34; href=&#34;https://github.com/MarkEdit-app/MarkEdit/wiki/Why-MarkEdit#feature-poor&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;也是有意而为之&lt;/a&gt;，只能手动复制Pandoc命令导出）&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;visual-studio-code&#34;&gt;Visual Studio Code
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/vscode.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;VS Code 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/vscode&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;microsoft/vscode&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;提到编辑文件，可能永远都绕不开VS Code，它也是我们的老朋友了。仅仅是编辑Markdown的话，不装任何插件的VS Code就能基本胜任，但不要忘了它有一个巨大的插件市场，大部分不满意的方面都能通过插件搞定。虽然效果可能只能说差强人意，但总比没有强。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（也许）早就是装机必备软件了，上手成本低&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS，也可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/coder/code-server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;code-server&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://vscode.dev/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;vscode.dev&lt;/a&gt; 等方法在网页端使用）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面比较美观&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;带语法高亮和实时预览&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;深度融合代码工作区，适合用来写readme&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;什么都找得到的插件市场，包括神奇的GitHub Copilot自动补全&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;虽然是Electron，但性能非常好&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;导出PDF需要装插件，体验欠佳&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;intellij-idea&#34;&gt;IntelliJ IDEA
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/idea.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;GoLand 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/JetBrains/intellij-community&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;JetBrains/intellij-community&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;写Java的读者应该对IDEA很熟悉了。用它写起Markdown也是很舒服的，代码块内还能自动补全，就像直接编译源代码一样。这里直接用GoLand了，毕竟JetBrains家IDE基本都是一个样。但是这个玩意似乎完全不支持PDF导出，或许JB加入这个功能的本意就只是写个readme吧。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;跨平台（Windows、Linux、macOS）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;与IDE工作区深度融合&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不是Electron或Web端&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;语法高亮和实时预览&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;代码块内的自动补全和快捷运行&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;图表支持&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不能导出PDF&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;打开一个项目才能写&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不支持TeX公式&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;microsoft-word&#34;&gt;Microsoft Word
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/MSWord.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;MS Word 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;混乱邪恶势力来了，吔屎啦，Markdown！！！Pandoc支持将Word文档转换为Markdown格式，而Word也有完善的PDF导出功能。鉴于Word本身的优秀体验，我觉得倒也不是完全不可行。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;操作逻辑简单，基本都能使用GUI完成，符合大部分人习惯&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;界面美观&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OneDrive同步深度融合，体验极佳&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不是Electron&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;功能强大&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;（桌面版）仅不支持Linux&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;闭源，价格昂贵&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;与Markdown特性不能完美兼容（也可以说完全不能兼容）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;极差的代码输入体验&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;xcode&#34;&gt;Xcode
&lt;/h2&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;markdown-editor-review-1/xcode.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Xcode 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;算Word不算Xcode的话，有点不合适了吧。当然，这玩意摆在这儿还是为了整活。&lt;/p&gt;
&lt;p&gt;优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;性能挺强的，战争与和平滑动完全不卡&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CommonMark支持还算不错&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;缺点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;不跨平台&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;闭源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;除CommonMark之外支持稀烂&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;待测&lt;/strong&gt;：&lt;a class=&#34;link&#34; href=&#34;https://editor.vrite.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Vrite&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>用 VMware Workstation 安装 Ubuntu 12.04 LTS 简明教程</title>
        <link>https://cyp0633.com/post/vmware-ubuntu-12.04/</link>
        <pubDate>Sat, 22 Jan 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/vmware-ubuntu-12.04/</guid>
        <description>&lt;p&gt;这篇文章主要是课程取向的，所以才会使用一个已经超出生命周期的32位Ubuntu版本。在对自己的水平有些许信心后，更建议安装仍提供32位版本的Debian最新版，即Debian 11。新的系统有更好的软件支持，更安全，也更加易用。&lt;/p&gt;
&lt;p&gt;选择VMware Workstation主要是个人认为因为它的操作对小白较友好。本文以VMware Workstation Pro 16.2.2和Windows 11为例，最近几个VMware版本和Windows 10操作基本相同。&lt;/p&gt;
&lt;p&gt;折叠框中的内容，是我认为可以帮助理解的补充知识，但不看这部分不影响你按照步骤装好一个虚拟机。如果还有疑问，欢迎评论。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;什么是虚拟机？&lt;/p&gt;
&lt;p&gt;如果你读过《三体III：死神永生》，你大概记得其中出现了一个小型的宇宙，物质来源于最初的大宇宙，当中有智子等人，与大宇宙隔离，独立生活。有一天，探测到由于小型宇宙带走了太多的物质，导致大宇宙的物质不够，需要将小型宇宙的物质移回大宇宙才能让宇宙继续存在（记得可能不准确，欢迎指正）。&lt;/p&gt;
&lt;p&gt;虚拟机是同样的道理，它划走物理机的一部分硬件而创造出一个以假乱真而又几乎完全隔离小型的物理机形态，你可以在上面跟物理机一样安装操作系统，研究程序原理，打游戏，做你想做的事情。虚拟机就相当于小型宇宙，而物理机相当于大宇宙，当虚拟机占用太大的时候，物理机也是会带不动的。&lt;br&gt;
对于CPU、内存和显卡，VMware Workstation Pro的虚拟化技术是将虚拟机占用作为一个进程；对于网络，是在物理机上安装虚拟网卡，模拟虚拟机连接到物理机网络上；而对于硬盘，使用文件模拟，这使得虚拟机可以拷贝、移动，当成一些文件来对待。&lt;/p&gt;
&lt;p&gt;什么是Ubuntu？&lt;/p&gt;
&lt;p&gt;Linux（严谨点，GNU/Linux）是Linus Torvalds由Unix得到灵感，编写的开源自由的系统，它属于 “类Unix”。我们熟悉的macOS就是Unix的一个分支，Debian Foundation基于Linux开发了Debian，而Canonical基于Debian开发了Ubuntu。&lt;br&gt;
Debian、Ubuntu和其他一些系统如Arch Linux、Alpine、Kali Linux等统称为Linux的发行版，意为包装好供用户使用的Linux版本。如果你对Unix系统的历史知识有些兴趣，可以看一下下面这张图。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/Unix_history-simple.svg&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Unix 系统演化图&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Unix系统演化图。版权信息：Eraserhead1, Infinity0, Sav_vas, CC BY-SA 3.0 &lt;a class=&#34;link&#34; href=&#34;https://creativecommons.org/licenses/by-sa/3.0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://creativecommons.org/licenses/by-sa/3.0&lt;/a&gt;, via Wikimedia Commons&lt;/p&gt;
&lt;h2 id=&#34;环境准备&#34;&gt;环境准备
&lt;/h2&gt;&lt;p&gt;首先要从 &lt;a class=&#34;link&#34; href=&#34;http://old-releases.ubuntu.com/releases/precise/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Canonical 网站&lt;/a&gt; 下载Ubuntu 12.04 LTS的镜像。在下面的列表中找到ubuntu-12.04.5-desktop-i386.iso，然后点击此链接即可下载。”创建虚拟机“之前能够下载完成就行了。&lt;/p&gt;
&lt;p&gt;然后从 &lt;a class=&#34;link&#34; href=&#34;https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VMware&lt;/a&gt; 网站找到Workstation 16 Pro for Windows并点击Download Now。&lt;/p&gt;
&lt;p&gt;VMware Workstation安装包下载之后，打开安装包，同意许可协议。&lt;/p&gt;
&lt;p&gt;安装位置可以任选，“增强型键盘驱动程序”和 “添加到PATH” 也可以任选，我印象里VMware的命令行程序用得不多，所以不需要加到PATH中。&lt;/p&gt;
&lt;p&gt;“启动时检查更新”和 “加入用户体验计划” 按需选择。&lt;/p&gt;
&lt;p&gt;创建两个快捷方式按需选择。&lt;/p&gt;
&lt;p&gt;最后，点击安装即可安装。&lt;/p&gt;
&lt;p&gt;第一次打开VMware的时候应该会提示激活。激活码请自行搜索寻找，如财力雄厚建议入正。&lt;/p&gt;
&lt;h2 id=&#34;创建虚拟机&#34;&gt;创建虚拟机
&lt;/h2&gt;&lt;p&gt;VMware Workstation左上角文件 - 新建虚拟机。&lt;/p&gt;
&lt;p&gt;类型选择典型。&lt;/p&gt;
&lt;p&gt;” 安装客户机操作系统 “时，选择”&lt;strong&gt;稍后安装操作系统&lt;/strong&gt;“-”Linux“-”Ubuntu“。如果你让VMware帮你安装，后续调整中文的操作可能有困难。&lt;/p&gt;
&lt;p&gt;”虚拟机名称”和 “路径” 可以自行决定，但个人建议本路径下保证50GB左右空闲。我们需要划出大量空间作为虚拟机的硬盘，虽然不会立即全部占满，但最好还是留有空余。&lt;/p&gt;
&lt;p&gt;“最大磁盘大小 “我填写了45GB，读者也可以按需填写。这个值后期可以扩大，但需要使用分区工具同步扩大系统分区，有一定的学习成本，所以建议一开始就做得大一点。是否拆分多个文件，也是按需选择。&lt;/p&gt;
&lt;p&gt;下一步后，点击”自定义硬件 “。” 内存 “设定最大4GB即可，因大部分人电脑都是16GB RAM，不缺这4G；” 处理器 “中” 每个处理器的内核数量 “建议设定为你的处理器线程数量，这个可以在任务管理器 - 性能 - CPU的” 逻辑处理器 “查看。” 新CD/DVD（SATA）“选择”使用ISO映像文件“，浏览你的Ubuntu ISO镜像（就是之前下载的ubuntu-12.04.5-xxxxxxx.iso）并选择它，然后勾选“启动时连接”。&lt;/p&gt;
&lt;p&gt;为什么是4GB？&lt;/p&gt;
&lt;p&gt;因为32位计算机最大寻址范围就是4GB，即 $2^{32}Bytes=4294967296Bytes=4GBytes$。更大的内存空间在正常情况下无法被32位系统利用，加了也相当于没加。&lt;br&gt;
实际上还有硬件所需的一部分寻址空间，导致可用内存低于4GB。但一般情况下，设置的上限直接当成4GB就行了。&lt;/p&gt;
&lt;p&gt;点击关闭 - 完成，虚拟机就创建好了。&lt;/p&gt;
&lt;h2 id=&#34;安装操作系统&#34;&gt;安装操作系统
&lt;/h2&gt;&lt;p&gt;我们现在创建的虚拟机是完全空白的，里面什么都没有，而我们需要的正是把Ubuntu 12.04 LTS装进去。&lt;/p&gt;
&lt;p&gt;直接点左上方的开机。因为硬盘中没有东西可以启动，而我们又连接了ISO文件作为光盘（可以直接想象成一个光盘刻有Ubuntu镜像，放入虚拟机的光驱中。什么，你不会不知道光盘是啥吧？），就可以从光盘启动，具体原理应该后面会讲。&lt;/p&gt;
&lt;p&gt;在第一个页面，先在左边选择中文简体，再选择” 安装Ubuntu“。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/welcome.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;欢迎页面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;“安装中下载更新” 可选可不选，反正软件源已经停止服务了（见下文）。“安装这个第三方软件” 建议选择。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/ready_to_install.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;准备安装&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;选择 “清除整个磁盘并安装Ubuntu”，继续。不用害怕，清除的只是虚拟机的硬盘，不会对你的其他文件造成任何影响。然后直接点击 “现在安装”。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/installation_type.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;安装类型选择&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在安装的过程中，会有一些设置需要你完成。”你在什么地方 “对话框，你可以填入你的城市名，也可以直接选Shanghai，没有区别。” 键盘布局“直接下一步，反正不自带中文输入法，跳过。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/where.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;您在什么地方？&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;“您是谁” 中，填入姓名（可以随便填）、计算机名（会展示在终端中，不重要）、用户名（默认用户）和密码。&lt;strong&gt;密码一定要记住。&lt;/strong&gt; 是否自动登录看你心情，但个人倾向于不加密主目录。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/account.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;您是谁？&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Linux的用户管理机制&lt;/p&gt;
&lt;p&gt;Linux系统中，有一个root账户，拥有系统最高权限，类似于Windows的Administrator超级管理员账户。其他的用户没有root用户这样的权限，但在将他们加入sudoer列表之后，他们能够使用sudo命令暂时获得root用户的权限，执行一部分命令。这些用户也可以使用su命令切换到root用户。&lt;br&gt;
Ubuntu默认不开放root账户登录，官方更推荐在每个需要的命令前加上sudo。&lt;br&gt;
也或许你听说过Android系统获取root权限的说法，&lt;br&gt;
参见 &lt;a class=&#34;link&#34; href=&#34;https://zh.wikipedia.org/zh-cn/Sudo&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;维基百科&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;点击继续，Ubuntu会继续安装系统。当提示”安装完毕 “时，点击下方VMware的提示框中的” 我已完成安装 “，然后点击” 现在重启“。&lt;/p&gt;
&lt;p&gt;确认右下角光盘图标旁没有绿点，然后按下回车。如果重启后提示 “remove installation media and press enter” 等文字，右键右下角光盘图标，点击断开，然后在虚拟机中回车。&lt;/p&gt;
&lt;p&gt;请注意：如果你的鼠标在虚拟机窗口内，但却是Windows小手样式，说明你的输入没有被发送到虚拟机中。只有在窗口中点一下之后，你按Enter才会被Ubuntu捕捉到。可以使用Ctrl+Alt来切换输入发送到虚拟机中或是物理机中。&lt;/p&gt;
&lt;p&gt;之后系统就会开始自动登录。输入密码登录后大概是这个样子。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/startup.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;首次登陆后界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;根据 &lt;a class=&#34;link&#34; href=&#34;https://ubuntu.com/about/release-cycle&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ubuntu 的发布周期&lt;/a&gt;，显然这个版本是已经不受支持的。但如果你想和老师的步调尽量保持一致，同时对自己解决不同版本之间问题的能力完全没有信心，不要升级14.04。&lt;/p&gt;
&lt;h2 id=&#34;安装软件&#34;&gt;安装软件
&lt;/h2&gt;&lt;p&gt;到现在，系统已经装好了，但我强烈建议做一下以下的操作。&lt;/p&gt;
&lt;p&gt;以下要输入的内容较多，由于虚拟机和物理机默认不共享剪贴板，建议先在虚拟机内部的Firefox中打开本网页，然后复制所需的部分。&lt;/p&gt;
&lt;h3 id=&#34;安装vmware-tools&#34;&gt;安装VMware Tools
&lt;/h3&gt;&lt;p&gt;这个东西可以显著增强虚拟机的流畅度。在比较旧的Ubuntu中，我们需要手动安装。&lt;/p&gt;
&lt;p&gt;如果VMware提示安装Tools，点击安装。如果没有弹出，也可以使用顶部” 虚拟机 - 安装VMware Tools“选项来启动这个过程。&lt;/p&gt;
&lt;p&gt;正常情况下应该会弹出一个文件管理器窗口，没有的话也可以点击左边Dock栏的的DVD图标打开。复制里面的tar.gz文件，点击窗口左侧的 “主文件夹”，在这里粘贴。&lt;/p&gt;
&lt;p&gt;Linux的文件系统&lt;/p&gt;
&lt;p&gt;Linux与Windows不同，并不靠盘符区分硬盘分区，而是将所有东西放到一个主目录中。默认只有系统所在的分区会包含在其中，其他分区依靠一种称为 “挂载”（mounting）的机制。&lt;br&gt;
在这之前需要说明，在Linux中遵循 “万物皆文件” 的原则，其他的分区、传感器接收的数据、键盘输入，甚至随机熵等都是以文件形式表示的，这个我也不太理解，知道就行。&lt;br&gt;
所谓挂载，就是将主目录中的一个路径指定为访问另一个分区的根目录。如果你是Windows用户，可以想象一下电脑只留一个C盘，D盘本来是不会显示的，但你指定了一个目录如C:\DiskD\ 来指向原来的D:\，对D盘的读写则必须通过上面的路径来达到。&lt;br&gt;
值得一提的是，现在已经有自动挂载机制了，所以其他分区和U盘之类的设备都会自动挂载到系统上，大部分时候不需要自行配置。&lt;br&gt;
一个路径以 / 开头，指的是绝对路径，从根目录开始算起；若没有 /，或是./，则是相对路径，从当前目录开始算起。&lt;br&gt;
root用户的用户目录是 / root/，而其他用户的目录是 / usr / 用户名 /。上文的 “主文件夹” 就是 / usr / 用户名 / home/。因为虚拟光驱中的文件无法写入，所以需要使用这种方式。&lt;/p&gt;
&lt;p&gt;在桌面按下Ctrl+Alt+T打开终端，依次（指上一个命令执行完毕后，再输下一个）输入以下命令（井号开头的部分都是注释，无需输入；文件名可能有差异，请留意）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;tar -zxvf VMwareTools-10.3.23-16594550.tar.gz # 解压 VMware Tools 工具
cd vmware-tools-distrib/ # 进入解压后的文件夹
sudo ./vmware-install.pl # 调用 root 权限（sudo）执行安装脚本。在 Linux 中，可执行文件的扩展名并没有严格限制&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tar -zxvf VMwareTools-10.3.23-16594550.tar.gz &lt;span class=&#34;c1&#34;&gt;# 解压 VMware Tools 工具&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; vmware-tools-distrib/ &lt;span class=&#34;c1&#34;&gt;# 进入解压后的文件夹&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo ./vmware-install.pl &lt;span class=&#34;c1&#34;&gt;# 调用 root 权限（sudo）执行安装脚本。在 Linux 中，可执行文件的扩展名并没有严格限制&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Shell和Terminal&lt;/p&gt;
&lt;p&gt;详见 &lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/weixin_38214171/article/details/90050340&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blog.csdn.net/weixin_38214171/article/details/90050340&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;然后输入你的用户密码（字符不可见），回车，就可以开始安装了。遇到任何提示都可以直接回车，保持默认选项不变。&lt;/p&gt;
&lt;h3 id=&#34;更换软件源并升级软件包&#34;&gt;更换软件源并升级软件包
&lt;/h3&gt;&lt;p&gt;为了安装软件和安全更新，需要换源。&lt;/p&gt;
&lt;p&gt;APT和软件源&lt;/p&gt;
&lt;p&gt;有一种程序叫做 “包管理器”。顾名思义，这类程序的作用就是管理软件。在Windows上有winget，在macOS上有Homebrew，而对于Debian和基于此的Ubuntu，默认的包管理器是apt。&lt;br&gt;
apt在更新列表（update）、升级应用（upgrade）、安装应用（install）的时候，会访问软件源，并从其中获取相应的资源。软件源的列表存储于 / etc/apt/sources.list。&lt;br&gt;
上面已经说过，Ubuntu 12.04已经不受支持，所以官方默认软件源已经不再提供服务，但Ubuntu有old-releases软件源（参见 &lt;a class=&#34;link&#34; href=&#34;https://help.ubuntu.com/community/EOLUpgrades&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方文档&lt;/a&gt;）。&lt;br&gt;
在新版本中，也推荐进行换源操作，以加速访问，比较著名的有 &lt;a class=&#34;link&#34; href=&#34;https://mirrors.tuna.tsinghua.edu.cn/help/ubuntu/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;清华源&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://mirrors.ustc.edu.cn/help/ubuntu.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;中科大&lt;/a&gt; 源（请勿使用Ubuntu 12.04的清华源，可能有些问题）。&lt;/p&gt;
&lt;p&gt;输入以下命令。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak # 备份原软件源列表
sudo gedit /etc/apt/sources.list&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak &lt;span class=&#34;c1&#34;&gt;# 备份原软件源列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo gedit /etc/apt/sources.list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;在弹出的窗口中，将文件内容全部删除，替换为：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ precise-proposed main restricted universe multiverse
deb http://old-releases.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ precise main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ precise-proposed main restricted universe multiverse
deb-src http://old-releases.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise-proposed main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb http://old-releases.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ precise main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ precise-security main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ precise-updates main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ precise-proposed main restricted universe multiverse
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;deb-src http://old-releases.ubuntu.com/ubuntu/ precise-backports main restricted universe multiverse&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这是 &lt;strong&gt;Ubuntu 12.04的&lt;/strong&gt; 软件源archive。完成后，使用Ctrl+S保存，然后关闭。对于不同的Ubuntu版本，请使用不同的软件源；一个比较简单的判断方法是查看版本代号，如12.04是Precise，14.04是Trusty，20.04是Focal，22.04是Jammy，如果不含你的版本对应代号，一定不能直接使用。&lt;/p&gt;
&lt;p&gt;虽然这是一个停止支持的Ubuntu版本，但还是建议将软件包更新到最新版本。&lt;/p&gt;
&lt;p&gt;为加速访问，如果已有HTTP代理服务器，可以先 &lt;a class=&#34;link&#34; href=&#34;https://www.cnblogs.com/dou-fu-gan/p/14725899.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;参照这里&lt;/a&gt; 设置代理，具体请自行研究。&lt;/p&gt;
&lt;p&gt;在终端中依次输入&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;sudo apt-get update
sudo apt-get upgrade&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get update
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get upgrade&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果第一步报错，请检查sources.list是否输入正确。如果提示 “您希望继续执行吗”，输入y并回车。如果提示” 有几个包无法下载“，则重新执行上述第一条命令。&lt;/p&gt;
&lt;h3 id=&#34;安装中文输入法&#34;&gt;安装中文输入法
&lt;/h3&gt;&lt;p&gt;如你所见我们的Ubuntu是打不了中文的。而桌面等文件夹默认就是用中文命名的，现在连个桌面都cd不进去，所以当然要安装中文输入法。&lt;/p&gt;
&lt;p&gt;在终端执行以下命令以安装fcitx：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;sudo apt-get install &amp;#34;fcitx&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get install &lt;span class=&#34;s2&#34;&gt;&amp;#34;fcitx&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后点击顶部状态栏右边的键盘图标，选择” 汉语 - Pinyin“，就可以切换中文输入法了。可以发现，右上角的键盘已经变成了 “拼”。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vmware-ubuntu-12.04/chinese_ime.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;中文输入法效果&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;还是没搞懂这里有成品&#34;&gt;还是没搞懂？这里有成品
&lt;/h2&gt;&lt;p&gt;如果你实在是不会安装，可以使用我按照上面步骤预先安装好的虚拟机文件，在VMware Workstation Pro 16.2.2上实测可用，链接如下，用户名和密码均为cyp0633。但我仍然建议先尝试自行安装，这对你的学习也有益，也给我服务器省点流量。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://drive.cyp0633.icu/s/d4H0&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://drive.cyp0633.icu/s/d4H0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;虚拟机本体使用分卷压缩，包含3个文件共2.01GB，请全部下载解压，打开其中的vmx文件即可使用，强烈建议使用SHA-256做checksum。&lt;/p&gt;
&lt;h2 id=&#34;附录一些建议--提醒&#34;&gt;附录：一些建议 / 提醒
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;请尽量适应终端命令行操作为主，GUI界面为辅的方式，在Linux上这样效率非常高。&lt;/li&gt;
&lt;li&gt;如果你有任何问题，请Google/Bing。若能翻译成英语再搜索，则能搜索到Stack Overflow等网站的大佬的解答。&lt;/li&gt;
&lt;li&gt;Linux的软件包管理机制和文件管理机制，与Windows有非常大不同，而与macOS比较相似。&lt;/li&gt;
&lt;li&gt;虚拟机的 “快照” 功能十分有用，它类似于Git的label机制，可以在发现问题时快速回到之前保存过的状态，非常适合试病毒。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/x_i_y_u_e/article/details/49047273&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://blog.csdn.net/x_i_y_u_e/article/details/49047273&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.jianshu.com/p/33e37b78e03f&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.jianshu.com/p/33e37b78e03f&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>使用 Maddy&#43;RainLoop 搭建自己的邮箱</title>
        <link>https://cyp0633.com/post/self-hosting-mail-maddy-rainloop/</link>
        <pubDate>Fri, 21 Jan 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/self-hosting-mail-maddy-rainloop/</guid>
        <description>&lt;p&gt;一直想用自己的域名搭建一个的邮箱，但传统的Dovecot+Postfix方案十分复杂，封装起来的docker-mailserver虽整洁不少，但仍然存在占用资源很高的问题。&lt;/p&gt;
&lt;p&gt;想起Golang效率挺高的，也已经有了不错的生态，于是找到了Maddy，一个使用Golang编写的一体化邮件服务器，占用较少，也免去了各种模块相互配合的。它充当了MTA（中转服务器）和MDA（投递服务器）的角色。&lt;/p&gt;
&lt;p&gt;而Rainloop则是一个PHP写成的webmail，可以作为一个类似于Gmail的网页端。&lt;/p&gt;
&lt;p&gt;一般的VPS都可以搭建邮件服务器，不过某些服务商会屏蔽必要的25端口，可能需要发工单解决，不过上网搜一下一般就能知道。&lt;/p&gt;
&lt;p&gt;本文以Nginx 1.20.2、PHP 8.1.1、Ubuntu 18.04 LTS为例&lt;/p&gt;
&lt;h2 id=&#34;邮件服务器maddy&#34;&gt;邮件服务器：Maddy
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/%22Github%22&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/foxcpp/maddy&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;foxcpp/maddy&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;下载与安装&#34;&gt;下载与安装
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://maddy.email/tutorials/setting-up/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Maddy 的文档&lt;/a&gt; 说得其实挺明白的，但如果你不想看英语，也可以跟我走。这里使用预编译的二进制文件来搭建。&lt;/p&gt;
&lt;p&gt;首先要从 &lt;a class=&#34;link&#34; href=&#34;https://github.com/foxcpp/maddy/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Releases&lt;/a&gt; 下载最新的二进制文件到服务器中，文件名为maddy-x.x.x-x86_64-linux-musl.tar.zst。&lt;/p&gt;
&lt;p&gt;解压zst文件需要zstd依赖（Debian系可直接用apt安装），安装后使用&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;tar --use-compress-program=unzstd -xvf archive.tar.zst&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tar --use-compress-program&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;unzstd -xvf archive.tar.zst&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;来指定zstd程序解压这个文件。然后将文件夹内的maddy和maddycli复制到 / usr/local/bin目录下。&lt;/p&gt;
&lt;p&gt;除此之外，Maddy无法以root用户运行，所以你还需要新建一个用户：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;sudo useradd -mrU -s /sbin/nologin -d /var/lib/maddy -c &amp;#34;maddy mail server&amp;#34; maddy&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo useradd -mrU -s /sbin/nologin -d /var/lib/maddy -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;maddy mail server&amp;#34;&lt;/span&gt; maddy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;预编译二进制文件的压缩包内还带有systemd服务，可以直接拷贝到系统文件夹内使用：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;sudo cp ./systemd/*.service /etc/systemd/system
sudo systemctl reload&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo cp ./systemd/*.service /etc/systemd/system
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo systemctl reload&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;将压缩包内附带的 &lt;code&gt;maddy.conf&lt;/code&gt; 复制到etc目录下，然后用你喜欢的文本编辑器打开。暂时只需要编辑Base variables部分，记得要将上面的内容都换成你对应的。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;$(hostname) = mx1.example.org # 外界通过这个域名找到你的邮件服务器。
$(primary_domain) = example.org # 你的邮箱 @后面的域名，比如 test@example.org，而不一定是 test@mx1.example.org
$(local_domains) = $(primary_domain) # @后面可以添加的其他域名，比如 test@one.example.org。你需要在几个域名中选一个主要的，将其填入 primary domain。

tls file /etc/maddy/certs/$(hostname)/fullchain.pem /etc/maddy/certs/$(hostname)/privkey.pem # TLS 证书文件。&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;hostname&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; mx1.example.org &lt;span class=&#34;c1&#34;&gt;# 外界通过这个域名找到你的邮件服务器。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;primary_domain&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; example.org &lt;span class=&#34;c1&#34;&gt;# 你的邮箱 @后面的域名，比如 test@example.org，而不一定是 test@mx1.example.org&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;local_domains&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;primary_domain&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# @后面可以添加的其他域名，比如 test@one.example.org。你需要在几个域名中选一个主要的，将其填入 primary domain。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tls file /etc/maddy/certs/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;hostname&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/fullchain.pem /etc/maddy/certs/&lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;hostname&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;/privkey.pem &lt;span class=&#34;c1&#34;&gt;# TLS 证书文件。&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;对于证书文件，如果你使用Certbot获取hostname的TLS证书，你可以直接进行一个软连接，使得Maddy可以识别，而且要确保其有权限读取：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;ln -s /etc/letsencrypt/live /etc/maddy/certs
sudo setfacl -R -m u:maddy:rX /etc/letsencrypt/{live,archive}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;ln -s /etc/letsencrypt/live /etc/maddy/certs
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo setfacl -R -m u:maddy:rX /etc/letsencrypt/&lt;span class=&#34;o&#34;&gt;{&lt;/span&gt;live,archive&lt;span class=&#34;o&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果由其他方法获取证书，可以将文件拷贝至 / etc/maddy/certs并用相似的命令赋予maddy用户读取权限。&lt;/p&gt;
&lt;p&gt;现在我们可以将其启动了：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;systemctl start maddy&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start maddy&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h3 id=&#34;配置dns&#34;&gt;配置DNS
&lt;/h3&gt;&lt;p&gt;首先是各个domain的A/AAAA record，即上面提到example.org和one.example.org的指向。这个没必要指向你的邮件服务器IP，也就是说你可以拿这些域名指向其他服务器建个站什么的，但如果没有另外的用处，不设置应该也没什么问题。&lt;/p&gt;
&lt;p&gt;然后仍然是上面几个domain，这次是MX record。它由domain指向hostname。举个例子，将example.org的MX记录指向mx1.example.org，意思是任何发送到 @example.org的邮件服务都由mx1.example.org来处理。如果你有多个domain，那么需要逐个设置。&lt;/p&gt;
&lt;p&gt;之后设置hostname即邮件服务器的A/AAAA记录。它需要将类似于mx1.example.org的地址解析为IP地址。&lt;/p&gt;
&lt;p&gt;要设置MTA-STS（后面会讲），需要将mta-sts.example.org和mta-sts.one.example.org（即各个domain）的A/AAAA记录指向邮件服务器IP。&lt;/p&gt;
&lt;p&gt;还有一系列的TXT类型的解析如下。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SPF&lt;/strong&gt; 为domain和hostname（非必要）都添加txt解析，内容如下。用于表明MX解析的域名是可以发邮件的。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;v=spf1 mx ~all&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;v=spf1 mx ~all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;DMARC&lt;/strong&gt; 用于处理损坏的邮件。需要为所有 _dmarc.yourdomain（如 _dmarc.example.org和 _dmarc.one.example.org）添加。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;v=DMARC1; p=quarantine; ruf=mailto:postmaster@example.org&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;v=DMARC1; p=quarantine; ruf=mailto:postmaster@example.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;MTA-STS标记&lt;/strong&gt; 加上之后，失败的报告会被送到指定的邮箱（默认postmaster）。为 _mta-sts.example.org添加（其他domain不要漏下）&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-8&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-8&#34; style=&#34;display:none;&#34;&gt;v=STSv1; id=1&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;v=STSv1; id=1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后为 _smtp._tls.example.org添加&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-9&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-9&#34; style=&#34;display:none;&#34;&gt;v=TLSRPTv1;rua=mailto:postmaster@example.org&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;v=TLSRPTv1;rua=mailto:postmaster@example.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;DKIM Key&lt;/strong&gt; 在 / var/lib/maddy/dkim_keys/example.org_default.dns（文件名因人而异）找到该项TXT记录值，并将其给予default._domainkey.example.org的TXT解析。&lt;/p&gt;
&lt;h3 id=&#34;mta-sts保护&#34;&gt;MTA-STS保护
&lt;/h3&gt;&lt;p&gt;其实包括MTA-STS和DKIM等措施，对于发送邮件来说并不是必要的，但如果没有这几个措施，那么一些大电子邮件服务商（比如Gmail）会认为从你的服务器发出的是垃圾邮件。&lt;/p&gt;
&lt;p&gt;MTA-STS（&lt;a class=&#34;link&#34; href=&#34;https://datatracker.ietf.org/doc/html/rfc8461&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RFC 8461&lt;/a&gt;）是一个预防中间人攻击的防护措施。它的标记已经在上一步做好。然后，我们需要使用一个网页服务器来返回一串文本。&lt;/p&gt;
&lt;p&gt;官方文档推荐的方式是serve一个文本文档，内容如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;plain&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-10&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-10&#34; style=&#34;display:none;&#34;&gt;version: STSv1
mode: enforce
max_age: 604800
mx: mx1.example.org&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-plain&#34; data-lang=&#34;plain&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;version: STSv1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mode: enforce
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;max_age: 604800
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mx: mx1.example.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;当访问 &lt;a class=&#34;link&#34; href=&#34;https://mta-sts.example.org/.well-known/mta-sts.txt&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://mta-sts.example.org/.well-known/mta-sts.txt&lt;/a&gt; 的时候，就返回它。&lt;/p&gt;
&lt;p&gt;对于Nginx，也可以使用以下方式直接返回这串文字，在Nginx配置文件的HTTP块内加入一个server：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;nginx&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-11&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-11&#34; style=&#34;display:none;&#34;&gt;server {
    server_name mta-sts.example.org;
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_certificate /path/to/fullchain.pem; # 路径因人而异，下同
    ssl_certificate_key /path/to/privkey.pem;
    location = /.well-known/mta-sts.txt {
        default_type text/plain;
        return 200 &amp;#34;version: STSv1\r\nmode: enforce\r\nmx: mx1.example.org\r\nmax_age: 604800\r\n&amp;#34;;
    }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;server&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;server_name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;mta-sts.example.org&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;443&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[::]:443&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;ssl_protocols&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;TLSv1.1&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;TLSv1.2&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;TLSv1.3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;ssl_certificate&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/path/to/fullchain.pem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;c1&#34;&gt;# 路径因人而异，下同
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;kn&#34;&gt;ssl_certificate_key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/path/to/privkey.pem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/.well-known/mta-sts.txt&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;default_type&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;text/plain&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;200&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;version:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;STSv1\r\nmode:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;enforce\r\nmx:&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;mx1.example.org\r\nmax_age:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;604800&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;\r\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;当然，这之前需要确保你将mta-sts.example.org指向正确的IP，并申请其对应的TLS证书。&lt;/p&gt;
&lt;p&gt;如果你使用Nginx、Caddy或Litespeed等网页服务器，请自行研究。&lt;/p&gt;
&lt;p&gt;要验证是否添加成功，可以直接访问https://example.org/.well-known/mta-sts.txt，查看返回的内容。&lt;/p&gt;
&lt;p&gt;TLSA/DANE记录这里不再指引，因为我使用的阿里云DNS是不能添加DLSA记录的，有兴趣的可以自行看官方文档。&lt;/p&gt;
&lt;h3 id=&#34;添加账户&#34;&gt;添加账户
&lt;/h3&gt;&lt;p&gt;Maddy的账户体系是 “虚拟用户”，也就是说验证账户和IMAP邮箱是分离开来的。&lt;/p&gt;
&lt;p&gt;首先，要创建用户验证，使用命令：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-12&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-12&#34; style=&#34;display:none;&#34;&gt;maddyctl creds create example@example.org&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;maddyctl creds create example@example.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;输入账户密码，然后再创建它的邮箱：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-13&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-13&#34; style=&#34;display:none;&#34;&gt;maddyctl imap-acct create example@example.org&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;maddyctl imap-acct create example@example.org&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这样，一个传统意义上的邮件账户就创建完成了。&lt;/p&gt;
&lt;p&gt;如果需要更多帮助，可以使用&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-14&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-14&#34; style=&#34;display:none;&#34;&gt;maddyctl creds --help
maddyctl imap-acct --help&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;maddyctl creds --help
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;maddyctl imap-acct --help&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;命令来获取。&lt;/p&gt;
&lt;p&gt;到现在，你可以使用任何一个现代的邮件客户端，连接你刚刚创建的邮件服务器。IMAP协议即可，发送和接收可以全都选SSL。为安全起见，建议以后的邮件客户端全部启用SSL。&lt;/p&gt;
&lt;p&gt;发一封邮件，如果你上述的安全措施做得比较好，发送给Gmail等对安全比较严格的邮箱，应该能够作为重要邮件，起码不会被作为垃圾邮件。使用IMAP+SMTP+SSL，收件端口号为993，发件端口号为465。&lt;/p&gt;
&lt;h2 id=&#34;webmailrainloop&#34;&gt;Webmail：RainLoop
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/RainLoop/rainloop-webmail&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;RainLoop/rainloop-webmail&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;大部分看这篇文章的人都应该是搭着玩的个人用户吧。如果不是，那么请首先参阅RainLoop的 &lt;a class=&#34;link&#34; href=&#34;https://www.rainloop.net/purchase/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;不同版本比较页面&lt;/a&gt;，他们针对不同用户有不同的版本和Licence。这里直接选对无盈利的个人免费的Standard Edition，因其带有比较简便的更新功能。&lt;/p&gt;
&lt;h3 id=&#34;下载与安装-1&#34;&gt;下载与安装
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.rainloop.net/try-now/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;从这里&lt;/a&gt; 可以下载两种版本到服务器上。下载下来是ZIP格式，所以我们需要安装unzip解压（apt包管理器内有，不带apt的发行版请自行想办法）。&lt;/p&gt;
&lt;p&gt;然后输入以下命令，将RainLoop的文件拷贝至 / var/www/rainloop，并设置权限。你也可以使用其他自己喜欢的路径，别忘了修改后面的配置文件对应部分。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-15&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-15&#34; style=&#34;display:none;&#34;&gt;unzip rainloop-latest.zip -d /var/www/rainloop
cd /var/www/rainloop
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;unzip rainloop-latest.zip -d /var/www/rainloop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; /var/www/rainloop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;find . -type d -exec chmod &lt;span class=&#34;m&#34;&gt;755&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;find . -type f -exec chmod &lt;span class=&#34;m&#34;&gt;644&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;{}&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后编辑Nginx配置文件，加入server块：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;nginx&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-16&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-16&#34; style=&#34;display:none;&#34;&gt;server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name webmail.example.org;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    index index.html index.php;
    root /var/www/rainloop;
    client_max_body_size 2G;

    error_log /var/log/nginx/rainloop.error.log;
    access_log /var/log/nginx/rainloop.access.log;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ^~/data {
        deny all;
    }

    location ~ \.php$ {
        fastcgi_pass php-handler-https;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-nginx&#34; data-lang=&#34;nginx&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;server&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;443&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;listen&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;[::]:443&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;ssl&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;http2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;server_name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;webmail.example.org&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;ssl_certificate&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/path/to/fullchain.pem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;ssl_certificate_key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/path/to/privkey.pem&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;index&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;index.html&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;index.php&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;root&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/var/www/rainloop&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;client_max_body_size&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;2G&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;error_log&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/var/log/nginx/rainloop.error.log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;access_log&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/var/log/nginx/rainloop.access.log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;try_files&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$uri&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$uri/&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/index.php?&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$query_string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;^~/data&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;deny&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;all&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kn&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;~&lt;/span&gt; &lt;span class=&#34;sr&#34;&gt;\.php$&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;fastcgi_pass&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;php-handler-https&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;fastcgi_index&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;index.php&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;fastcgi_param&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;SCRIPT_FILENAME&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$document_root$fastcgi_script_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kn&#34;&gt;include&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;fastcgi_params&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;其中你必须更改的是 &lt;code&gt;server_name&lt;/code&gt;、&lt;code&gt;ssl_certificate&lt;/code&gt; 和 &lt;code&gt;ssl_certificate_key&lt;/code&gt;。你可以把页面直接放到邮件服务器上，也可以换个服务器或者域名，但如果你想直接用上文提到的mx1.example.org即hostname，那么可以做正向代理，但更推荐的做法是把RainLoop直接部署到邮件服务器上。其他root等项视情况更改。根据官方文档，data目录不能允许被外网访问从而直接获取配置文件，所以直接deny all。&lt;/p&gt;
&lt;p&gt;然后使用 &lt;code&gt;nginx -t&lt;/code&gt; 测试配置文件，如果没有问题，就 &lt;code&gt;systemctl restart nginx&lt;/code&gt; 重启nginx，然后访问webmail.example.org（例）试试吧。&lt;/p&gt;
&lt;p&gt;若仍提示no data folder write permission权限问题，大不了给对应目录文件直接777权限（问题不大、&lt;/p&gt;
&lt;h3 id=&#34;初始配置&#34;&gt;初始配置
&lt;/h3&gt;&lt;p&gt;访问webmail.example.org/?admin来进行初始配置。默认管理员用户名为admin，密码为12345。&lt;/p&gt;
&lt;p&gt;首先建议在 “安全” 选项卡中修改默认管理员密码。在 “域名“选项卡中，你可以添加你刚刚架设好的邮件domain，也可以添加其他商用邮箱域名。添加之后点击测试，可以测试一下邮件服务器在此设定下能否连通。正常来说，你不需要勾选” 使用短域名登录“。&lt;/p&gt;
&lt;p&gt;此外，” 白名单 “功能能够限制某域中能登陆到Webmail的账户列表，如设置example.com的白名单为test@example.com，那么除上述邮箱外，后缀为 @example.com的邮箱全部不能登录。&lt;/p&gt;
&lt;p&gt;这两项基础设置做完之后，你就可以重新打开webmail.example.org，输入你的邮箱和密码，登录Webmail。如果无法登录，请检查你刚刚的初始配置。如果能够成功进入邮箱，那就……enjoy it!&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.naut.ca/blog/2020/04/07/mta-sts-in-5-minutes/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://www.naut.ca/blog/2020/04/07/mta-sts-in-5-minutes/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://lala.im/6902.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://lala.im/6902.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>记为 Ubuntu 20.04 增加 IPv6 地址</title>
        <link>https://cyp0633.com/post/add-ipv6-on-ubuntu-22.04/</link>
        <pubDate>Wed, 19 Jan 2022 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/add-ipv6-on-ubuntu-22.04/</guid>
        <description>&lt;p&gt;本文以BuyVM装有Ubuntu 20.04.3的VPS为例，希望能够避免更多人踩坑甚至遭遇服务器失联。&lt;/p&gt;
&lt;p&gt;尤其对于并不是BuyVM的VPS用户来说，情况不一定相同，建议同时参照下面加粗的参考文献研究。&lt;/p&gt;
&lt;h2 id=&#34;分配ipv6地址&#34;&gt;分配IPv6地址
&lt;/h2&gt;&lt;p&gt;BuyVM的VPS本身不带IPv6，仅有一个IPv4。&lt;/p&gt;
&lt;p&gt;要分配一个IPv6地址，在Stallion管理界面 - Virtual Services-Networking-IPv6内点击Assign IPv6 Address。&lt;/p&gt;
&lt;p&gt;你可以随机选择一个，也可以在范围内指定一个IP地址。点击Add IPv6 Address，就可以了。&lt;/p&gt;
&lt;p&gt;暂时不要关闭Stallion，等待下一步操作。&lt;/p&gt;
&lt;h2 id=&#34;编辑netplan设置&#34;&gt;编辑Netplan设置
&lt;/h2&gt;&lt;p&gt;网络上搜到的教程大多是旧版Ubuntu所使用的方法，而Ubuntu 20.04.3已经开始使用Netplan。&lt;/p&gt;
&lt;p&gt;使用SSH连接到服务器。如果你担心因操作不当而失联，可以直接使用VNC连接，方法见下章。&lt;/p&gt;
&lt;p&gt;Netplan的默认配置文件处于 / etc/netplan中，里面应该有一个YAML文件，即其配置文件。&lt;/p&gt;
&lt;p&gt;使用你喜欢的代码编辑器（Vim，Nano，whatever）打开此文件，你将看到如下形式的配置文件。有些许差异可以忽略。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ethernets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;eth0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dhcp4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;将其改成如下内容，其中核心内容将在下面说明。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;yaml&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;network:
  version: 2
  ethernets:
    eth0:
      dhcp4: true
      dhcp6: true
      gateway4: x.x.x.x # IPv4 网关
      gateway6: xx::1 # IPv6 网关
      addresses: [x.x.x.x/24,&amp;#39;x:x::/Bitmask&amp;#39;] # 分别为 IPv4 地址、IPv6 地址、IPv6 Bitmask&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;network&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;m&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;ethernets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;eth0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dhcp4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;dhcp6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway4&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;x.x.x.x&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# IPv4 网关&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;gateway6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;xx::1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# IPv6 网关&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;addresses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;l&#34;&gt;x.x.x.x/24,&amp;#39;x:x::/Bitmask&amp;#39;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;c&#34;&gt;# 分别为 IPv4 地址、IPv6 地址、IPv6 Bitmask&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;从Stallion刚刚的页面中点击IPv4选项卡，然后在下方的IPv4 addresses中的Normal项找到设置图标。点击它，再点击Network Settings。&lt;/p&gt;
&lt;p&gt;这个IP Address就是你的IPv4地址，Gateway就是IPv4网关，分别将其替换入上面的修改内容。如果你的Netmask也是255.255.255.0，那么 / 24就不需要变动，它们的意义相同，只是一个Netmask和Bitmask的相互转换，前者是IPv4惯用表述，后者则是IPv6的表述。Netplan统一用后者。&lt;/p&gt;
&lt;p&gt;另外，对于某几个地点的Gateway，&lt;a class=&#34;link&#34; href=&#34;https://wiki.buyvm.net/doku.php/kvm#networking&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Frantech 官网&lt;/a&gt; 也有说明。&lt;/p&gt;
&lt;p&gt;同理，进入刚刚你分配的IPv6地址设置中，替换IP Address和Gateway为对应的值。Bitmask的值则替换为网页上Netmask/Bitmask的值，一般为48。&lt;/p&gt;
&lt;p&gt;保存配置文件，使用命令 &lt;code&gt;sudo netplan try&lt;/code&gt; 可以自动检查配置文件，如果看起来没有问题的话就可以按回车继续了。然后使用 &lt;code&gt;sudo netplan apply&lt;/code&gt; 来应用更改。&lt;/p&gt;
&lt;h2 id=&#34;检查网络连接&#34;&gt;检查网络连接
&lt;/h2&gt;&lt;p&gt;一小段时间之后，使用 &lt;code&gt;networkctl status eth0&lt;/code&gt; 命令查看eth0端口情况。除了查看Address信息有没有错误之外，最重要的是State。如果是绿色的routable(configured)，那么一切正常。否则，degraded表示可能没有连接公网，而若下方log中提示No Route to Host则可能代表Gateway设置错误。&lt;/p&gt;
&lt;p&gt;这之后，可以使用 &lt;code&gt;ping6 google.com&lt;/code&gt; 测试一下IPv6下的网络连接。也可以用其他设备Ping你刚刚分配的IPv6地址。如果都不会提示Network Unreachable，那么就万事大吉了。&lt;/p&gt;
&lt;h2 id=&#34;如果你的服务器已经因此失联&#34;&gt;如果你的服务器已经因此失联
&lt;/h2&gt;&lt;p&gt;你永远可以相信VNC。在Stallion右上方的Console内点击Direct VNC Connection，然后在你的VNC客户端（官方推荐的TightVNC就不错）Viewer上输入网页中弹出的用户名和密码，就可以连接到服务器了。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://hostloc.com/thread-745390-1-1.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://hostloc.com/thread-745390-1-1.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://oldtang.com/2314.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://oldtang.com/2314.html&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://developer.aliyun.com/article/744737&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://developer.aliyun.com/article/744737&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://askubuntu.com/questions/328265/trying-to-enable-ipv6-results-in-a-no-route-to-host-error&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://askubuntu.com/questions/328265/trying-to-enable-ipv6-results-in-a-no-route-to-host-error&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/46544606&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;strong&gt;https://zhuanlan.zhihu.com/p/46544606&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>记一次为 Vultr 的 WordPress 主机配置 IPv6 &#43; SSL 访问</title>
        <link>https://cyp0633.com/post/configure-ipv6-for-vultr-wordpress-site/</link>
        <pubDate>Sun, 14 Nov 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/configure-ipv6-for-vultr-wordpress-site/</guid>
        <description>&lt;p&gt;说来也怪，这个其实是我搞梯子的时候研究Nginx的副产物。&lt;/p&gt;
&lt;p&gt;先提一下VPS的当前环境：从Vultr直接部署的WordPress主机，Ubuntu 18.04.6 LTS，Nginx 1.20.1。已经使用了Let&amp;rsquo;s Encrypt的SSL服务获取了证书。其他的都没啥关系，就不提了。&lt;/p&gt;
&lt;p&gt;如果你还没有获取到SSL证书，你可以使用 &lt;a class=&#34;link&#34; href=&#34;https://certbot.eff.org/en&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Certbot&lt;/a&gt; 获取一个免费的，虽是英文教程但浅显易懂，中文教程也好找。&lt;/p&gt;
&lt;h2 id=&#34;编译替换nginx&#34;&gt;编译替换Nginx
&lt;/h2&gt;&lt;p&gt;我发现附带的Nginx是没有IPv6支持的，可以使用这个命令来验证：&lt;code&gt;nginx -V&lt;/code&gt;。输出大概是这样：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;nginx version: nginx/1.20.1
built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
built with OpenSSL 1.1.1  11 Sep 2018
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt=&amp;#39;-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.20.1/debian/debuild-base/nginx-1.20.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC&amp;#39; --with-ld-opt=&amp;#39;-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie&amp;#39;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;nginx version: nginx/1.20.1
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;built with OpenSSL 1.1.1  11 Sep 2018
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;TLS SNI support enabled
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt=&amp;#39;-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.20.1/debian/debuild-base/nginx-1.20.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC&amp;#39; --with-ld-opt=&amp;#39;-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie&amp;#39;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;不过截至写这篇文章的时候，Vultr已经可以部署基于Ubuntu 20.04的WordPress主机了。如果你运行上面的命令，发现带有 “&amp;ndash;with-ipv6” 的话，那么就可以跳过这一步了。如果没有，就先把configure arguments后面的内容复制下来备用。&lt;/p&gt;
&lt;p&gt;SSH连接服务器，使用 &lt;code&gt;wget https://nginx.org/download/nginx-1.20.1.tar.gz&lt;/code&gt; 下载Nginx 1.20.1版本（或者核对上面命令输出中的nginx version，一定要确认版本一致），使用 &lt;code&gt;tar -zxvf nginx-1.20.1.tar.gz&lt;/code&gt; 命令解压。&lt;/p&gt;
&lt;p&gt;安装一下依赖库，命令如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;sudo apt upgrade
sudo apt install build-essential libtool libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt upgrade
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install build-essential libtool libpcre3 libpcre3-dev zlib1g-dev openssl libssl-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;进入刚刚解压的文件目录，并执行&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;./configure --what-you-have-copied-just-now --with-ipv6&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./configure --what-you-have-copied-just-now --with-ipv6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;将其中 &lt;code&gt;--what-you-have-copied-just-now&lt;/code&gt; 替换成你刚刚复制的内容。不过，不加 &amp;ndash;with-ipv6其实也可以，新编译的默认是带有IPv6支持的。&lt;/p&gt;
&lt;p&gt;如果没有任何报错的话，再执行 &lt;code&gt;make&lt;/code&gt; 来编译（不要make install）。否则可以将报错内容Google一下，多半是少了什么库，对照着装就是了。&lt;/p&gt;
&lt;p&gt;Vultr的WordPress主机，Nginx可执行文件在 / usr/sbin，配置文件在 / etc/nginx/conf.d。做一下备份，然后将新编译好的nginx可执行文件替换进原文件，然后重启服务即可加入IPv6模块：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;mv /usr/sbin/nginx /usr/sbin/nginx.bak
mv objs/nginx /usr/sbin/
systemctl restart nginx.service&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mv /usr/sbin/nginx /usr/sbin/nginx.bak
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mv objs/nginx /usr/sbin/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl restart nginx.service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2 id=&#34;设置dns解析&#34;&gt;设置DNS解析
&lt;/h2&gt;&lt;p&gt;我使用的是阿里云DNS，直接将原域名AAAA解析至服务器的IPv6地址即可。这个应该不难。&lt;/p&gt;
&lt;p&gt;等一小会后，执行 &lt;code&gt;nslookup your.domain&lt;/code&gt;，解析到的应该是IPv6和v4两个地址。&lt;/p&gt;
&lt;h2 id=&#34;编辑nginx配置文件&#34;&gt;编辑Nginx配置文件
&lt;/h2&gt;&lt;p&gt;先备份，再用你喜欢的方法编辑 /etc/nginx/conf.d/wordpress_https.conf。如果内有两个server开头的大括号，有一个带有”managed by Certbot“标记，就注释掉或者删掉另外一个大括号连同里面的内容。我之前就是没有注意到实际的配置文件，导致IPv6访问死活没有SSL。&lt;/p&gt;
&lt;p&gt;找到 &lt;code&gt;listen 443 ssl;&lt;/code&gt;，然后在后面加入一行&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;listen [::]:443 ssl ipv6only=on;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;listen [::]:443 ssl ipv6only=on;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;即可让Nginx监听IPv6的443端口内容。如果你还想保留IPv6的HTTP访问（无SSL），再编辑 /etc/nginx/conf.d/wordpress_http.conf，在 &lt;code&gt;listen 80;&lt;/code&gt; 后面加入一行 &lt;code&gt;listen [::]:80;&lt;/code&gt;。&lt;/p&gt;
&lt;h2 id=&#34;检验ipv6访问及证书&#34;&gt;检验IPv6访问及证书
&lt;/h2&gt;&lt;p&gt;在 &lt;a class=&#34;link&#34; href=&#34;https://www.ssllabs.com/ssltest&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SSL Server Test (Powered by Qualys SSL Labs)&lt;/a&gt; 中输入你的域名，可以分别检验IPv6和v4下的SSL访问情况。你也可以自行打开网页检验。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.cnblogs.com/dreamofprovence/p/11789115.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Ubuntu 编译安装 nginx 以及配置自动启动 - 浮梦云烟 - 博客园 (cnblogs.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/jian_xi/article/details/79146921&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Linux 中查找 nginx 安装目录和 nginx.conf 配置文件目录 _纸上得来终觉浅，绝知此事要躬行 - CSDN 博客 _查找 nginx 目录&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>使用任务计划程序，根据网络环境自动开关代理软件</title>
        <link>https://cyp0633.com/post/auto-proxy-switch/</link>
        <pubDate>Wed, 03 Nov 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/auto-proxy-switch/</guid>
        <description>&lt;p&gt;住处的路由器经过一番折腾，自带访问国际互联网的环境，而其他地方的网络当然不会有这个东西了，这就需要在电脑上启动代理。每次搬电脑都要开关代理很麻烦，于是心生一计，使用Windows自带的十分完善的任务计划功能，来实现根据网络环境的代理软件自动开关功能。理论上这同时适用于Clash、ShadowsocksR等代理软件。&lt;/p&gt;
&lt;p&gt;在Windows 11 build 22000.282测试通过，理论上近几个大版本的Windows 10也同样适用。&lt;/p&gt;
&lt;h2 id=&#34;自动打开代理软件&#34;&gt;自动打开代理软件
&lt;/h2&gt;&lt;p&gt;这一部分讲述了在连接到某一特定SSID的WiFi网络时如何启动代理，以Shadowsocks为例。&lt;/p&gt;
&lt;p&gt;使用Windows搜索 “计划任务” 或者 “taskschd” 可以找到任务计划程序。&lt;/p&gt;
&lt;p&gt;点击右侧 “创建任务”，随便起个名字。&lt;/p&gt;
&lt;p&gt;切换到 “触发器” 选项卡，新建 “发生事件时” 触发器，“开始任务”选择 “发生事件时”，“日志” 选择 “Microsoft-Windows-NetworkProfile/Operational”，“源” 选择 “NetworkProfile”，“事件ID” 填写“10000”，其他不变，如图。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;auto-proxy-switch/trigger-settings.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;触发器设定&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;切换到 “操作” 选项卡，新建操作，在 “程序或脚本” 栏里浏览并选择你的Shadowsocks主程序，其他不变，点击确定。&lt;/p&gt;
&lt;p&gt;再切换到 “条件” 选项卡，选中 “只有在以下网络连接可用时才启动”，选择你希望打开Shadowsocks的网络环境。某些时候，网络SSID并不等于环境名称，这时最好查看“找到真正的网络名称” 部分以确保选择正确。这样相当于监听每一次网络环境改变事件，再检查当前网络环境，如果符合条件则启动。同时还需要关闭”只有在计算机使用交流电源时才启动此任务“，毕竟能拿着电脑到处跑的人应该会经常用电池吧。&lt;/p&gt;
&lt;p&gt;点击确定，即可完成设置。&lt;/p&gt;
&lt;h3 id=&#34;找到真正的网络名称&#34;&gt;找到真正的网络名称
&lt;/h3&gt;&lt;p&gt;有些时候，你可能会遇到和我一样的情况：明明想找一个名为xxx的WiFi，但在 “只有在以下网络连接可用时才启动” 下拉框中却发现了形如 “xxx 1”“xxx 2” 之类的网络。如果没有这种情况，那很好，你不用看这一小节了；否则，需要打开 “适配器选项” 窗口来确定真正的网络名称。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;auto-proxy-switch/adapter-options.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;适配器选项&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这里吐槽一下小米互传：就不能固定一个SSID吗？&lt;/p&gt;
&lt;p&gt;首先要连接目标网络，然后根据操作系统不同，有不同的步骤。&lt;/p&gt;
&lt;p&gt;对于Windows 10，在任务栏网络图标右键，选择 “打开网络和Internet设置”，然后点击 “更改适配器选项”；而对Windows 11，要打开设置 - 网络 &amp;amp; Internet - 高级网络设置 - 更多网络适配器选项。会弹出如下图的窗口。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;auto-proxy-switch/advanced_adapter_options.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;更多适配器选项&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这里再骂一次微软，Windows 10适配器选项页面的高分屏优化都比11好，起码字体没毛边。&lt;/p&gt;
&lt;p&gt;这里根据你的情况寻找你的网络名称，比如我的是 “PDCN_5G 7”。&lt;/p&gt;
&lt;h2 id=&#34;自动关闭代理软件&#34;&gt;自动关闭代理软件
&lt;/h2&gt;&lt;p&gt;仍然以Shadowsocks为例。这个实现起来相对麻烦些，因为任务计划没有设定关闭程序的操作。好在我们有PowerShell，所以我们可以使用PoweShell脚本来结束进程。&lt;/p&gt;
&lt;p&gt;新建一个文本文档，将扩展名改为. ps1，文件名任取。然后，在里面粘贴以下内容（假设你的Shadowsocks设定的是PAC模式）：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;Write-Output &amp;#34;Stopping Shadowsocks&amp;#34;
Get-Process | Where-Object {$_.ProcessName.Contains(&amp;#34;Shadowsocks&amp;#34;)} | Stop-Process
Write-Output &amp;#34;Trying to delete proxy registry&amp;#34;
Remove-ItemProperty -Path &amp;#39;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#39; -Name &amp;#34;AutoConfigURL&amp;#34;&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Write-Output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Stopping Shadowsocks&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Get-Process&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Where-Object&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ProcessName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;Contains&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Shadowsocks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Stop-Process&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Write-Output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Trying to delete proxy registry&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Remove-ItemProperty&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#39;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Name&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;AutoConfigURL&amp;#34;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后保存。&lt;/p&gt;
&lt;p&gt;按上面的步骤创建一个新任务。“触发器” 与上面相同。&lt;/p&gt;
&lt;p&gt;在 “操作”-“程序或脚本” 的“添加参数”栏填入刚刚新建的PowerShell脚本路径，“程序或脚本”填入“pwsh.exe”（如果你安装了新版PowerShell Core）或“powershell.exe”（通用，但是是老版本），其他不变，确定。如下图：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;auto-proxy-switch/powershell.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;编辑操作&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;编辑执行脚本操作&lt;/p&gt;
&lt;p&gt;“条件”-“只有在以下网络连接可用时” 改为你希望自动关闭Shadowsocks的网络环境。&lt;/p&gt;
&lt;p&gt;点击确定，即可完成设置。&lt;strong&gt;不想了解细节的读者，不需要读本节中下面的部分。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我们都知道，要关闭Shadowsocks，当然要结束Shadowsocks.exe。它运行的时候，还会同时启动Privoxy透明代理，但结束主程序的时候它也会一起关闭，所以没有必要考虑这个。&lt;/p&gt;
&lt;p&gt;如果你使用的是PAC代理模式而不是全局代理，有时系统设置 - 网络 &amp;amp; Internet - 代理 - 使用设置脚本的开关并不会关闭，部分影响网络浏览。这个开关由注册表键值HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\AutoConfigURL所管理，如果存在则代表这个开关打开，并将PAC代理指向它的值，键值字符串代表设置的代理服务器地址。那么，我们增加一条命令将这个键删掉，就可以保证彻底关闭了。&lt;/p&gt;
&lt;h2 id=&#34;进阶自动检测网络环境开关代理&#34;&gt;进阶：自动检测网络环境，开关代理
&lt;/h2&gt;&lt;p&gt;这部分以v2rayN为例。如果你经常在多个网络环境之间穿梭，每个网络条件不同（甚至同一个网络路由器端的梯子都有可能挂掉），上面的那个办法就不是那么好用了。既然我们写了PowerShell脚本，不妨一步到位，直接检测网络环境。&lt;/p&gt;
&lt;p&gt;首先你需要新建一个在网络环境改变的时候就调用的任务计划，而不需要特定网络连接条件，可以参照本文的 “自动打开代理” 部分。&lt;/p&gt;
&lt;p&gt;然后新建一个PowerShell脚本，少废话，上代码。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;Set-ItemProperty -Path &amp;#34;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#34; -Name ProxyEnable -Value 0 #首先禁用系统代理，防止对检测造成影响
$url = &amp;#34;http://clients3.google.com/generate_204&amp;#34;
$req = [system.Net.WebRequest]::Create($url)
$proxyActive = Get-Process v2rayN -ErrorAction SilentlyContinue #检测 v2rayN 是否运行，后面那个 param 是在它没有运行的情况下继续执行脚本
try {
    $res = $req.GetResponse() #获取 HTTP 状态码
} 
catch [System.Net.WebException] {
    $res = $_.Exception.Response
}
if ($res.StatusCode -eq&amp;#34;NoContent&amp;#34;) {
    #能够直连国际互联网
    Write-Output &amp;#34;Google Is Connected, Stopping Proxy&amp;#34;
    Get-Process | Where-Object {$_.ProcessName.Contains(&amp;#34;v2ray&amp;#34;)} | Stop-Process
}
else {
    #不能直连国际互联网
    if ($null -eq $proxyActive) {
        # 代理未运行，打开代理
        Write-Output &amp;#34;Cannot connect to Google, Starting Proxy&amp;#34;
        &amp;amp;&amp;#34;Your\Path\To\v2rayN.exe&amp;#34;
    }
    else {
        # 代理软件已运行，启用系统代理即可
        Write-Output &amp;#34;Re-enabling Proxy&amp;#34;
        Set-ItemProperty -Path &amp;#34;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#34; -Name ProxyEnable -Value 1
    }
}    &lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;Set-ItemProperty&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Name&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProxyEnable&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Value&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#首先禁用系统代理，防止对检测造成影响&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;http://clients3.google.com/generate_204&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$req&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;system.Net.WebRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]::&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Create&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$proxyActive&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Get-Process&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;v2rayN&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-ErrorAction&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SilentlyContinue&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#检测 v2rayN 是否运行，后面那个 param 是在它没有运行的情况下继续执行脚本&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;try&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;$res&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$req&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;GetResponse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;c&#34;&gt;#获取 HTTP 状态码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;catch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;System.Net.WebException&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;$res&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;Response&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$res&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;StatusCode&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-eq&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;NoContent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;#能够直连国际互联网&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;Write-Output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Google Is Connected, Stopping Proxy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nb&#34;&gt;Get-Process&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Where-Object&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$_&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;ProcessName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;py&#34;&gt;Contains&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;v2ray&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)}&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;Stop-Process&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c&#34;&gt;#不能直连国际互联网&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;vm&#34;&gt;$null&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-eq&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$proxyActive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c&#34;&gt;# 代理未运行，打开代理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;Write-Output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Cannot connect to Google, Starting Proxy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Your\Path\To\v2rayN.exe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c&#34;&gt;# 代理软件已运行，启用系统代理即可&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;Write-Output&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Re-enabling Proxy&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;Set-ItemProperty&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Path&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings&amp;#34;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Name&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ProxyEnable&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;-Value&lt;/span&gt; &lt;span class=&#34;mf&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;将里面的 &lt;code&gt;Your\Path\To\v2rayN.exe&lt;/code&gt; 替换为v2rayN.exe路径，然后让那个任务计划在满足条件时执行它。&lt;/p&gt;
&lt;p&gt;v2rayN采用的是系统代理方案，把v2rayN.exe结束掉，会自动结束xray.exe，但要手动控制系统代理。控制它的注册表项是HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ProxyEnable，类型为DWORD，1为开启，0为关闭。&lt;/p&gt;
&lt;p&gt;显而易见，&lt;a class=&#34;link&#34; href=&#34;http://clients3.google.com/generate_204&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;http://clients3.google.com/generate_204&lt;/a&gt; 是在墙外的网站。如果访问正常，这个页面会返回一个HTTP 204 NoContent，否则res会是 $null。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://qastack.cn/superuser/262799/how-to-launch-a-command-on-network-connectiondisconnection&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;/a&gt;&lt;a class=&#34;link&#34; href=&#34;https://superuser.com/questions/262799/how-to-launch-a-command-on-network-connection-disconnection&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;windows - How to launch a command on network connection/disconnection? - Super User&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.fmqcloud.com/archives/task-win.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;利用 Windows 计划任务定时关闭程序 - 蜂鸣器 (fmqcloud.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://meta.appinn.net/t/topic/3212/14&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;一键打开关闭 ie 代理 - 问题求助 - 小众软件官方论坛 (appinn.net)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.netwrix.com/2018/09/11/how-to-get-edit-create-and-delete-registry-keys-with-powershell/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;How to Get, Edit, Create and Delete Registry Keys with PowerShell (netwrix.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhidao.baidu.com/question/1495346086099937419.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;如何在 powershell 中让运行的程序停止 _百度知道 (baidu.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.51cto.com/281816327/1436748&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;设定 Windows 计划任务定期执行 PowerShell 脚本【图文】_StanlyCheng_51CTO 博客&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://cloud.tencent.com/developer/ask/97261&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;如何在 PowerShell 中获取数字 HTTP 状态码？ - 问答 - 云 + 社区 - 腾讯云 (tencent.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://social.technet.microsoft.com/Forums/windows/en-US/e9edd868-4421-4e67-bd37-83c151f671cc/check-if-a-process-is-running?forum=winserverpowershell&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Check if a process is running (microsoft.com)&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Windows 11 bug 大赏</title>
        <link>https://cyp0633.com/post/windows-11-bugs/</link>
        <pubDate>Sun, 10 Oct 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/windows-11-bugs/</guid>
        <description>&lt;p&gt;因为我对Windows 11奇差无比的稳定性非常愤怒，所以水了这篇博客。可能持续更新。&lt;/p&gt;
&lt;p&gt;老（伪）软粉，无意搞什么微软圣经，只是发发牢骚。&lt;/p&gt;
&lt;p&gt;如果你没遇到部分或者全部这些bug，那么祝贺你，你很幸运；但请不要抱侥幸心理而选择直接OTA升级，即使不全新安装，也请下载并使用完整ISO升级，这样流畅度可能大幅提升，bug可能大幅减少，简要方法见文末。&lt;/p&gt;
&lt;h2 id=&#34;1无法打开xxx因为它处于脱机状态&#34;&gt;1.“无法打开xxx，因为它处于脱机状态”
&lt;/h2&gt;&lt;p&gt;发现于Build 22000.194&lt;/p&gt;
&lt;p&gt;Forza Horizon 4安装在非系统硬盘上，但一直连接在电脑上，其他文件也正常访问。&lt;/p&gt;
&lt;p&gt;不定期发生，可能重启后解决；如果重启后仍未解决，可能静置一段时间后自动解决。&lt;/p&gt;
&lt;h2 id=&#34;2-农历日历显示错乱自相矛盾&#34;&gt;2. 农历日历显示错乱，自相矛盾
&lt;/h2&gt;&lt;p&gt;发现于Build 22000.194&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug1.png&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;2&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;今天到底是九月初三还是初四？&lt;/p&gt;
&lt;h2 id=&#34;3-桌面窗口缩略图弹出错位&#34;&gt;3. 桌面窗口缩略图弹出错位
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.194&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;3&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;缩略图应该弹出在图标正上方（注意我鼠标的位置，没有用截图就是为了看鼠标）。&lt;/p&gt;
&lt;h2 id=&#34;4图片app缩略图更新不及时&#34;&gt;4.“图片”App缩略图更新不及时
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.194&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug3.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;4&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;裁剪后的图片如大图所示，而下方缩略图则仍为裁剪前的图片。&lt;/p&gt;
&lt;h2 id=&#34;5-深色模式转换不完全&#34;&gt;5. 深色模式转换不完全
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.194、22000.258&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug4.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;5-1&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;5-2&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;从深色模式转回浅色模式，同一窗口下的部分内容仍停留在深色模式，即使其余内容可以自动转换。&lt;/p&gt;
&lt;h2 id=&#34;6-高dpi缩放错误&#34;&gt;6. 高DPI缩放错误
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.194、22000.282&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug5.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;6-1&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;界面只占了窗口左上方的一小部分。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug12.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;6-2&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;可大，可小。&lt;/p&gt;
&lt;h2 id=&#34;7-任务栏图标消失&#34;&gt;7. 任务栏图标消失
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.194&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug7.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;7&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;除开始菜单图标外，App图标全部消失。我有两块屏幕，扩展方式连接，而主屏幕的任务栏图标一切正常。&lt;/p&gt;
&lt;h2 id=&#34;8-资源管理器上方功能图标消失&#34;&gt;8. 资源管理器上方功能图标消失
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.258、22000.282&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug8.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;8&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;一次卡出两个bug，不愧是我&lt;/p&gt;
&lt;p&gt;上方功能菜单的图标大部分都没了。能点，但单纯是看不见。&lt;/p&gt;
&lt;h2 id=&#34;9windows开始菜单图标消失&#34;&gt;9.Windows开始菜单图标消失
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.258&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug9.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;9&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;10-输入法指示器错位&#34;&gt;10. 输入法指示器错位
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.258&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug10.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;10&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;此处是屏幕左下方，常用vscode的读者应该很容易看出来。&lt;/p&gt;
&lt;h2 id=&#34;11-任务栏音量图标显示颠倒&#34;&gt;11. 任务栏音量图标显示颠倒
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.258、22000.346&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug11.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;11&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;声音打开的时候显示关闭，声音关闭的时候显示打开。&lt;/p&gt;
&lt;h2 id=&#34;12windows开始菜单打不开&#34;&gt;12.Windows开始菜单打不开
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.258&lt;/p&gt;
&lt;p&gt;这个不用图描述吧？&lt;/p&gt;
&lt;h2 id=&#34;13-开始菜单阴影遮罩错位&#34;&gt;13. 开始菜单阴影遮罩错位
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.282&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug13.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;13&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;你们开始菜单呐还是要提高自己的姿势水平，不要总想着搞个大遮罩，这样是不行滴！&lt;/p&gt;
&lt;h2 id=&#34;14-任务栏选项错位&#34;&gt;14. 任务栏选项错位
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.282&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug14.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;14&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这里是这块屏幕的左端，正常来说应该显示在对应图标的上方。&lt;/p&gt;
&lt;h2 id=&#34;15-任务栏无故出现强提醒&#34;&gt;15. 任务栏无故出现强提醒
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.346&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug15.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;15&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;如你所见，我并没有打开任何Windows Explorer窗口，而它却在任务栏给我发了一个强提醒。&lt;/p&gt;
&lt;h2 id=&#34;16-任务管理器渲染成点阵字体&#34;&gt;16. 任务管理器渲染成点阵字体
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.346&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug17.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;16&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这玩意没过多久自己闪退了，不过重新打开任务管理器就好了。&lt;/p&gt;
&lt;h2 id=&#34;17-解锁后全屏模糊&#34;&gt;17. 解锁后全屏模糊
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.346&lt;/p&gt;
&lt;p&gt;没有图，Windows截图转存WebDAV的时候损坏了……&lt;/p&gt;
&lt;h2 id=&#34;18-任务栏图标错位&#34;&gt;18. 任务栏图标错位
&lt;/h2&gt;&lt;p&gt;出现于22000.348&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug19.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;18&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;《潜水的Visual Studio》&lt;/p&gt;
&lt;h2 id=&#34;19-搜索窗口错位&#34;&gt;19. 搜索窗口错位
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.376&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug20.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;19&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Windows搜索本该遵循任务栏图标位置设置，出现在左下方，然而却出现在了中间。&lt;/p&gt;
&lt;h2 id=&#34;20-出现无法消失的窗口&#34;&gt;20. 出现无法消失的窗口
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.376&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug21.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;20&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;是的，就这么凭空出现在那里。&lt;/p&gt;
&lt;h2 id=&#34;21-远程桌面断开后系统音量和亮度调节无法恢复&#34;&gt;21. 远程桌面断开后，系统音量和亮度调节无法恢复
&lt;/h2&gt;&lt;p&gt;出现于Build 22000.434&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-bugs/win11bug22.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;21&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;远程桌面（RDP）连接时是无法调节系统亮度的，音量默认最大，由客户端控制。断开后仍无法使用Windows控制中心调节亮度，音量也未恢复，但实际上可以使用Twinkle Tray调节亮度，播放声音设备也可正常识别。&lt;/p&gt;
&lt;p&gt;复现概率很小。&lt;/p&gt;
&lt;h2 id=&#34;附录升级windows的正确姿势&#34;&gt;附录：升级Windows的正确姿势
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;打开 &lt;a class=&#34;link&#34; href=&#34;https://uupdump.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;UUP dump&lt;/a&gt;，一般用户建议点击“公开发布的最新内部版本” 或“最新发布预览通道版本”后的“x64”，如果看得懂，也可以选择其他预览版、架构，或从下方更新列表手动选择。然后，不懂的建议直接一路下一步。&lt;/li&gt;
&lt;li&gt;解压从上面网页下载到的zip，Windows用户双击执行uup_download_windows.cmd，等待下载转换压缩过程完成。&lt;/li&gt;
&lt;li&gt;点击解压后目录出现的ISO文件，双击setup.exe安装。由于我们下载的文件已经包含最新更新，建议选择更改检查更新的方式 - 不检查更新。&lt;/li&gt;
&lt;li&gt;一路下一步等待自动升级。&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>再见了，小 X 知识网，再也不见</title>
        <link>https://cyp0633.com/post/goodbye-content-farm/</link>
        <pubDate>Sat, 09 Oct 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/goodbye-content-farm/</guid>
        <description>&lt;p&gt;不知何时，Google的搜索结果中出现了大量垃圾搜索结果，尤以”小X知识网 “和“小X百科网” 最为猖獗。&lt;/p&gt;
&lt;p&gt;点进任意一个此种网站，发现基本都是营销号套话，和从别处随意复制粘贴来的内容——几乎都没有原文链接，更几乎不可能事先申请过转载授权。据称这种网站一般被称作” 内容农场 “，专门发布垃圾文章，同时大搞SEO，因此搜索结果通常很靠前。&lt;/p&gt;
&lt;p&gt;之后从V2EX找到了Chromium插件 &lt;a class=&#34;link&#34; href=&#34;https://chrome.google.com/webstore/detail/ublacklist/pncfbmialoiaghdehhbnbhkkgmjanfhe&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;uBlacklist&lt;/a&gt;（被墙，不过对于Google用户应该不是问题），用于屏蔽Google等几个搜索引擎中的特定搜索结果，眼不见心不烦。同时支持Firefox和Safari。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/iorate/ublacklist&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;iorate/ublacklist&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安装后，Google的每个搜索结果旁都会显示 “加入黑名单” 按钮，而在浏览某个网页时，你可以点击插件栏的uBlacklist按钮，将正在浏览的网站加入黑名单。加入黑名单的域名或子域名，将会被从搜索结果中剔除，同时在搜索界面显示“uBlacklist已经屏蔽了x个网址”，其中域名和子域名遵循Mozilla匹配模式（格式如 &lt;code&gt;://search.bilibili.com/&lt;/code&gt;。Google有时会在搜索结果中包含B站搜索的网页，而如果我需要视频结果我会使用站内搜索，所以这里将它屏蔽掉）。&lt;/p&gt;
&lt;p&gt;实际上，我也一直苦于搜索结果中的 “程序员信息网”” 代码先锋网“之类网站，它们更像是纯粹的搬运（或者说，偷窃）各位博主的劳动成果。由于这种网站并不太多，简单的像上面这样域名屏蔽即可解决，大不了再屏蔽就是了。此外，华为云社区有时也会干这种不三不四的事情，搞不懂是为什么，反正一起被我屏蔽了。&lt;/p&gt;
&lt;p&gt;但这些 “小X知识网” 实在太多了，有的域名都没注册直接拿IP地址就出来污染，靠域名根本屏蔽不完，怎么办？uBlacklist还支持标题屏蔽，更支持正则表达式，格式如 &lt;code&gt;title\your_regex\&lt;/code&gt;。直接添加 &lt;code&gt;title\ 小. 知识网 \&lt;/code&gt; 和 &lt;code&gt;title\ 小. 百科网 \&lt;/code&gt;，搜索结果马上就清净了。&lt;/p&gt;
&lt;p&gt;想一劳永逸？在下面的V2EX原帖链接中，一些网友还提供了规则订阅链接，免于手动配置屏蔽，威力比较大，可能误伤。&lt;/p&gt;
&lt;p&gt;或者你也可以尝试”Content Farm Terminator“插件，它能够一定程度上自动屏蔽这类内容农场网站。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/danny0838/content-farm-terminator&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;danny0838/content-farm-terminator&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;参考：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.v2ex.com/t/806025&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;请问在 google 搜索时，频繁遇到小 X 知识网等内容农场式结果，怎么办？ - V2EX&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;亿点碎碎念&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;作为互联网汪洋大海的一个小透明网站，不知道我的文章有没有落入这类网站的魔爪之中。&lt;/p&gt;
&lt;p&gt;我个人是反感这种做派的，但鉴于本站的文章默认遵守CC BY-SA 4.0协议（后续会在网站更多文章中有更明显的体现），只要注明来源、许可没问题那我也不好干涉，所以如果您碰巧发现疑似我的文章被盗而未标明出处，欢迎直接在本文下方发送评论，我将尽量投诉此类网站，在此不胜感激。当然，懒得帮也没关系，还是感谢您能抽时间观看本文 :)&lt;/p&gt;
&lt;p&gt;不知道这些网站为什么要这么做，搞不懂盈利方式。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>我的 C 盘空间清理方法论</title>
        <link>https://cyp0633.com/post/clean-c-partition/</link>
        <pubDate>Fri, 10 Sep 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/clean-c-partition/</guid>
        <description>&lt;p&gt;C盘空间的清理一直是Windows用户的老大难问题，用着用着空间就没了，这里分享一些清理C盘空间的方法。&lt;/p&gt;
&lt;p&gt;除非你的C盘已经非常满了，否则不建议完全删除或禁用缓存一类的文件（如缩略图缓存），它能显著提升电脑速度。即使C盘很满，我也建议先扩容——当然，这就不是本文所要讨论的范畴了。&lt;/p&gt;
&lt;h2 id=&#34;空间分析&#34;&gt;空间分析
&lt;/h2&gt;&lt;p&gt;首先下载 &lt;a class=&#34;link&#34; href=&#34;https://windirstat.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WinDirStat&lt;/a&gt;，用它分析C盘的空间利用情况。进去之后选C盘，然后它就会开始扫描分析你的C盘内容。界面是英文的，但连猜带蒙应该也能看懂。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;clean-c-partition/windirstat.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;WinDirStat 内容&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;扫描完成后，它能够以很直观的图表呈现C盘的各个区域占用了多大。上方是C盘文件树和按类型的空间占用情况，下方则是将不同文件和目录分别染色之后，用块大小表示的空间占用情况。比如左上方的黄色块，对应的就是占用5GB的开发工具vscode cpptools缓存目录；而右边巨大的紫色块则是Windows搜索索引文件Windows.edb。&lt;/p&gt;
&lt;p&gt;或者你也可以使用 &lt;a class=&#34;link&#34; href=&#34;https://www.jam-software.com/treesize_free&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;TreeSize&lt;/a&gt;，其免费版相比WinDirStat有颜值更高的用户界面和各方面都更好的性能，但没有下方的占用情况块状图。如果你有需求恰巧也很有钱，可以购买其Personal版本，功能多一些。&lt;/p&gt;
&lt;p&gt;如果你找到了大量占用C盘空间的元凶，请勿直接删除它！这可能导致系统或者应用程序无法正常启动。建议在Google或者 &lt;a class=&#34;link&#34; href=&#34;http://cn.bing.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;必应&lt;/a&gt; 搜索引擎搜索文件或者文件夹名，以确认是否能删除；&lt;strong&gt;如果没有什么非常必须的理由，不要用百度。&lt;/strong&gt; 如果遇到英文网站，不要直接退缩，能读就读，不能读也可以谷歌翻译看看，里面也可能有很有价值的信息。&lt;/p&gt;
&lt;p&gt;下面会时不时整理一些我遇到的切实可行的方法，供大家参考。在Windows 10 21H1测试通过，但可能不适用于所有系统版本。&lt;/p&gt;
&lt;h2 id=&#34;windows系统和microsoft应用&#34;&gt;Windows系统和Microsoft应用
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://answers.microsoft.com/zh-hans&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Microsoft 社区&lt;/a&gt; 有很多关于Windows清理的有用建议，比如什么系统文件能不能删除等，在搜索的时候可以多多留意。&lt;/p&gt;
&lt;h3 id=&#34;windows搜索索引&#34;&gt;Windows搜索索引
&lt;/h3&gt;&lt;p&gt;参考了 &lt;a class=&#34;link&#34; href=&#34;https://baiyunju.cc/6693&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;C 盘清理教程丨 24G 大的“Windows.edb” 是什么文件，可以删除吗？-『白云居』 (baiyunju.cc)&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;常表现为有一个巨大的C:\ProgramData\Microsoft\Search\Data\Applications\Windows\Windows.edb文件。&lt;/p&gt;
&lt;p&gt;如果你不需要在Windows搜索中直接搜索到文件记录的内容（如某个代码文件中的某个语句），你可以在 “此电脑” 中，右键盘符（不止C盘）选择“属性”，禁用“除了文件属性外，还允许索引此驱动器上文件的内容”，选择“适用于子目录和文件”，然后等待系统应用属性（很慢），然后参考下一段的方法重建索引文件。这样可以显著减小索引文件的大小。&lt;/p&gt;
&lt;p&gt;如果想将它移出C盘，前往Windows设置 - 搜索 - 搜索Windows - 高级搜索引擎索引器设置 - 高级，选择一个新的位置，然后点击重建索引。&lt;/p&gt;
&lt;h3 id=&#34;windows-subsystem-for-linux-wsl-2&#34;&gt;Windows Subsystem for Linux (WSL 2)
&lt;/h3&gt;&lt;p&gt;常表现为C盘内一个大约4GB的vhdx文件。&lt;/p&gt;
&lt;p&gt;如果希望将它移出C盘，请参见 &lt;a class=&#34;link&#34; href=&#34;https://cyp0633.com/archives/784&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;如何将 WSL2 迁移至其他盘&lt;/a&gt;。&lt;/p&gt;
&lt;h3 id=&#34;windows自带-磁盘清理-工具&#34;&gt;Windows自带 “磁盘清理” 工具
&lt;/h3&gt;&lt;p&gt;这个工具可以用来清理硬盘内的传递优化文件等一些杂七杂八的文件。&lt;/p&gt;
&lt;p&gt;前往 此电脑 - C盘 - 属性 - 磁盘清理（等一下）- 清理系统文件，你可以根据下面的描述决定是否清理某一项文件。&lt;/p&gt;
&lt;p&gt;另外，你也可以从Windows设置 - 系统 - 存储中管理你的C盘使用情况。&lt;/p&gt;
&lt;h3 id=&#34;传递优化&#34;&gt;传递优化
&lt;/h3&gt;&lt;p&gt;简单来说，就是Windows更新服务器不足，所以设计了传递优化功能，能够从其他电脑上下载别人已经更新好的更新文件，类似于BT下载。不能只索取而不付出，所以如果你允许从其他电脑下载，你的电脑也会为别人服务。&lt;/p&gt;
&lt;p&gt;如果想关闭，前往Windows设置 - 更新和安全 - 传递优化，关闭 “允许从其他电脑下载”。&lt;/p&gt;
&lt;h3 id=&#34;更改个人文件夹目录&#34;&gt;更改个人文件夹目录
&lt;/h3&gt;&lt;p&gt;如果你不知道什么是UWP应用什么是桌面应用，全都做就行了。&lt;/p&gt;
&lt;p&gt;对于UWP应用的默认设定，前往Windows设置 - 系统 - 存储 - 更改新内容的保存位置，选择C盘以外的位置，点击应用。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;clean-c-partition/change-new-content-position.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;更改新内容的保存位置&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;对于Windows桌面应用，打开 “此电脑”，分别进入“下载”“视频”“图片”“文档”“音乐” 文件夹的属性，选择 “位置” 选项卡，选择另外一个位置，别忘了点击“移动”。&lt;/p&gt;
&lt;h3 id=&#34;microsoft-onedrive&#34;&gt;Microsoft OneDrive
&lt;/h3&gt;&lt;p&gt;在C:/Users / 用户名 / AppData/Local/Microsoft/OneDrive内有大量日志文件。&lt;/p&gt;
&lt;h3 id=&#34;microsoft-edge&#34;&gt;Microsoft Edge
&lt;/h3&gt;&lt;p&gt;在C:/Users / 用户名 / AppData/Local/Microsoft/Edge/User Data/BrowserMetrics内有大量单个4MB的遥测文件，可以删除。&lt;/p&gt;
&lt;p&gt;微软 &lt;a class=&#34;link&#34; href=&#34;https://techcommunity.microsoft.com/t5/discussions/browsermetrics/m-p/967920&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;已经确认了此 bug&lt;/a&gt;，但半年多了，还没修。&lt;/p&gt;
&lt;h2 id=&#34;开发工具&#34;&gt;开发工具
&lt;/h2&gt;&lt;h3 id=&#34;visual-studio-code&#34;&gt;Visual Studio Code
&lt;/h3&gt;&lt;h4 id=&#34;c-intellisense功能缓存&#34;&gt;C++ IntelliSense功能缓存
&lt;/h4&gt;&lt;p&gt;参考了 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Microsoft/vscode-cpptools/issues/3347#issuecomment-476277174&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;.vscode caching too much data since update&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;常表现为在C:\Users\ 你的用户名 \AppData\Local\Microsoft\vscode-cpptools\ipch中有大量20MB左右的ipch文件。&lt;/p&gt;
&lt;p&gt;在VSCode设置中搜索 &amp;ldquo;intellisensecache&amp;rdquo;，你可以改变缓存位置和缓存大小（单位MB）。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;clean-c-partition/cpptools.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Intelli Sense Cache Path&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;android-studio&#34;&gt;Android Studio
&lt;/h3&gt;&lt;p&gt;软链接（符号链接）是一个泛用性比较强的办法，理论上适用于所有较大而难以改变位置的文件 / 目录。以下方法均测试通过。&lt;/p&gt;
&lt;p&gt;Android Studio的构建密钥、AVD等均存放于~/.android目录下，可以用类似于以下的命令将其移至其他目录。关于图形化的操作方法以及其他知识，请翻阅参考文献。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;clean-c-partition/symbolic_link.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;符号链接&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;此外，~/.gradle目录也不小，可以迁走。&lt;/p&gt;
&lt;p&gt;参考：&lt;a class=&#34;link&#34; href=&#34;https://sspai.com/post/66834&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://sspai.com/post/66834&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;日常应用&#34;&gt;日常应用
&lt;/h2&gt;&lt;h3 id=&#34;qqtim&#34;&gt;QQ/TIM
&lt;/h3&gt;&lt;p&gt;以TIM为例，左下角选项 - 设置 - 文件管理中可以管理APP所存储的文件，还可以移动接收文件的文件夹。&lt;/p&gt;
&lt;p&gt;聊天图片通常非常大，存储于C:\Users\ 用户名 \Documents\Tencent Files\QQ号 \Image。“C2C”文件夹中存储了私人聊天的图片，而 “Group2” 文件夹存储了群聊图片，可以更细致地手动清理。&lt;/p&gt;
&lt;p&gt;腾讯系软件的日志位于C:\Users\ 用户名 \AppData\Roaming\Tencent\Logs。&lt;/p&gt;
&lt;h3 id=&#34;nvidia显卡驱动&#34;&gt;NVIDIA显卡驱动
&lt;/h3&gt;&lt;p&gt;在C:/ProgramData/NVIDIA Corporation/Downloader内。显卡驱动安装文件一般大至400MB，很可观。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>如何将 WSL2 迁移至其他盘</title>
        <link>https://cyp0633.com/post/wsl2-migration/</link>
        <pubDate>Sat, 04 Sep 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/wsl2-migration/</guid>
        <description>&lt;p&gt;在Windows中，WSL2（Windows Subsystem for Linux）子系统默认安装在C盘，本文介绍如何将其移动至其他盘符，也可以在不同电脑间迁移。&lt;/p&gt;
&lt;p&gt;以下内容总结自 &lt;a class=&#34;link&#34; href=&#34;https://github.com/MicrosoftDocs/WSL/issues/412&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;how to move the vhdx of wsl2 to other disk · Issue #412 · MicrosoftDocs/WSL (github.com)&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;首先打开任何一个终端，CMD或者PowerShell都可以。建议在你希望迁移后WSL所处的目录下打开，如我希望将WSL迁移到D:\UbuntuWSL，就在这个目录下打开，或者打开后使用 &lt;code&gt;cd D:\UbuntuWSL&lt;/code&gt; 命令。&lt;/p&gt;
&lt;p&gt;然后，输入 &lt;code&gt;wsl --list&lt;/code&gt; 并运行，系统会为你输出当前的子系统列表，如：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;text&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;适用于 Linux 的 Windows 子系统分发版:
Ubuntu2 (默认)
docker-desktop
docker-desktop-data
Ubuntu&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;适用于 Linux 的 Windows 子系统分发版:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ubuntu2 (默认)
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker-desktop
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker-desktop-data
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Ubuntu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;请记住你想迁移的子系统名。下面的命令将会占用很多系统资源。&lt;/p&gt;
&lt;p&gt;然后，运行 &lt;code&gt;wsl --export &amp;lt;子系统名&amp;gt; &amp;lt;导出文件名. tar&amp;gt;&lt;/code&gt;，其中 “子系统名” 就是你刚刚记住的子系统名，“导出文件名”是你希望导出文件的命名，可以使用完整路径代替（如D:\UbuntuWSL\ubuntu.tar）。这个命令可以将已安装的特定子系统打包成TAR压缩文件。&lt;/p&gt;
&lt;p&gt;找到此TAR文件，将其移动到你想迁移到的位置，并将终端的工作目录移动至那里。当然如果你一开始就设定好目录那现在就不用了，而且其实不迁移也没什么问题&lt;/p&gt;
&lt;p&gt;运行 &lt;code&gt;wsl --import &amp;lt;迁移后子系统名称&amp;gt; &amp;lt;迁移后 WSL 工作目录&amp;gt; &amp;lt;tar 文件路径&amp;gt;&lt;/code&gt;，这个命令可以从tar文件导入子系统。迁移后的子系统名称不能与原来已有的重复；工作目录可以任选，不一定要和tar文件在一起。&lt;/p&gt;
&lt;p&gt;再次运行 &lt;code&gt;wsl --list&lt;/code&gt;，如果你迁移后的子系统本应成为默认而实际上并没有，使用 &lt;code&gt;wsl --set-default &amp;lt;子系统名&amp;gt;&lt;/code&gt; 命令来设为默认。&lt;/p&gt;
&lt;p&gt;现在，你可以使用 &lt;code&gt;wsl --unregister 子系统名&lt;/code&gt; 来完全删除原子系统，不过我建议先使用迁移后的系统一段时间，来确保没有问题。&lt;/p&gt;
&lt;p&gt;已知问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;迁移后默认账户变为root。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试正常工作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;仍可将WSLg GUI应用程序集成到开始菜单。&lt;/li&gt;
&lt;li&gt;Windows资源管理器仍可浏览Linux文件系统的文件。&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        <item>
        <title>Cloudreve：属于你的网盘</title>
        <link>https://cyp0633.com/post/cloudreve-personal-cloud-drive/</link>
        <pubDate>Sun, 08 Aug 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/cloudreve-personal-cloud-drive/</guid>
        <description>&lt;p&gt;无论是搭建在互联网的服务器上、本地，还是局域网的其他设备上，&lt;a class=&#34;link&#34; href=&#34;https://github.com/cloudreve/Cloudreve&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cloudreve&lt;/a&gt; 都能提供出色的云服务。对于个人，它存点资料完全够用；而对于组织，它也有账号管理系统，可以满足多人使用的需求。我是将它作为个人云使用的，除上面所说之外，它还有许多感知强烈的优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;上传下载不限速，具体视服务器和客户机而定&lt;/li&gt;
&lt;li&gt;文件实时在线预览 / 编辑 / 压缩&lt;/li&gt;
&lt;li&gt;连接到其他存储服务，如Microsoft OneDrive、亚马逊S3等，当然也可以存在服务器端&lt;/li&gt;
&lt;li&gt;Material Design网页界面，多平台、深色模式及PWA支持&lt;/li&gt;
&lt;li&gt;支持文件分享，可选直链分享&lt;/li&gt;
&lt;li&gt;WebDAV&lt;/li&gt;
&lt;li&gt;配合aria2实现离线下载&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;相比官方原版OneDrive，它的网页端可以自由访问；而相比百度云，它就只有容量不占优了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cloudreve-personal-cloud-drive/cloudreve-ui.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Cloudreve PWA 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;以下皆以amd64架构的Ubuntu 20.04为例。&lt;/p&gt;
&lt;h2 id=&#34;部署&#34;&gt;部署
&lt;/h2&gt;&lt;p&gt;在服务器中合适的位置用 &lt;code&gt;chmod&lt;/code&gt; 新建一个目录，然后下载 &lt;a class=&#34;link&#34; href=&#34;https://github.com/cloudreve/Cloudreve/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Releases&lt;/a&gt; 页面对应架构的软件包，解压即可。&lt;/p&gt;
&lt;p&gt;对于负载不大的情况，可以直接使用Cloudreve自带的反代服务器，无需重新设置。&lt;/p&gt;
&lt;p&gt;直接执行 &lt;code&gt;./cloudreve&lt;/code&gt; 即可使其前台运行，后台运行可以使用nohup。第一次运行建议截个图，内含管理员账号密码，用它登录进去之后可以在管理后台进行改名改密码等操作。&lt;/p&gt;
&lt;h3 id=&#34;ssl&#34;&gt;SSL
&lt;/h3&gt;&lt;p&gt;如果你想使用Cloudreve的OneDrive同步，你还需要HTTPS访问，而这需要一个SSL证书和一个域名。域名可以自己买，而这里主要解决SSL的问题。这里推荐使用Certbot来完成这个过程，它使用了Let&amp;rsquo;s Encrypt的服务。可以参考 &lt;a class=&#34;link&#34; href=&#34;https://certbot.eff.org/lets-encrypt/ubuntufocal-other&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文档&lt;/a&gt; 的方法。简单来说，就是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 &lt;code&gt;sudo snap install certbot&lt;/code&gt; 安装certbot&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;sudo certbot certonly --standalone&lt;/code&gt;（如果80端口没被占用）&lt;/li&gt;
&lt;li&gt;依次输入你的邮箱和域名&lt;/li&gt;
&lt;li&gt;记下证书路径和私钥路径&lt;/li&gt;
&lt;li&gt;编辑Cloudreve文件夹下的conf.ini，加入以下内容：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[SSL]
Listen = :xxx ; 将 xxx 替换为 HTTPS 访问该网站用的端口号，如 https://abc.com:xxx，推荐使用 443
CertPath = /etc/letsencrypt/live/abc.com/fullchain.pem ;abc.com 替换为你的域名
KeyPath = /etc/letsencrypt/live/abc.com/privkey.pem ; 同上&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[SSL]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;Listen&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;:xxx ; 将 xxx 替换为 HTTPS 访问该网站用的端口号，如 https://abc.com:xxx，推荐使用 443&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;CertPath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/etc/letsencrypt/live/abc.com/fullchain.pem ;abc.com 替换为你的域名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;KeyPath&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;/etc/letsencrypt/live/abc.com/privkey.pem ; 同上&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果你已经在运行Cloudreve，先执行 &lt;code&gt;killall cloudreve&lt;/code&gt; 再重新启动。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cloudreve-personal-cloud-drive/upload-speed.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;上传速度演示，受网速限制&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;上传速度演示，受网速限制&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;到现在就可以使用服务器本地的硬盘空间作为一个网盘了。操作非常简单，我想我没必要再说了。但对于OneDrive，我觉得还得再提一句。&lt;/p&gt;
&lt;h2 id=&#34;连接onedrive&#34;&gt;连接OneDrive
&lt;/h2&gt;&lt;p&gt;许多云主机的空间很小，装不下几个大文件，这时可以连接到OneDrive，支持个人用户或者企业 / 学校用户，以及各种Microsoft 365套餐。&lt;/p&gt;
&lt;p&gt;在下载大文件的时候，主机直接连接微软服务器。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;cloudreve-personal-cloud-drive/download-speed.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;下载速度&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
			&lt;figcaption&gt;就是这么快……&lt;/figcaption&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在管理后台的”存储策略 “点击添加，然后按步骤操作。如果你用的不是公司 / 学校Microsoft账户，注册应用程序时需要选择” 任何组织目录…… 及个人Microsoft账户 “，后面才可以验证，否则会出现” 无法使用个人帐户在此登录，请改用工作或学校帐户“的错误。&lt;/p&gt;
&lt;p&gt;添加完成之后，还需要在” 用户组 “设置里选择特定用户组使用的使用的存储策略，才能使用其他平台的存储空间。&lt;/p&gt;
&lt;h3 id=&#34;onedrive代理加速&#34;&gt;OneDrive代理加速
&lt;/h3&gt;&lt;p&gt;可以参考 &lt;a class=&#34;link&#34; href=&#34;https://niconiconi.cc/blog/202.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文章&lt;/a&gt;，Cloudreve的OneDrive反代原理是一样的。不过，如果你使用的是OneDrive个人版，获取到的下载链接类似于 &lt;a class=&#34;link&#34; href=&#34;https://public.bn.files.1drv.com%ef%bc%8c%e4%b9%9f%e6%98%af%e5%8f%af%e4%bb%a5%e7%9a%84%ef%bc%8c%e4%b8%8d%e5%bf%85%e5%bc%ba%e6%b1%82&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://public.bn.files.1drv.com，也是可以的，不必强求&lt;/a&gt; SharePoint链接。&lt;/p&gt;
&lt;h2 id=&#34;反代&#34;&gt;反代
&lt;/h2&gt;&lt;p&gt;我使用的是Nginx反代，所以当然以它为例。核心部分就是照着官方文档的配置，在Nginx的某个server中加入以下的location。&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:5212;
    # 如果您要使用本地存储策略，请将下一行注释符删除，并更改大小为理论最大文件尺寸
    # client_max_body_size 20000m;
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;location&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;/&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;X-Forwarded-For&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;$proxy_add_x_forwarded_for;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;proxy_set_header&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;Host&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;$http_host;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;proxy_redirect&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;off;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;proxy_pass&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;http:&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//127.0.0.1:5212;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;    &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;如果您要使用本地存储策略，请将下一行注释符删除，并更改大小为理论最大文件尺寸&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;err&#34;&gt;#&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;client_max_body_size&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;20000m;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;需要注意的是，Cloudreve目前（指3.3.2和3.4.0-beta1）并不能够使用二级目录反代，如设置 &lt;code&gt;location ^~ /cloud&lt;/code&gt;，因为Cloudreve会在调用静态资源的时候访问不带二级目录的内容，即使 “站点URL” 中已添加二级目录也是这样。所以，我更推荐使用在Nginx里新建一个server，将另一个二级域名的根目录直接指向Cloudreve。只需设定不同的 &lt;code&gt;server_name&lt;/code&gt;，Nginx就可以根据不同的二级域名来访问不同的服务，即使设定的listen端口相同。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;参考文献&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://docs.cloudreve.org/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Cloudreve 官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://forum.cloudreve.org/d/1139&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;无法使用个人帐户在此登录，请改用工作或学校帐户 - Cloudreve Forum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;又水一篇，开心&lt;/p&gt;
</description>
        </item>
        <item>
        <title>HNU 校园网 IPv6 免流教程 2.0</title>
        <link>https://cyp0633.com/post/hnu-ipv6-bypass-billing-2/</link>
        <pubDate>Wed, 28 Jul 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/hnu-ipv6-bypass-billing-2/</guid>
        <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;阅读前警告&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;此教程仅供学习参考和经验交流，如您决定实践，作者对造成的后果不负任何责任，也不保证效果。&lt;/p&gt;
&lt;p&gt;本教程只适用于2021年9月的湖南大学校园网，未来有更新可能，其他高校情况也不尽相同。&lt;/p&gt;
&lt;p&gt;在新的校园网计费标准下，以这个步骤执行，并不一定能省钱，而且体验也不一定好。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;炒个冷饭，由于好久之前写的 &lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/archives/53&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;免流实录（还算不得教程）&lt;/a&gt; 实在是太散乱，这次决定整理一下思路（持续整理中）。&lt;/p&gt;
&lt;h2 id=&#34;校园网环境与免流概述&#34;&gt;校园网环境与免流概述
&lt;/h2&gt;&lt;p&gt;湖南大学校园网，可以看作有IPv4和IPv6两条连接外界的通道。IPv4会经过校园网的计费和限速系统，然后接入联通或电信的骨干网；IPv6则没有计费、（可能）没有限速，接入CERNET2，也就是纯IPv6的下一代教育网。&lt;/p&gt;
&lt;p&gt;宿舍的校园网接入只有无线路由器，而路由器检测到电脑MAC地址前缀就会分配IPv6地址，而手机等设备则不会。目前还不能确定哪些是它认为的电脑MAC地址。&lt;/p&gt;
&lt;p&gt;平常的网络流量，v4和v6兼有，v4居多；这里的校园网免流目标，是将所有流量通过IPv6通道发送给代理服务器，并由代理服务器帮助我们访问网络资源，再将信息通过IPv6通过校园网传回我们的设备，以绕过校园网计费系统。代理服务器一般来说也是同时支持v4和v6的。由于需要一台代理服务器，延迟会有显著的增加，所以效果不一定比之前好。&lt;/p&gt;
&lt;p&gt;免流并不能免掉所有的流量，比如BT下载和SFTP协议等可能仍然走校园网IPv4，猜测和端口号有关，经过特殊设置应该也能免掉。不做额外设置，一天内消耗校园网流量可以控制在10M以内。&lt;/p&gt;
&lt;p&gt;本文的内容，就是围绕着如何把网络流量转移到IPv6上展开的。&lt;/p&gt;
&lt;h2 id=&#34;前期准备&#34;&gt;前期准备
&lt;/h2&gt;&lt;p&gt;要做校园网免流，你一定需要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;大量、大量、大量的时间和耐心，你永远不知道有什么问题等着你&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;校园网外一台具有IPv6连接且常开的主机，包括但不限于国内外提供商的云主机（推荐），或者你家里带IPv6的路由器 / 电脑等。会收取一定的费用，按配置而定。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果想要更好的体验，建议额外准备：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;基本的网络和Linux知识，方便自行摸索和看懂网上的教程。如果时间实在太多，可以忽略此条&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一台能够刷入第三方固件的路由器，如小米 / 红米、斐讯、华硕等品牌的大部分型号；或软路由&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;通读此教程，了解大致框架&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;选择代理协议&#34;&gt;选择代理协议
&lt;/h2&gt;&lt;p&gt;所谓代理，简单来说就是把你电脑上网的流量统统转发到另一台计算机上，由它代访问。而协议就是代理服务器和你的计算机通信的方式。&lt;/p&gt;
&lt;p&gt;代理方式根据代理服务器和路由器 / 软路由的硬件条件，以及你的需求而定，多种代理方式可以结合使用。&lt;/p&gt;
&lt;p&gt;下面介绍几种常用的代理协议。&lt;/p&gt;
&lt;h3 id=&#34;vpn&#34;&gt;VPN
&lt;/h3&gt;&lt;p&gt;虚拟专用网络，没有什么引申义。&lt;/p&gt;
&lt;p&gt;很容易被封锁，所以国外服务器请勿使用，国内服务器也有一定风险。&lt;/p&gt;
&lt;p&gt;但是能够代理所有流量，最干净利落，而且对服务器负担较小。&lt;/p&gt;
&lt;h3 id=&#34;shadowsocksr&#34;&gt;Shadowsocks/R
&lt;/h3&gt;&lt;p&gt;Shadowsocks对服务器和路由器的负担也较小。如果你使用的路由器拥有不高于MT7621A的CPU或不高于128M的RAM，建议使用Shadowsocks。&lt;/p&gt;
&lt;h3 id=&#34;vlessgrpc&#34;&gt;Vless+gRPC
&lt;/h3&gt;&lt;p&gt;所有Vless不带加密，更建议购买域名设置证书之后设置TLS加密使用。&lt;/p&gt;
&lt;p&gt;原则上不建议任何性能不高于 &lt;a class=&#34;link&#34; href=&#34;#Shadowsocks/R&#34; &gt;上面提到配置&lt;/a&gt; 的路由器使用，虽然评论区也有大佬成功。&lt;/p&gt;
&lt;p&gt;该协议延迟较低，而最大带宽不及下面的Vless+TCP(XTLS)。&lt;/p&gt;
&lt;h3 id=&#34;vlesstcpxtls&#34;&gt;Vless+TCP(XTLS)
&lt;/h3&gt;&lt;p&gt;相比于上面的gRPC方案，能跑出更高的速度，但延迟稍高。&lt;/p&gt;
&lt;p&gt;根据XTLS协议作者RPRX的说法，如果你使用国外VPS访问国内网站，很容易被侦测。所以 &lt;strong&gt;尽量仅在国内服务器上使用XTLS&lt;/strong&gt;。&lt;/p&gt;
&lt;h3 id=&#34;vmesswebsocket&#34;&gt;Vmess+WebSocket
&lt;/h3&gt;&lt;p&gt;这个自己研究吧，因为能套Cloudflare CDN所以受到一些人的欢迎。&lt;/p&gt;
&lt;h3 id=&#34;wireguard&#34;&gt;Wireguard
&lt;/h3&gt;&lt;p&gt;建议搭配Tailscale使用，详见下文。&lt;/p&gt;
&lt;h2 id=&#34;配置代理服务器&#34;&gt;配置代理服务器
&lt;/h2&gt;&lt;p&gt;配置代理服务器主要就是配置服务端软件。代理服务器分两种，一种是云主机VPS，一种是你自己的硬件。二选一即可。&lt;/p&gt;
&lt;h3 id=&#34;云主机&#34;&gt;云主机
&lt;/h3&gt;&lt;p&gt;国内的云主机延迟较低，但通常限制流量和网速，比较贵；而境外（包括香港等直连境外互联网的地区）的云主机一般流量限制很宽松，带宽很充裕，还带有你懂的功能，但延迟可能很高。系统建议选择各类Linux，配置不用太高，单核1G内存够用。一定要选择带IPv6的方案，尽量也带上IPv4（以访问部分落后的网站…… 包括本站）。&lt;/p&gt;
&lt;p&gt;下面将以几个主机商为例，介绍一些与代理服务器有关的概况。&lt;/p&gt;
&lt;p&gt;关于地域选择的重要提示&lt;/p&gt;
&lt;p&gt;不建议 &lt;strong&gt;任何人&lt;/strong&gt; 在 &lt;strong&gt;任何情况下&lt;/strong&gt; 使用 &lt;strong&gt;境外&lt;/strong&gt;（国外、港澳台）机器代理访问境内网络，此处即使用境外主机达成免流的行为。据Xray开发者RPRX称，作为代理用途访问境内网站的境外服务器 &lt;strong&gt;很容易遭到识别与封禁&lt;/strong&gt;（即被墙）。&lt;br&gt;
如果有访问被封锁网站的特殊需求，建议使用境内服务器作为第一道中转，并配置分流规则，将境外流量转发至境外主机代理。&lt;/p&gt;
&lt;h4 id=&#34;vultr&#34;&gt;Vultr
&lt;/h4&gt;&lt;p&gt;Vultr是国外的服务商，有美国、英国、韩国、日本、新加坡、墨西哥等地的服务器，而且配置较简单，不需要太关注虚拟硬盘、IP地址的分配。支持支付宝。&lt;/p&gt;
&lt;p&gt;实测亚特兰大、洛杉矶、硅谷、西雅图、伦敦的线路并不是CN2线路（一种延迟较低的线路），英国线路延迟200ms左右，美国线路大多200-300ms左右。&lt;/p&gt;
&lt;p&gt;每月5美元的服务器包含单核CPU、1G RAM、25G SSD、每月1T流量，带宽大约600-1000Mbps。可以在创建时选择附带IPv6。&lt;/p&gt;
&lt;h4 id=&#34;华为云&#34;&gt;华为云
&lt;/h4&gt;&lt;p&gt;华为云可以选择按流量计费或按带宽计费。如果按流量计费，带宽上限300Mbps（可自行设置），0.8元 / G；如果按带宽计费，10Mbps就要500元一个月。比校园网还贵，所以说免流只是玩玩而已。&lt;/p&gt;
&lt;p&gt;华为云的弹性公网IP可以开启IPv6转换，它的作用是以类似NAT的方式，将流入的所有v6流量在服务端转发到v4上，所以也可以达到免流目的，而且不需要特殊操作。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;SSH连接主机，可以直接在命令行输入ssh用户名 @服务器地址，然后输入服务器的root密码，即可操控服务器；传输文件建议使用WinSCP。更详细的操作建议自行网上搜索教程。&lt;/p&gt;
&lt;p&gt;对于Shadowsocks协议，建议使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocks/shadowsocks-rust&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;shadowsocks-rust&lt;/a&gt;，也可使用V2ray-core或者Xray-core。&lt;/p&gt;
&lt;p&gt;对于Vless/Vmess，建议使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/xtls/xray-core&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Xray-core&lt;/a&gt; 做服务端软件（&lt;a class=&#34;link&#34; href=&#34;https://xtls.github.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用文档&lt;/a&gt;）。&lt;/p&gt;
&lt;p&gt;对于Tailscale+Wireguard，可以看 “自有硬件” 部分。&lt;/p&gt;
&lt;p&gt;如果你嫌手撸配置文件太麻烦，而不需要在服务器搭建其他东西，可以在网络上搜索一键脚本安装；对Vless/Vmess，还可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/vaxilu/x-ui&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;x-ui&lt;/a&gt; 来简化操作，提供了较高的自由度和简化的GUI界面。&lt;/p&gt;
&lt;p&gt;端口号建议随意填写， 但如果你后面选择手动导入配置而不是导入protocol:// 链接，一定要确保参数的前后一致。&lt;/p&gt;
&lt;p&gt;然后使用各服务端的链接导出功能导出服务器链接配置，先将其导入手机或电脑上的客户端测试连接。&lt;/p&gt;
&lt;p&gt;客户端方面，如果你使用Vless/Vmess，Android端推荐 &lt;a class=&#34;link&#34; href=&#34;https://play.google.com/store/apps/details?id=com.v2ray.ang&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;v2rayNG&lt;/a&gt; 或AnXray，iOS/iPadOS端推荐&lt;a class=&#34;link&#34; href=&#34;https://apps.apple.com/us/app/shadowrocket/id932747118&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Shadowrocket&lt;/a&gt;（国区没有）和QuantumIt X（国区也没有，又叫圈X，复杂），Windows可以使用v2rayN；对Shadowsocks/R，Windows端可以用&lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocksrr/shadowsocksr-csharp/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ShadowsocksR&lt;/a&gt;（兼容SS/SSR）、v2rayN和&lt;a class=&#34;link&#34; href=&#34;https://github.com/shadowsocks/shadowsocks-windows&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Shadowsocks&lt;/a&gt;（只有SS），Android和iOS同上。注意按照服务端对应安装客户端。&lt;/p&gt;
&lt;p&gt;导入链接后，设定全局代理，启动服务器连接，使用 &lt;a class=&#34;link&#34; href=&#34;https://test-ipv6.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IPv6 测试 (test-ipv6.com)&lt;/a&gt; 检查IP地址是否改变，如果你的代理服务器在境外还可以打开Google检查。如果正常，确保客户端机器有IPv6环境的情况下（可以使用上面的网站确定，移动数据网络一般都有），将客户端中服务器配置的地址栏换成IPv6地址，再次连接测试。&lt;/p&gt;
&lt;h3 id=&#34;自有硬件&#34;&gt;自有硬件
&lt;/h3&gt;&lt;p&gt;使用自己的硬件有两种方法。一条路是使用Tailscale实现点对点连接。个人没有实测过，但这是配置最简单的一种方法。&lt;/p&gt;
&lt;p&gt;方法很简单，打开 &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://tailscale.com/&lt;/a&gt;，它就会给你安装指引。&lt;/p&gt;
&lt;p&gt;而另一条路，就是使用自己的硬件搭建代理服务器。这条路虽然也不用租云主机，但难度很大，还不一定能省钱，首先当然要确定你自己家里之类地方的网络环境有IPv6。&lt;/p&gt;
&lt;p&gt;个人推荐使用能够刷入第三方固件的路由器，它们常带有SSR或v2ray服务端，开启后能够直接连接，不需要做端口转发。如下图为路由器Padavan系统的SSR服务端界面。如果没有的话，也可以使用Linux系统的X86 PC机，性能更强。如果用旧手机、树莓派等ARM设备，配置将会非常麻烦，不建议使用。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-zoom-src=&#34;https://cloudreve-4976k5p3pchqsw.oss-cn-qingdao.aliyuncs.com/blog/681-ipv6TrafficFree/ss-server.avif&#34; src=&#34;https://cloudreve-4976k5p3pchqsw.oss-cn-qingdao.aliyuncs.com/blog/681-ipv6TrafficFree/ss-server.avif&#34; loading=&#34;lazy&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;电脑作为服务端的配置方法其实和上面的大同小异，而路由器端可能更加简单，使用自带的服务端程序解决。&lt;/p&gt;
&lt;p&gt;IPv6一般会是公网地址（即只属于你），但考虑到可能会动态分配，最好买一个域名，搞一个DDNS，动态解析域名到你的服务端。&lt;/p&gt;
&lt;p&gt;配置完成后，参照云主机部分的测试方式进行连接测试。&lt;/p&gt;
&lt;h3 id=&#34;机场&#34;&gt;机场
&lt;/h3&gt;&lt;p&gt;机场的线路一般用于你懂的用途，但如果有IPv6的话，也可以选择。不过请注意监管风险。&lt;/p&gt;
&lt;p&gt;机场可能会给Clash订阅链接，关于Clash的使用请自行搜索，与上面提到的有些许不同。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;如果上面的步骤都成功的话，你实际上就可以进行一定程度上的免流了。电脑连接上校园网，打开上面所说的客户端，选择全局代理（或者配合Proxifier实现更完全的代理），即可绕过计费。可以下载一个大文件试试是否没有记流量。Android设备需要一定的操作来伪装成电脑的MAC地址以获得IPv6地址，而iPhone或者iPad用户由于Apple的限制，并不能搞定，还需要看下一部分。&lt;/p&gt;
&lt;h2 id=&#34;配置路由器&#34;&gt;配置路由器
&lt;/h2&gt;&lt;p&gt;这部分的目的，是在宿舍内构建一个完全走代理的网络，还可以让不能走验证的设备（如智能家居）连上网，以及建设一个可以相互通信的局域网环境。&lt;/p&gt;
&lt;p&gt;我使用的路由器是小米AC2100，刷入Padavan固件，以下都以此为例。如果不确定哪些路由器适合你，可以直接选择 &lt;a class=&#34;link&#34; href=&#34;https://www.right.com.cn/forum/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;恩山无线论坛&lt;/a&gt; 上热门的路由器，它们的第三方固件较多，选择余地较大。&lt;/p&gt;
&lt;p&gt;后面对路由器做的所有更改，&lt;strong&gt;都要点击离选项下方最近的那个“应用本页面设置”才能生效。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;刷入第三方固件&#34;&gt;刷入第三方固件
&lt;/h3&gt;&lt;p&gt;官方固件当然不会拥有SSR这类功能，也没有我们迫切需要的无线桥接功能。&lt;/p&gt;
&lt;p&gt;如果你也选择了这款路由器，或是换壳型号红米AC2100，可以参考一下 &lt;a class=&#34;link&#34; href=&#34;https://www.right.com.cn/forum/forum.php?mod=viewthread&amp;amp;tid=4054150&amp;amp;extra=page%3D1%26filter%3Dtypeid%26typeid%3D43&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;红米 (小米) AC2100 无需 Telnet 刷入 Breed 和 Padavan 固件教程&lt;/a&gt;。Breed方便刷固件翻车时恢复，也为我们提供了改MAC的功能；而Padavan则有大量我们需要或不需要的扩展功能，甚至还可以增强信号的稳定性。&lt;/p&gt;
&lt;h3 id=&#34;连接无线桥接&#34;&gt;连接无线桥接
&lt;/h3&gt;&lt;p&gt;宿舍里没有连至校园网的网口，所以我们需要使用无线桥接功能，将路由器作为一个设备连接至校园网AP。在路由器管理后台连接页面打开 “无线桥接”，按照如下的方式配置，点击应用本页面设置，然后回到网络地图 - 外部网络状态，就可以检查路由器是否连接到了校园网，这一步一般没问题。用手机连上路由器网络，过一下校园网验证确认能够使用。这时可以访问上面提到的IPv6测试网站，如果你碰巧有了IPv6，恭喜你，下一步可以跳过了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing-2/wifi-bridge.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;WiFi 桥接&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;需要注意，2.4GHz现在先不开，也不要配置宽带连接之类的其他东西。&lt;/p&gt;
&lt;h3 id=&#34;获取ipv6地址&#34;&gt;获取IPv6地址
&lt;/h3&gt;&lt;p&gt;这一步非常繁琐，但却是至关重要的一步。&lt;/p&gt;
&lt;p&gt;打开”高级设置 - 外部网络 - IPv6设置 “，如图调整各选项。其中DNSv6没必要非得按这个来，可以自行寻找DNSv6服务器。” 获取IPv6外网地址 “一定要选” 从两端“。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing-2/ipv6-settings.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;IPv6 设置&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;然后到高级设置 - 系统管理 - 服务，打开 “启用NAPT66” 然后重启路由器。&lt;/p&gt;
&lt;p&gt;断开路由器电源，用网线连接LAN口和电脑，按住重置键，接通电源，直到路由器指示灯闪烁，松开重置键。在电脑地址栏输入192.168.1.1进入Breed恢复控制台，点进MAC地址修改，将所有MAC地址均换为某一电脑厂商对应前缀的MAC地址（一般属于CLEVO的前缀，即0090F5比较保险，CLEVO是神舟电脑的代工厂；你可以使用我写的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/cyp0633/MAC-Generator&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MAC 地址生成器&lt;/a&gt;，须自备Python环境）。保存，重启路由器。&lt;/p&gt;
&lt;p&gt;将你的设备连上路由器，测试一下IPv6连接状况（尤其是非电脑设备），现在你的路由器应该已经伪装成了一台电脑，可以获取校园网IPv6了。&lt;/p&gt;
&lt;h3 id=&#34;连接代理服务器&#34;&gt;连接代理服务器
&lt;/h3&gt;&lt;p&gt;这一部分要和你之前 “配置代理服务器” 部分的内容相匹配。&lt;/p&gt;
&lt;h4 id=&#34;padavan固件&#34;&gt;Padavan固件
&lt;/h4&gt;&lt;p&gt;SSR：使用扩展功能 - Shadowsocks，工作模式选择全局代理，其余根据你的服务器配置填写。&lt;/p&gt;
&lt;p&gt;其他：使用扩展功能 - 搭建网络环境 - V2ray。透明代理可以不开这里的，使用广告屏蔽功能 - transocks的透明代理程序，工作模式也要选全局。&lt;/p&gt;
&lt;h4 id=&#34;openwrt&#34;&gt;OpenWrt
&lt;/h4&gt;&lt;p&gt;可以使用PassWall程序，需要手动开启IPv6路由（小心开了上不了网）。&lt;/p&gt;
&lt;p&gt;到这里，校园网免流基本就能达成了。Enjoy it!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;参考文献：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/91901946&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;校园网路由器后设备使用 ipv6 经验分享&lt;/a&gt; – 知乎&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.right.com.cn/forum/thread-473835-1-1.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;h 大老毛子 ipv6 的 wan 口地址获取不到&lt;/a&gt; – 恩山无线论坛&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;另外也可以尝试 “53端口免流”，通过DNS的端口代理，一般来说DNS查询不会被封禁。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>用 FRP 内网穿透，随时随地远程连接</title>
        <link>https://cyp0633.com/post/frp-remote-access/</link>
        <pubDate>Thu, 01 Jul 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/frp-remote-access/</guid>
        <description>&lt;p&gt;谁都不想天天带着厚重的游戏本出去，更何况某些高性能的服务器或者台式机等设备根本带不出去，于是有了远程桌面和SSH之类功能，前者在远程设备中连接另一台Windows电脑的桌面，后者则访问另一台电脑的终端命令行。&lt;/p&gt;
&lt;p&gt;但是，中国的网络环境大家都懂的，大部分电脑都没有公网IP，对于既有移动需求又有远程桌面需求的电脑来说，IP也时常会变换。能不能有一个有固定公网IP的云主机，来作为中转，将流量转到被连接的主机上呢？&lt;/p&gt;
&lt;p&gt;于是我们有了FRP。FRP可以进行内网穿透，具体来讲，就是我们上面所说的事情。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/fatedier/frp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;fatedier/frp&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-zoom-src=&#34;https://github.com/fatedier/frp/blob/dev/doc/pic/architecture.png?raw=true&#34; src=&#34;https://github.com/fatedier/frp/blob/dev/doc/pic/architecture.png?raw=true&#34; loading=&#34;lazy&#34;  alt=&#34;FRP 原理图&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;FRP由两部分组成，分别是服务端和客户端，前者是有公网IP的那台机器，后者是由于各种原因需要被穿透的那台机器。&lt;/p&gt;
&lt;p&gt;在看下面的内容之前，建议先了解一下 &lt;a class=&#34;link&#34; href=&#34;https://baike.baidu.com/item/%E7%AB%AF%E5%8F%A3%E5%8F%B7&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;端口号&lt;/a&gt; 的概念。&lt;/p&gt;
&lt;h2 id=&#34;搭建frp服务端&#34;&gt;搭建FRP服务端
&lt;/h2&gt;&lt;p&gt;我们需要一台有固定公网IP的机器来搭建FRP，常为云主机。建议选择中国大陆网络连接比较顺畅的服务器，以保证较低的延迟。&lt;/p&gt;
&lt;p&gt;首先从 &lt;a class=&#34;link&#34; href=&#34;https://github.com/fatedier/frp/blob/dev/doc/pic/architecture.png?raw=true&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;FRP release&lt;/a&gt; 页面下载适合你服务端机器的包，一般是amd64，Linux还是Windows依你服务器端的系统决定。解压，然后将它传到你的服务器上；如果你对命令行足够熟悉，也可以直接用 &lt;code&gt;wget&lt;/code&gt; 命令在服务器上下载解压。&lt;/p&gt;
&lt;p&gt;然后，进入FRP的路径，修改frps.ini，基础的结构如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;[common]
bind_port = xxxx # 服务端与客户端之间通信所用的端口
dashboard_port = xxxx # 网页控制台的端口号，你没有域名的话可以使用 “服务器 ip: 这个端口号” 来访问控制台
token = xxxxx # 客户端连接到服务端的密码
dashboard_user = xxxx # 网页控制台的用户名
dashboard_pwd = xxxx # 网页控制台的密码
vhost_http_port = xxxx # HTTP 协议端口
vhost_https_port = xxxx # HTTPS 协议端口&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[common]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;bind_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # 服务端与客户端之间通信所用的端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;dashboard_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # 网页控制台的端口号，你没有域名的话可以使用 “服务器 ip: 这个端口号” 来访问控制台&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxxx # 客户端连接到服务端的密码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;dashboard_user&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # 网页控制台的用户名&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;dashboard_pwd&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # 网页控制台的密码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;vhost_http_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # HTTP 协议端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;vhost_https_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # HTTPS 协议端口&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;server_port是服务端与客户端通信使用的端口，而下一部分提到的remote_port是外界连接至服务端的哪个端口，相当于连接到客户端的local_port。&lt;/p&gt;
&lt;p&gt;按需设置即可，注意端口不要冲突了。这些数字可能都会用到，也别忘了。完成之后，输入命令 &lt;code&gt;./frps -s frps.ini&lt;/code&gt; 来启动服务端。推荐使用nohup命令来实现后台运行：&lt;code&gt;nohup ./frps -s frps.ini $&lt;/code&gt;。不会有人用Windows Server吧？&lt;/p&gt;
&lt;p&gt;搭建完成之后，访问 “你的服务器IP: 控制台端口号” 来访问网页控制台，并用先前设置的控制台用户名和密码登录，这里你就可以看到你的FRP服务器信息了。&lt;/p&gt;
&lt;p&gt;此外，你也可以使用 &lt;a class=&#34;link&#34; href=&#34;https://www.natfrp.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Sakura Frp&lt;/a&gt;，它是预先搭建好的一系列FRP服务器，你可以免费使用，但它的带宽等有一定的限制，如果想追求更好的体验，最好还是自行使用国内的服务器搭建。&lt;/p&gt;
&lt;h2 id=&#34;搭建frp客户端&#34;&gt;搭建FRP客户端
&lt;/h2&gt;&lt;p&gt;由客户端决定要和FRP服务端建立几个连接，各个连接分别转发哪个端口，以及应该如何转发。&lt;/p&gt;
&lt;p&gt;在将任何东西暴露于公网之前，我建议：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;做好适当的防护措施，防止攻击；&lt;/li&gt;
&lt;li&gt;先在局域网下测试连接通过，排除客户端本身设置问题造成的麻烦。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;仍然是从上面的release页面下载对应于你客户端机器系统的压缩包，客户端和服务端是同包的。解压之后编辑frpc.ini，基本结构如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;[common]
server_addr = xxx # 你服务端的地址，可以用域名或者 IP 地址，这里不加端口号。
server_port = xxx # 服务端与客户端通信所用的端口号
token = xxx # 客户端连接到服务端的密码

[xxx] # 这一套配置文件的名称，可以自定义，一套配置文件建立一个连接，一个 ini 可以有多套
type = tcp # 通信所用的协议，支持 TCP、UDP、HTTP、HTTPS 等协议的转发，要与实际通信协议配套
local_ip = 127.0.0.1 # 本地需要暴露到互联网上的 IP 地址，理论上也可以是同一个局域网的，本机的话就是 127.0.0.1 或者 localhost
local_port = xxx # 本地需要暴露到互联网上的端口号
remote_port = xxx # 服务端可以将什么端口映射为你本地的端口
use_compression = xxx # 是否启用压缩，值为 true 或者 false，启用则占用两边 CPU 资源
use_encryption = xxx # 是否加密，同上&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;[common]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;server_addr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 你服务端的地址，可以用域名或者 IP 地址，这里不加端口号。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;server_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 服务端与客户端通信所用的端口号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 客户端连接到服务端的密码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;[xxx] # 这一套配置文件的名称，可以自定义，一套配置文件建立一个连接，一个 ini 可以有多套&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;tcp # 通信所用的协议，支持 TCP、UDP、HTTP、HTTPS 等协议的转发，要与实际通信协议配套&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;local_ip&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;127.0.0.1 # 本地需要暴露到互联网上的 IP 地址，理论上也可以是同一个局域网的，本机的话就是 127.0.0.1 或者 localhost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;local_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 本地需要暴露到互联网上的端口号&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;remote_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 服务端可以将什么端口映射为你本地的端口&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;use_compression&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 是否启用压缩，值为 true 或者 false，启用则占用两边 CPU 资源&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;use_encryption&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx # 是否加密，同上&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;更详细的配置可以参考文末附录的官方文档。然后输入命令 &lt;code&gt;./frpc -c frpc.ini&lt;/code&gt;，就可以启动客户端服务了。&lt;/p&gt;
&lt;p&gt;你可以打开上述的服务端网页控制台，来检查一下连接是否成功。&lt;/p&gt;
&lt;h3 id=&#34;windows系统的特别提示&#34;&gt;Windows系统的特别提示
&lt;/h3&gt;&lt;p&gt;鉴于很多人使用的是Windows系统，这里特别提醒一下：需要使用cmd或者PowerShell等终端来启动，不能直接双击frpc.exe，并且命令窗口关闭之后就会停止运行。&lt;/p&gt;
&lt;p&gt;那么怎么去除碍眼的命令行，还让它一直后台运行呢？少数派的文章中提出，可以写一个batch脚本，来实现这个效果：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bat&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;@echo off
if &amp;#34;%1&amp;#34; == &amp;#34;h&amp;#34; goto begin
mshta vbscript:createobject(&amp;#34;wscript.shell&amp;#34;).run(&amp;#34;&amp;#34;&amp;#34;%~nx0&amp;#34;&amp;#34;h&amp;#34;,0)(window.close)&amp;amp;&amp;amp;exit
:begin
cd X:\xxx rem 这个路径改为 frpc.exe 的位置
frpc -c frpc.ini
exit&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bat&#34; data-lang=&#34;bat&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; off
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%1&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;h&amp;#34;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;goto&lt;/span&gt; &lt;span class=&#34;nl&#34;&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mshta vbscript:createobject(&lt;span class=&#34;s2&#34;&gt;&amp;#34;wscript.shell&amp;#34;&lt;/span&gt;).run(&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;%~nx0&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&amp;#34;h&amp;#34;&lt;/span&gt;,0)(window.close)&lt;span class=&#34;p&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nl&#34;&gt;begin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;cd&lt;/span&gt; X:\xxx rem 这个路径改为 frpc.exe 的位置
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;frpc -c frpc.ini
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;exit&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;如果你没有Visual Studio Code等代码编辑器，你也可以将这段内容复制到记事本里，另存为一个文本文档，然后将文件扩展名改成. bat，是一样的效果。&lt;/p&gt;
&lt;p&gt;现在，双击这个bat文件，就可以启动后台服务了；在任务管理器中找到frpc.exe，结束它，就能将它关闭。你还可以使用 “计划任务” 功能实现FRP的开机启动。至于Linux用户，这些步骤大同小异，请参考上一节的nohup命令。&lt;/p&gt;
&lt;h3 id=&#34;远程连接wsl-2子系统&#34;&gt;远程连接WSL 2子系统
&lt;/h3&gt;&lt;p&gt;正如我开头提到的，相信很多人都拥有高性能但不太好移动的计算机，而为了方便日常生产生活，这台计算机常装有Windows系统。有些工作实在是没必要用远程桌面完成，只需要SSH连接终端就可以了，这时使用SSH连接WSL子系统内的Linux bash终端，就可以随时轻易利用强大的算力了。下面以Windows 10 21H1上的Ubuntu 20.04.2 LTS为例。&lt;/p&gt;
&lt;p&gt;需要特别注意的是，WSL2系统本身是并不能直接SSH连接的。要解决这个问题，首先要重装一个 “正常的”OpenSSH”：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;sudo apt-get remove openssh-server
sudo apt-get install openssh-server&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get remove openssh-server
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt-get install openssh-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后还需要编辑一下sshd_config文件，使其允许使用密码接入SSH，当然如果你能够把所有设备的公钥全都加进去，倒也可以不用用户名和密码…… 毕竟这是要暴露到公网上的东西，我甚至更推荐使用RSA公钥验证。&lt;/p&gt;
&lt;p&gt;如果你需要密码登录，则用sudo提权后使用文本编辑器编辑 &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; 文件。我这里推荐使用Visual Studio Code（前面加code或者code-insiders，需要Windows宿主系统上装有vscode），或者GNU Nano（前面加nano），当然如果你是大佬也可以用Vim之类的工具。打开之后，将PasswordAuthentication后面的no改为yes即可。&lt;/p&gt;
&lt;p&gt;然后下载Linux AMD64版本的FRP包，修改frpc.ini如下：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;ini&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;[common] # 这个和上面同理
server_addr = xxx
server_port = xxx
token = xxx

[WSL_ssh] # 这个名称可以自定义
type = tcp # SSH 协议建立在 TCP 的基础上，所以填 TCP
local_ip = 127.0.0.1
local_port = 22 # 本地 SSH 端口默认为 22，当然你可以改，也建议改一下，记得同步修改 SSH 配置
remote_port = xxxx # 服务端映射的端口&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-ini&#34; data-lang=&#34;ini&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;[common] # 这个和上面同理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;server_addr&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;server_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;token&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxx&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;[WSL_ssh] # 这个名称可以自定义&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;type&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;tcp # SSH 协议建立在 TCP 的基础上，所以填 TCP&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;local_ip&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;127.0.0.1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;local_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;22 # 本地 SSH 端口默认为 22，当然你可以改，也建议改一下，记得同步修改 SSH 配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;remote_port&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;xxxx # 服务端映射的端口&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;运行服务，你就可以远程连接到WSL 2了，注意端口号的变化。使用命令 &lt;code&gt;ssh -oPort=remote_port user@server_addr&lt;/code&gt; 来连接客户端的SSH。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;ref.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://sspai.com/post/52523&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用 frp 进行内网穿透 - 少数派 (sspai.com)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://gofrp.org/docs/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;文档 | frp (gofrp.org)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.jianshu.com/p/cd4d604e0b44&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用 ssh 工具连接到 ubuntu on windows（wsl） - 简书 (jianshu.com)&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Windows 11 21996 泄露版本体验</title>
        <link>https://cyp0633.com/post/windows-11-21996-leaked/</link>
        <pubDate>Wed, 16 Jun 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/windows-11-21996-leaked/</guid>
        <description>&lt;p&gt;6月15日晚间，疑似百度贴吧一个人放出了自称为Windows 11的截图，然后今早一觉醒来竟然出现了Dev版本的ISO镜像。当然是直接装进虚拟机啊。&lt;/p&gt;
&lt;p&gt;提醒：&lt;strong&gt;此Windows内部版本仅作尝鲜之用，不建议日用，更不建议长期使用！&lt;/strong&gt; 使用时建议退出Microsoft账号，防止可能存在的追查！&lt;/p&gt;
&lt;p&gt;下面所指的Windows 10，指的都是build 19043。&lt;/p&gt;
&lt;h2 id=&#34;安装引导&#34;&gt;安装引导
&lt;/h2&gt;&lt;p&gt;从ISO启动画面仍然是从Windows Vista沿用至今的画面，值得注意的是这次安装时没有中文可选，而且安装速度似乎得到了大幅提升。&lt;/p&gt;
&lt;p&gt;但是此后，安装引导画面就焕然一新了。&lt;/p&gt;
&lt;p&gt;首先映入眼帘的…… 是一个方形的Windows logo。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/startup.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;开机画面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这个logo很明显已经经过了Fluent Design重新设计，因而具有了一丢丢光影效果，但这未免也太像巨硬四色logo了吧？&lt;/p&gt;
&lt;p&gt;然后是开机引导OOBE环节，灵动的Fluent Design取代了以前的大色块，看起来更加的活泼。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/oobe1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OOBE 1&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/oobe2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OOBE 2&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/oobe3.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OOBE 3&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/oobe4.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OOBE 4&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/oobe5.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OOBE 5&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后则是传统的坐和放宽环节，这次的背景不再是满屏渐变颜色，取而代之的是灯光一样的光效。这里的速度似乎也比之前快了不少，确实只有a few minutes。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/finish-setup.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;完成安装&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;外观交互&#34;&gt;外观交互
&lt;/h2&gt;&lt;p&gt;Windows 11最直观的改变应该就是外观的体验了。这次的外观改进，是近几年来最彻底的一次，将日常使用的地方基本都Fluent化了，即使没啥好改的也改了改，起码让你感受到它改了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/desktop.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Windows 11 桌面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;桌面任务栏与通知中心&#34;&gt;桌面、任务栏与通知中心
&lt;/h3&gt;&lt;p&gt;任务栏基本重做，更加的果里果气（划掉）最近任务居中了，而开始、搜索和最近任务则换了个图标继续出现。值得注意的是，这次新增了Widgets（小部件）按钮，这个东西后面讲。&lt;/p&gt;
&lt;p&gt;任务栏中间的开始、搜索、最近任务和小部件在点击的时候都会出现图标动态动画，而所有图标在点击打开时都会出现一个先缩小再放大的按压动画，最小化时则会向下弹一小段距离再弹回，终于也有了视觉反馈。&lt;/p&gt;
&lt;p&gt;打开新程序时，任务栏上左边的图标都会不同步地往左移，然后新打开窗口的图标出现一个下落的动画。&lt;/p&gt;
&lt;p&gt;在任务栏上右键，现在只会出现任务栏设置，不会出现Windows 10中的繁多选项。而这些设置，必须在Windows徽标上右键，才可以触发；这就是以前Win+X触发的菜单。这里，以前选项名后面所带的字母似乎已经消失，因此我们也不能再使用键盘快捷键打开里面的选项。&lt;/p&gt;
&lt;p&gt;Win+X的右键菜单加入了高斯模糊效果，但似乎并不是所有地方都有…… 或者说，我并没有发现第二个地方有高斯模糊。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/win-x-blur.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Win&amp;#43;X&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;它的深色模式适配似乎更漂亮。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/win-x-dark.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Win&amp;#43;X 深色&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;任务栏中的窗口是否打开，现在也可由图标下方的短线长短和颜色来区分。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/taskbar.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;新任务栏&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;还有一个非常小的细节：任务栏的日历窗口，时间使用了新的字体。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/windows-10-calendar.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Windows 10&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/windows-11-calendar.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Windows 11&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;话说，默认的桌面壁纸似乎还挺好看？&lt;/p&gt;
&lt;p&gt;桌面其实并没有什么大改，如果硬要说有改动，就是桌面右键菜单有了圆角。&lt;/p&gt;
&lt;p&gt;通知中心…… 也加了圆角。还有新绘制的简笔画Fluent图标。别的似乎并没有什么大改动？好吧，换图标本来就是对微软来说的大改动。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/notification-center.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;新通知中心&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;窗口&#34;&gt;窗口
&lt;/h3&gt;&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/new-window.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;新版窗口&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;新版的窗口加入了大量的圆角元素（是的，又是圆角），还增加了文件夹按钮之间的间距，这使得触摸操作误触的可能性更加小了。&lt;/p&gt;
&lt;p&gt;窗口的开关，过渡动画相比Windows 10更加流畅舒服。从任务栏的呼出和最小化，将淡入淡出的效果基本隐去，从而更好地表现出窗体运动的轨迹；而关闭窗口操作，将淡出效果的持续时间变长，动画更加明显。实际上说白了还是以前那套动画效果，但现在这么一微调看起来就是舒适多了。&lt;/p&gt;
&lt;p&gt;字体渲染似乎也迎来了一定的改进，可以对比一下下文中cinebench的截图中的英文文字。&lt;/p&gt;
&lt;p&gt;系统默认的许多控件重做，按钮、复选框等控件更加果里果气，而滚动条…… 这又是从哪儿来的创意啊喂！&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/new-controls.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;新控件&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;以及…… 还是没对齐。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/text-alignment.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;文字对齐&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;开始菜单&#34;&gt;开始菜单
&lt;/h3&gt;&lt;p&gt;先亮明观点：我不喜欢新版开始菜单。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/start-menu.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Windows 11 新版开始菜单&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;旧的磁贴多么漂亮实用，微软咔一下，手起刀落，直接砍掉，变成了毫无特色的图标栏。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/applist.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;所有应用&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;“所有应用” 页面的效率也限制为一列，在大屏上的效率简直低到令人发指。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/windows10-start-menu.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Windows 10，使用全屏开始屏幕模式&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Pinned和Recommended分别是固定在开始菜单的图标和提供的应用建议。相比Windows 10最大可扩展至整屏的开始屏幕，Windows 11的小不点开始菜单明显更加局促；一页可放置的图标变少，图标大小不可变，也使得人们不能像以前一样根据使用频率，来调整磁贴的大小，使它们更显眼；能够将图标充满整个磁贴，从而使用突出的主题色先大致确定图标位置的优势，也一去不复返了。关于如何自定义磁贴，你可以参考 &lt;a class=&#34;link&#34; href=&#34;http://cyp0633.icu/archives/248&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;我写的这篇文章&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;新版Windows搜索，我觉得则没那么容易评价。如果你从开始菜单通过直接输入关键字召唤它，它经常会丢掉开始的几个字符，比如我直接在开始菜单输入Windows 11，转为搜索后就吞掉了最前面的2个字母，而在Windows 10上，这个问题是不存在的。&lt;/p&gt;
&lt;p&gt;不过界面似乎有所改观，这个我觉得可以给好评。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/windows-search.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;新搜索&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h3 id=&#34;图标&#34;&gt;图标
&lt;/h3&gt;&lt;p&gt;别看我只写了这么几个字，图标在我看来却是Windows 11最震撼人心的更新，对，就是最震撼人心的。因为我在以前，从来没有见过微软在换了整体设计风格之后，图标能够立刻跟上更换；甚至对于Office，换Fluent风格图标已经是大更新了。&lt;/p&gt;
&lt;p&gt;从前面的几节中，你大概已经初见端倪，文件夹图标已经焕然一新。这次基本将所有地方都Fluent化，提供了比较一致的视觉体验。&lt;/p&gt;
&lt;h2 id=&#34;新功能&#34;&gt;新功能
&lt;/h2&gt;&lt;h3 id=&#34;小部件widgets&#34;&gt;小部件（Widgets）
&lt;/h3&gt;&lt;p&gt;点击Widget按钮，左边弹出一个Microsoft Timeline栏，里面显示了一些新闻Feed流，和本地天气等信息，比较像Windows 10近些天更新的任务栏右下角资讯功能。&lt;/p&gt;
&lt;p&gt;我比较怂，把微软账号给退了，所以就不能使用小部件功能了，也就莫得截图了。&lt;/p&gt;
&lt;h3 id=&#34;windows-terminal与开发&#34;&gt;Windows Terminal与开发
&lt;/h3&gt;&lt;p&gt;Windows 11这次终于将Windows Terminal内置进系统，在各级目录右键即可打开，对开发的友好程度大幅提升。当然，指望微软把Visual Studio Code整合进去就不太现实了……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/windows-terminal.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;上 10 下 11&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这里的字体渲染似乎也有所不同，当然也可能又是中英文的原因。&lt;/p&gt;
&lt;p&gt;但令人匪夷所思的是，它自带的仍然是旧版PowerShell，版本5.1.21996.1，而截至此时PowerShell 7.1.3也已发布。当然我不太懂也没法怎么说。&lt;/p&gt;
&lt;h3 id=&#34;power-automate&#34;&gt;Power Automate
&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://flow.microsoft.com/zh-cn/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Power Automate&lt;/a&gt; 似乎是微软的低代码效率工作解决方案。低代码这个概念炒得挺火的，能够让没有编程基础的人也能更有效率地完成工作，虽然本质上也是编写类似于程序的东西。这次，微软直接将它内置进了系统。我也不会用，我就不过多介绍了，不过我觉得这个是比较有生产力的一个东西。&lt;/p&gt;
&lt;h2 id=&#34;性能&#34;&gt;性能
&lt;/h2&gt;&lt;p&gt;我也没有什么好的性能测试项目，只跑了一个Cinebench R23，结果似乎并不是很令人满意。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/benchmark.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Cinebench R23 成绩&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;我分配了4G内存、16个线程，而同样配置的Win10虚拟机可以达到8113分。当然，这是在虚拟机环境下的测试结果；由于VMware Workstation并未适配Windows 11，测试结果也有可能不准确。&lt;/p&gt;
&lt;p&gt;据其他媒体的测试，Windows 11下对于大小核处理器的支持似乎更加优秀，或许也是为了新款Intel处理器所做的准备。&lt;/p&gt;
&lt;h2 id=&#34;一些缺憾&#34;&gt;一些缺憾
&lt;/h2&gt;&lt;h3 id=&#34;各种风格共存的界面&#34;&gt;各种风格共存的界面
&lt;/h3&gt;&lt;p&gt;Windows 11还是有一些十分令人迷惑的东西，比如，切换本地账户和微软账户的UI仍然是割裂的，一股Metro（Windows 8）风。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/switch-account.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;切换账户&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;其实类似的UI割裂感仍然存在于一些地方。下面这张图真的看得我血压上来了……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/control-panel.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;控制面板&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;不知道多少年代多少风格的杂糅&lt;/p&gt;
&lt;h3 id=&#34;记事本uwp化了但没全uwp化&#34;&gt;记事本：UWP化了，但没全UWP化
&lt;/h3&gt;&lt;p&gt;还有十分诡异的Windows记事本，我甚至不知道它是UWP程序还是桌面程序。&lt;/p&gt;
&lt;p&gt;C:/Windows/notepad.exe的图标，仍然是Windows 7风格，但打开它，状态栏等图标却是Fluent的。从Windows任务管理器中打开文件位置，发现它竟然指向一个UWP应用。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-11-21996-leaked/notepad.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;记事本&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;刚刚那个 / Windows文件夹中的记事本有340K，相比Windows 10的197K，不知道加了什么东西…… 不过可以肯定的是，它现在只是一个UWP应用的跳板。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结
&lt;/h2&gt;&lt;p&gt;需要重申的是，这一版Windows 11是早期内部开发版本，甚至都没有进Dev通道推送给Windows Insiders用户，所以在这个版本的Windows 11中，不可避免地会出现半成品的痕迹，我们并不应该因此来否定整个Windows 11。&lt;/p&gt;
&lt;p&gt;这一版Windows 11，可以看出微软正在下决心让自己有数十年历史的系统更加现代化，至少在外观方面，Windows 11做得比过去数年都更有诚意得多。而现代系统所缺少的小功能，尤其是老对手macOS，和移动端OS如HarmonyOS 2.0以及MIUI等所具有的，Windows一样没有，比如自动深色模式和全局深色模式、完善的高DPI缩放和更好的字体渲染、屏幕时间管理（数字健康）、可遍及几乎所有应用的权限管理（只有Windows Store应用支持部分权限，即使如此桌面应用也只能一起控制开关），还有内置的屏幕色彩管理等等。&lt;/p&gt;
&lt;p&gt;当Windows部门（哦，现在好像合到Azure部门了）沉浸于换UI、砍功能、写bug、改名字带来的成就感时，其他操作系统开发商则一直在努力加强人性化，在UI方面也并未落下。希望这次微软的改变只是一个开始。&lt;/p&gt;
&lt;p&gt;微软曾承诺会建设新的Microsoft Store，这无疑有利于Windows应用生态的收紧，不过我仍然怀疑微软能不能让腾讯、Facebook这样的巨头低头，规规矩矩地存在它该在的目录，干它该干的事。&lt;/p&gt;
&lt;p&gt;我觉得，Windows也许仍然有未来，但这个版本的Windows 11，显然不够未来。&lt;/p&gt;
&lt;p&gt;最后放一个微软在四年前畅想的Fluent Design宣传片。&lt;/p&gt;

&lt;iframe src=&#34;//player.bilibili.com/player.html?aid=15431098&amp;amp;bvid=BV1bx411g7JA&amp;amp;cid=25114145&amp;amp;page=1&#34;scrolling=&#34;no&#34;border=&#34;0&#34;frameborder=&#34;no&#34;framespacing=&#34;0&#34;allowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;

</description>
        </item>
        <item>
        <title>当代大学生如何愉快地刷网课？</title>
        <link>https://cyp0633.com/post/online-course-hack/</link>
        <pubDate>Thu, 27 May 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/online-course-hack/</guid>
        <description>&lt;p&gt;如今的大学生应该都懂刷课的痛吧，不知道什么时候出现了一堆莫名其妙的网课，正常看都不一定能有时间看完，但这网课又偏偏占平时分，咸鱼需要它及格，卷王需要它刷绩点，所以基本是人人都需要刷网课。&lt;/p&gt;
&lt;p&gt;目前看来，刷网课的方式主要有Tampermonkey脚本、Python脚本、Chrome插件等，效率和实现方式各不相同。下面以各个网站为例，讲讲我推荐的几种刷课方式。特定的方式不一定只适用于特定的网站，有很多通用的方法可以都试一下。&lt;/p&gt;
&lt;p&gt;不过这种选题，啥时候没了也说不定，且看且珍惜吧。&lt;/p&gt;
&lt;h2 id=&#34;知到--智慧树---tampermonkey&#34;&gt;知到 / 智慧树 - &lt;strong&gt;Tampermonkey&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;对于这个网课，我一般使用Tampermonkey脚本。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.tampermonkey.net/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tampermonkey&lt;/a&gt;，俗称油猴，是各大主流浏览器上的一个脚本管理器扩展，对Google Chrome、Firefox、Microsoft Edge Chromium、Microsoft Edge Legacy（EdgeHTML）和Safari都有支持，可以在Chrome Web Store等官方应用店下载，各大国产Chromium内核浏览器也可以使用提取的crx文件来安装扩展。它的原理大致是在特定的网页上加载JavaScript，从而实现网页原本不具有的功能。如果觉得它好用，也不妨给它捐助。你也可以使用Violentmonkey和AdGuard等类似的能加载脚本的插件。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;online-course-hack/chrome-web-store.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Chrome Web Store 页面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;安装之后，点击Tampermonkey图标，可以使用 “新建脚本” 来自己写一个脚本，或者在此处粘贴你从GitHub等地获取的脚本，或者使用 “获取脚本” 来从网上直接下载脚本。我建议从 &lt;a class=&#34;link&#34; href=&#34;http://greasyfork.org&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Greasy Fork&lt;/a&gt; 搜索到你需要的脚本，比如直接搜索 “知到” 就可以找到适用于它的脚本，然后点击 “安装此脚本” 即可安装在Tampermonkey中。大部分脚本都遵循一定的开源协议，这意味着你可以随意使用或者修改它的源代码。脚本是只在特定的网站中有效的，Tampermonkey右下角标的数字，就是在这个页面启用的脚本数。点击它，可以控制适用于该页面脚本的开关。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;online-course-hack/tampermonkey.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Tampermonkey 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;我使用的插件能够实现播完自动切换课程，自动1.5倍速，自动静音播放，还可以打开考试之后自动搜题（可以用来赶作业，不过正确率实在变态所以慎用）。值得注意的是，它还有模拟点击延迟的功能，以模拟真正的人工操作。 &lt;a class=&#34;link&#34; href=&#34;https://greasyfork.org/zh-CN/scripts/380506-%E6%99%BA%E6%85%A7%E6%A0%91%E7%BD%91%E8%AF%BE%E5%8A%A9%E6%89%8B&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这是它的 Greasy Fork 链接&lt;/a&gt;。&lt;/p&gt;
&lt;h2 id=&#34;微伴安全微课---python--tampermonkey&#34;&gt;微伴安全微课 - &lt;strong&gt;Python&lt;/strong&gt; + &lt;strong&gt;Tampermonkey&lt;/strong&gt;
&lt;/h2&gt;&lt;p&gt;这似乎是我们每个暑假都必有的网课。它包含大量的JavaScript等元素组成的互动式页面（而不是单纯的视频）。但是它的部分课程有一个弱点：浏览器可以直接发送完成请求，来完成某个课程。所以，对于这部分，我使用Python脚本，直接获取课程列表并发送完成请求，就可以以极快的速度刷完了。&lt;/p&gt;
&lt;p&gt;我这里所说的Python脚本，指的是通过urllib库完成的操作，将自己伪装成一个浏览器，可以跳过某些步骤而直接进行我们想要的操作，因而效率一般非常高。比如这个地方，我们就可以跳过网课的浏览阶段，在获取课程列表、种类列表、课时列表之后，可以得到每个课时的ID，然后将它填进一个JSON文件，将它用一个POST请求发送给完成网课对应的地址，于是服务器就以为我们完成了网课。写过爬虫的应该都明白。还有通过Selenium，操纵一个真正的浏览器完成操作的方式，在此不表（因为我根本不会）。&lt;/p&gt;
&lt;p&gt;当然，不明白也没关系，因为我已经fork了一份别人的代码，做了一些改进，应该可以用了，&lt;a class=&#34;link&#34; href=&#34;http://github.com/cyp0633/AutoWeiBan&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;地址在这里&lt;/a&gt;。经过实测，大概能在五分钟内刷完200 + 节网课。具体使用方法请参照它的GitHub页面和应用内指引。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;online-course-hack/weiban.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;运行截图（敏感信息已打码）&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;刚刚我们提到只有部分课程有此弱点，那其他的课程呢？我摸索了一个下午，由于水平太菜，愣是没有找到它的规律。不过还有一个Tampermonkey插件，它也可以刷这个网课。&lt;a class=&#34;link&#34; href=&#34;https://greasyfork.org/zh-CN/scripts/413752-weiban-mycourse-cn%E5%88%B7%E8%AF%BE%E5%8A%A9%E6%89%8B&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;点击这里转到 Greasy Fork 页面&lt;/a&gt;。它的基本原理也是尝试直接发送完成请求，但是对于不能这么办的课时，你打开后，它会尝试点击屏幕上的按钮，直到提示完成。效率有点低，但是毕竟不用全程都手动点了对吧。&lt;/p&gt;
&lt;p&gt;另外，《新大学英语视听说课程》配套平台 “iSmart” 也可以使用Python脚本刷课。离谱的是，它的答案会传到本地，然后在本地验证正误。可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Mufanc/iSmartAuto2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mufanc/iSmartAuto2&lt;/a&gt; 搭配iSmart客户端的调试模式刷课，该工具还会自动生成学习时间。考虑到这个系统似乎是外包给天学网的，不知道天学网的课程是否能使用相似方法刷。&lt;/p&gt;
&lt;h2 id=&#34;雨课堂试题---浏览器插件&#34;&gt;雨课堂（试题） - 浏览器插件
&lt;/h2&gt;&lt;p&gt;这里我隆重推荐一款网页端的搜题软件，“&lt;a class=&#34;link&#34; href=&#34;http://www.zaixiantiku.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;划词搜题&lt;/a&gt;”，它能搜出绝大部分题目。&lt;/p&gt;
&lt;p&gt;只需要选中你需要搜的题的题干，插件会自动弹出搜题按钮。点击那个按钮，它就会为你找到对应的题目。&lt;/p&gt;
&lt;p&gt;美中不足的是没有解析，毕竟很多时候搜题只是为了想学点知识。&lt;/p&gt;
&lt;h2 id=&#34;中国大学mooc---手机-息屏听剧-功能或android模拟器&#34;&gt;中国大学MOOC - 手机 “息屏听剧” 功能或Android模拟器
&lt;/h2&gt;&lt;p&gt;有一些网课平台的课程，在电脑端需要手动切换课时或者点击播放，而在手机端却可以连续播放。我们利用这一特性，使用手机实现连续听课；考虑到锁屏后容易中断的特性，可以使用机型自带的 “息屏听剧” 等功能，让锁屏时也不停止播放。&lt;/p&gt;
&lt;p&gt;你也可以使用电脑端的Android模拟器，如各种手游模拟器，运行网课应用，就相当于有一部手机在挂网课了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;online-course-hack/background-play.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;后台播放&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;we-learn随行课堂---直接看源代码&#34;&gt;We Learn随行课堂 - 直接看源代码
&lt;/h2&gt;&lt;p&gt;写在最后面是因为这个完全没有技术含量。页面加载后，答案就会直接显示在浏览器DevTools的 “元素” 页面。这证明答案是直接传到本地，然后在本地完成验证的，而且还选了一种十分拙劣的方式。怎么说呢，感觉这个是故意而为之……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;online-course-hack/welearn.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;We Learn 答案直接显示在源代码中，注意红圈&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;对于Chromium内核浏览器，在We Learn学习页面打开Dev Tools（Firefox请自行探索），即可在 “元素” 选项卡找到答案。&lt;/p&gt;
&lt;h2 id=&#34;写在最后&#34;&gt;写在最后
&lt;/h2&gt;&lt;p&gt;使用任何刷课插件都是有风险的，如果老师或者平台愿意查，应该都能查出来，尤其是一秒钟好几节课那种脚本。对于参照本文而产生的任何后果，作者概不负责。&lt;/p&gt;
&lt;p&gt;请认真对待线上考试等严肃场景！只有要求看但实际上也许并不是这么有效的课程，我才推荐使用如此的特殊方法刷课。&lt;/p&gt;
&lt;p&gt;对于大部分网站，Tampermonkey都有脚本支持，但很多年久失修的脚本容易失效，敬请注意。也可以在GitHub搜索网站名，也可能有人会做刷课脚本。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>自定义 Windows 10 开始菜单磁贴</title>
        <link>https://cyp0633.com/post/customize-win10-tile/</link>
        <pubDate>Sat, 01 May 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/customize-win10-tile/</guid>
        <description>&lt;p&gt;众所周知，Windows会为桌面应用程序（即不是从Microsoft Store安装的应用）自动生成磁贴，一般像是这样子。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/steam-original-tile.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Steam 原图标&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Steam默认生成的磁贴&lt;/p&gt;
&lt;p&gt;系统会自动使用快捷方式对应exe的图标，将其安放在磁贴中央一块小区域内，然后在左下角加上快捷方式名称。无疑这是十分丑陋的，左下方的label暂且不说，图标占据了太小的空间，不能一眼就看到，而磁贴的底色也不能随着应用改变，只能是一成不变的灰白色或者灰黑色。&lt;/p&gt;
&lt;p&gt;还能怎么办？当然自己画磁贴，让它看起来更舒服一点了！&lt;/p&gt;
&lt;p&gt;需要用到的工具：&lt;a class=&#34;link&#34; href=&#34;https://forum.xda-developers.com/t/win10tile-native-custom-windows-10-tiles-with-jump-list-and-context-menu.3248677/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MyTile&lt;/a&gt;（也叫Win10Tile）、&lt;a class=&#34;link&#34; href=&#34;https://www.mitec.cz/iconex.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;IconExplorer&lt;/a&gt;、Photoshop（推荐使用，画图倒也行）。这些工具都可以在网上下载到，我放出了前两款的官网链接。&lt;/p&gt;
&lt;p&gt;据说还有一个方案是使用Better StartMenu，但这个App需要后台进程运行，可能占用资源，在此略去不表；而我们所说的方案，不需要后台进程，但是应用更新后需要重新设置。&lt;/p&gt;
&lt;h2 id=&#34;step-1找到应用路径&#34;&gt;Step 1：找到应用路径
&lt;/h2&gt;&lt;p&gt;桌面应用在开始菜单的磁贴，本质上还是它在开始菜单中的快捷方式。所以，要修改磁贴图标，就要从它所对应的快捷方式入手。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/mytile-teaser.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Win10Tile 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在上面的文本框中输入程序名称，就可以搜索开始菜单中符合条件的快捷方式。在下面选择想更改的快捷方式，在Application Target中就可以找到这个快捷方式（也就是某个磁贴）所指向的应用程序路径。&lt;/p&gt;
&lt;p&gt;如果你已经有了做好的图标，你可以直接跳到最后一步；如果没有，那么需要一步一步往下走。&lt;/p&gt;
&lt;h2 id=&#34;step-2提取图标&#34;&gt;Step 2：提取图标
&lt;/h2&gt;&lt;p&gt;将exe文件之前的那一段复制下来，粘贴到Icon Explorer左上角的地址栏中，按回车，如上图就是 “C:\Program Files\Adobe\Adobe Photoshop CS6 (64-bit)”。&lt;/p&gt;
&lt;p&gt;然后选择对应的exe文件，就可以看到exe文件里包含的图标。&lt;/p&gt;
&lt;p&gt;如果地址在C盘且含有 “ProgramData” 目录，那么需要将其粘贴到资源管理器的地址栏，将对应的exe文件复制一份出来，然后再Icon Explorer地址栏中找到你刚刚拷出来的目录。Icon Explorer对原地址没有访问权限，所以并不能直接读取。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/IconExplorer.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Icon Explorer&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Icon Explorer主界面，来自mitec.cz&lt;/p&gt;
&lt;p&gt;在右边的图标列表里，选择最大的那个，最好选择下方有标注PNG的，方便之后编辑。大部分应用应该都能提供32位、256*256的PNG图标。然后将它保存到你能找到的位置。&lt;/p&gt;
&lt;p&gt;如果只有ico，你也可以save as png，但是保存下来的图片可能失真，这时候你需要保存ico，用画图打开，再另存为png格式。&lt;/p&gt;
&lt;h2 id=&#34;step-3修改图标&#34;&gt;Step 3：修改图标
&lt;/h2&gt;&lt;p&gt;我们提取出来的图标大部分奇形怪状，少数规则的也不能适应方磁贴的需要。这时候就需要修改图标。&lt;/p&gt;
&lt;p&gt;对于大部分图标，可以直接加底色，比如BitComet、金山文档、Python和VLC Player。我一般选取整个图标最深的颜色，然后再将其加深一点，作为底色。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/BitComet_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;BitComet&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/python_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Python&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/vlc_0_2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;VLC&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/%E9%87%91%E5%B1%B1%E6%96%87%E6%A1%A3_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;金山文档&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而对于Office系列图标这些周围有阴影的图标，很难使用油漆桶工具涂色。我建议使用PS选择图标区域，用刚刚的办法选取底色，然后反选、填充。近看可能不太完美，但是离远一点基本看不出来。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/EXCEL_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Excel&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/ONRES_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;OneNote&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/POWERPNT_0_6-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;PowerPoint&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/WINWORD_0_6.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Word&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有一些图标带有渐变效果，可以在方形区域内重新绘制渐变，把原画面中的元素重新移到新渐变上去。比如Steam和GitHub Desktop。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/steam_0_5.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Steam&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/GitHubDesktop_0_2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;GitHub Desktop&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有一些图标，用上面的方法并不能处理得十分完美，这时候需要自行便宜行事，比如TIM。我认为这样处理会比较好看。比如Epic Games Store、TIM、Photoshop和Premiere。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/Adobe-Premiere-Pro_0_5.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Premiere Pro&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/EpicGamesLauncher_0_5.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Epic Games Launcher&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/Photoshop_0_3.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Photoshop&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;customize-win10-tile/TIM_0_3-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;TIM&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;step-4更换图标&#34;&gt;Step 4：更换图标
&lt;/h2&gt;&lt;p&gt;这一步最简单，在MyTile内找到你想更改的应用快捷方式，点击Select Image，选择你刚刚编辑的图标，然后点击Save。会自动帮你生成小尺寸图标。&lt;/p&gt;
&lt;p&gt;现在，打开开始菜单，你就可以看到修改后的磁贴样式了。&lt;/p&gt;
&lt;p&gt;谨以此文献给远去的Windows 10，
和灵动的磁贴系统。&lt;/p&gt;
</description>
        </item>
        <item>
        <title>夜间的 Windows，可以更好用</title>
        <link>https://cyp0633.com/post/windows-dark-experience/</link>
        <pubDate>Sat, 20 Mar 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/windows-dark-experience/</guid>
        <description>&lt;p&gt;对于Android与iOS用户来说，深色模式似乎已经是一个司空见惯的功能。苹果的强大号召力令各大应用开发商火速失陪了深色模式，而对于小米和魅族等手机的用户，优秀的系统反色算法使得日常使用的覆盖也没有什么问题。但是对于Windows这一个 “史前” 系统，深色模式并没有那么完善。相比移动端的敏捷，Windows早已落后了太多。&lt;/p&gt;
&lt;p&gt;本文将介绍一些让Windows的深色模式更好用的方法，包括但不限于工具和tips。当然，即使这样也不能让Windows的深色模式体验令人完全满意。&lt;/p&gt;
&lt;h2 id=&#34;windynamicdesktop--晚上就该有晚上的壁纸&#34;&gt;WinDynamicDesktop | 晚上就该有晚上的壁纸
&lt;/h2&gt;&lt;p&gt;苹果设备中，有许多自带壁纸是带有深浅色模式两种版本的，能够完美融合进变暗的系统界面。小米MIUI超级壁纸 “几何” 也有跟随系统深色模式的功能，主要是底色能够跟随变换。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/phone-contrast.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;手机的深色模式&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;更酷的是，macOS从Mojave开始加入了一个特性叫做动态桌面（Dynamic Desktop）。这个功能可以根据一天中的不同时间，自动切换适合的壁纸，以匹配外界环境。也就是说，外面是白天，壁纸也是白天；外面是晚上，壁纸也是晚上。不过，实际上都是静态的壁纸在轮换23333。&lt;/p&gt;
&lt;p&gt;现在，有一位大佬在Windows上实现了类似的功能，软件称为WinDynamicDesktop，可以 &lt;a class=&#34;link&#34; href=&#34;https://github.com/t1m0thyj/WinDynamicDesktop/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在 GitHub 下载&lt;/a&gt;，也可以 &lt;a class=&#34;link&#34; href=&#34;https://www.microsoft.com/store/apps/9nm8n7dq3z5f?cid=storebadge&amp;amp;ocid=badge&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;从 Microsoft Store 下载&lt;/a&gt;。它自带了macOS上的多款高质量动态桌面壁纸，如Mojave Desert、Catalina和Big Sur。这样，你的电脑在晚上就可以换上深色的壁纸，避免刺眼。&lt;/p&gt;
&lt;p&gt;如果你的桌面比较干净，这些由苹果钦定的壁纸也具有非常高的观赏价值。每张壁纸取景的相对位置不变，变的只有晨昏，衔接流畅自然，景色也很美。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/dynamic-desktop.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;动态桌面壁纸&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;windows-auto-dark-mode--系统也要黑下来&#34;&gt;Windows Auto Dark Mode | 系统也要黑下来
&lt;/h2&gt;&lt;p&gt;移动端许多系统都支持日出日落自动切换深色模式，而Windows的所有深色模式设置，却只有一个选项。&lt;/p&gt;
&lt;p&gt;于是就有了Windows Auto Dark Mode这款软件。我推荐 &lt;a class=&#34;link&#34; href=&#34;https://github.com/Armin2208/Windows-Auto-Night-Mode/releases&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;从 GitHub 下载&lt;/a&gt;，或者你也可以利用WinGet命令下载（关于WinGet可以查看 &lt;a class=&#34;link&#34; href=&#34;http://cyp0633.icu/archives/111&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这篇文章&lt;/a&gt;，命令为 &lt;code&gt;winget install &amp;quot;Auto Dark Mode&amp;quot;&lt;/code&gt;）。也可以使用Chocolatey或者Scoop下载，请参看GitHub页面。&lt;/p&gt;
&lt;p&gt;它有丰富的Windows系统与应用深色模式设置，如下图：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/wadm-1.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Auto Dark Mode 1&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/wadm-2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Auto Dark Mode 2&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/wadm-3.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Auto Dark Mode 3&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/wadm-4.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Auto Dark Mode 4&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它使用登录任务代替后台进程，如此就可以少留一个后台了，减少了内存占用，任务栏托盘也更加干净（当然，这么简单的一个小程序的确不应该占用一个托盘）。十分令人惊喜的是，它还支持Connected Standby等现代新特性。如果你不需要花里胡哨的动态壁纸，你也完全可以使用这款应用的” 壁纸 / 主题” 功能来设置切换壁纸。&lt;/p&gt;
&lt;h2 id=&#34;dark-reader--白底网页闪瞎眼赶紧反色保平安&#34;&gt;Dark Reader | 白底网页闪瞎眼，赶紧反色保平安
&lt;/h2&gt;&lt;p&gt;Windows对网页端的依赖，比移动操作系统更大，但是只有GitHub等极少数网页适配了深色模式， 也就是说，你打开的 大部分网页，都能在晚上闪瞎你的眼。正巧，在Windows Auto Dark Mode中发现了一个 &lt;a class=&#34;link&#34; href=&#34;https://github.com/darkreader/darkreader&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Dark Reader&lt;/a&gt;，能够强制网页反色，把大量的亮色块转换为暗色…… 有点像MIUI浏览器的逻辑？&lt;/p&gt;
&lt;p&gt;Dark Reader是一款浏览器插件，支持基于Chromium的浏览器（&lt;a class=&#34;link&#34; href=&#34;https://chrome.google.com/webstore/detail/dark-reader/eimadpbcbfnmbkopoojfekhnkhdbieeh&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Google Chrome&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://microsoftedge.microsoft.com/addons/detail/dark-reader/ifoakfbpdcdoeenechcleahebpibofpc&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;新版 Microsoft Edge&lt;/a&gt;）和 &lt;a class=&#34;link&#34; href=&#34;https://addons.mozilla.org/en-US/firefox/addon/darkreader/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Mozilla Firefox&lt;/a&gt;。此外，它也支持 &lt;a class=&#34;link&#34; href=&#34;https://addons.thunderbird.net/en-US/thunderbird/addon/darkreader&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Thunderbird Mail&lt;/a&gt;，Mozilla的一款邮件客户端。其他基于Chromium的浏览器请自行访问上面两个地址来获取下载链接，可能兼容性不是非常好。&lt;/p&gt;
&lt;p&gt;安装插件后自动弹出 &lt;a class=&#34;link&#34; href=&#34;https://darkreader.org/help/zh-CN/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用方法页面&lt;/a&gt;，在此不再赘述。值得一提的是，它也支持跟随系统的深色模式进行变换。&lt;/p&gt;
&lt;h2 id=&#34;twinkle-tray--这些还不够暗那就让屏幕暗下来&#34;&gt;Twinkle Tray | 这些还不够暗？那就让屏幕暗下来
&lt;/h2&gt;&lt;p&gt;很多时候，光是把屏幕上的内容变成深色，在暗光下的观感仍然很差，原因是屏幕亮度太高，尤其是对于大部分LCD屏用户来说。&lt;/p&gt;
&lt;p&gt;屏幕亮度的调节一直是Windows的老大难问题，除非你只用笔记本的内置屏幕，这样的话Windows通知中心下部的亮度条调节亮度会非常方便。但是，如果你是台式机用户，或者是外接屏幕的笔记本用户，难免需要调节外接显示器的亮度。Twinkle Tray就是这样一款应用，将调节亮度的快捷方式做进系统托盘。&lt;/p&gt;
&lt;p&gt;它使用DDC/CI和WMI协议与显示器通信。大部分显示器与线缆都支持此功能，比如我的飞利浦245E1，但是微软还是没把它做进系统，匪夷所思。&lt;/p&gt;
&lt;p&gt;它可以 &lt;a class=&#34;link&#34; href=&#34;https://www.microsoft.com/store/productId/9PLJWWSV01LK&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在 Microsoft Store 下载&lt;/a&gt;。另外，它的源代码开放在 &lt;a class=&#34;link&#34; href=&#34;https://github.com/xanderfrangos/twinkle-tray&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub&lt;/a&gt; 上。&lt;/p&gt;
&lt;p&gt;警告：这款软件似乎并不完善。我使用这款软件之后，发现笔记本在不外接电源的时候流畅度大幅降低（卸载或关闭之后可以恢复），还有人出现了显示器亮度异常的问题。建议安装之前仔细考虑后果，安装后先设置恢复默认亮度快捷键再调整亮度，以免显示器亮度调节异常。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;windows-dark-experience/twinkletray.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Twinkle Tray 托盘快捷操作&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Windows 的包管理程序，WinGet 简单体验</title>
        <link>https://cyp0633.com/post/winget-the-windows-package-manager/</link>
        <pubDate>Sun, 07 Mar 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/winget-the-windows-package-manager/</guid>
        <description>&lt;p&gt;各家操作系统都有自己的包管理器，能够使用统一的软件源为电脑获取应用。比如Debian的apt，macOS的Homebrew。Windows一直缺少一个广泛使用、功能完备的包管理器，Chocolatey和NuGet也并不是非常完善。终于微软发布了WinGet包管理器，也算是对开发社区更加友好的重要举措。&lt;/p&gt;
&lt;h2 id=&#34;申请winget内测&#34;&gt;申请WinGet内测
&lt;/h2&gt;&lt;p&gt;在写这篇文章的时候，WinGet目前还处于公共预览版阶段，所以需要从 &lt;a class=&#34;link&#34; href=&#34;https://aka.ms/AppInstaller_InsiderProgram&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Windows 程序包管理器预览体验计划&lt;/a&gt; 链接的问卷中填入你的微软账号邮箱。申请通过后会给你发一封邮件，然后你就可以在Microsoft Store中等待包管理器的更新了。但现在WinGet已经公测，也已经随Windows推送。&lt;/p&gt;
&lt;p&gt;如果你不想使用Microsoft Store，你也可以在 &lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/winget-cli/releases/tag/v-0.2.10191-preview&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;GitHub Releases&lt;/a&gt; 下载单独的安装包，或者加入Windows Insider，直接体验测试版的Windows。&lt;/p&gt;
&lt;h2 id=&#34;winget基本操作&#34;&gt;WinGet基本操作
&lt;/h2&gt;&lt;p&gt;WinGet兼容命令提示符，当然也兼容PowerShell。我使用PowerShell 7.1.1 + Windows Terminal来运行。&lt;/p&gt;
&lt;p&gt;以下是winget命令的操作。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/winget-help.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;操作&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;那就来实地操作一下，比如安装个TIM？&lt;/p&gt;
&lt;p&gt;输入&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;powershell&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;winget install TIM&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;winget&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;install&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;TIM&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;来安装TIM。winget会从腾讯的服务器下载最新的安装包，然后静默安装。&lt;/p&gt;
&lt;p&gt;小彩蛋：命令后面加 &amp;ndash;rainbow参数，进度条会变成彩虹色~&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/miuiplus.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;rainbow&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;下载完成后会请求管理员权限，没啥问题，毕竟Linux装个软件还得输sudo不是。&lt;/p&gt;
&lt;p&gt;后面的过程基本是静默安装，只弹出了一个 “TIM正在运行，是否关闭TIM” 的对话框。也没有任何的捆绑插件，十分纯净。&lt;/p&gt;
&lt;p&gt;我又测试了安装华为浏览器，也是静默安装的。这里出现了一个问题：应用名 “Huawei Browser” 有空格，不能被正确识别。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/huawei.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;华为浏览器&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;但是可以使用包名代替：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/huawei_true.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;用包名安装华为浏览器&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;这样就可以正常安装了。&lt;/p&gt;
&lt;p&gt;值得注意的是，这个软件似乎是用户投放的，不属于官方。这个人好像还传了许多奇奇怪怪的软件……&lt;/p&gt;
&lt;h2 id=&#34;关于软件源&#34;&gt;关于软件源
&lt;/h2&gt;&lt;p&gt;Microsoft的初衷是建设一个对开发者更友好的包管理器，但正如你所见，对于一般人来说，WinGet似乎也挺合适。正如上面的测试，TIM这种日常软件也被包含在软件源中。而且绝佳的地方是它没有捆绑，可以免于安装整个全家桶的困扰。&lt;/p&gt;
&lt;p&gt;可以使用winget search命令来搜索软件包。比如搜索xiaomi，出现了MIUI + 客户端。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/xiaomi.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;MIUI&amp;#43;&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;当然，微软自家的应用当然不能落下（虽然不都是微软的应用）：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/microsoft.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Microsoft 的搜索结果&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;搜索Microsoft得到的结果（部分）&lt;/p&gt;
&lt;p&gt;也有其他家的开发工具：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/sublime.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Sublime Text&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Sublime Text&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/clang.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Clang LLVM&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Clang LLVM&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/jre.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;JRE&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Java运行时&lt;/p&gt;
&lt;p&gt;如果你想打会游戏，甚至还有……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/steam.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Steam&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Steam&lt;/p&gt;
&lt;p&gt;软件包管理器的默认软件源架设在Azure上，但软件源的代码GitHub上。如果你发现缺少你的应用，可以在 &lt;a class=&#34;link&#34; href=&#34;https://github.com/microsoft/winget-pkgs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt; 提交Pull Request。也有很多爱好者自行上传的应用。未来也可能会出现第三方软件源。&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://winget.run/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;winget.run&lt;/a&gt; 是更加友好的软件包查找器，似乎与PyPI有点相似？&lt;/p&gt;
&lt;h2 id=&#34;一些缺陷&#34;&gt;一些缺陷
&lt;/h2&gt;&lt;p&gt;某些软件会出现安装失败的现象。比如上文提到的MIUI+，CLI中提示安装失败：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/xiaomi.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;安装失败&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;不光安装失败，还把我之前装的那个版本也整坏了……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;winget-the-windows-package-manager/libpng16.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;安装损坏&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;而且目前对一些我们可能认为理所当然的东西支持还不稳定，甚至…… 卸载。它被划为了实验性功能。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;p&gt;[1] &lt;a class=&#34;link&#34; href=&#34;https://docs.microsoft.com/zh-cn/windows/package-manager/winget/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;使用 winget 工具管理和安装应用程序 | Microsoft Docs&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        <item>
        <title>在 Windows 上用 vscode 进行 C&#43;&#43; 开发</title>
        <link>https://cyp0633.com/post/vscode-cpp-windows/</link>
        <pubDate>Sun, 28 Feb 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/vscode-cpp-windows/</guid>
        <description>&lt;img src="https://cyp0633.com/post/vscode-cpp-windows/vscode-themephoto.png" alt="Featured image of post 在 Windows 上用 vscode 进行 C&#43;&#43; 开发" /&gt;&lt;p&gt;&lt;strong&gt;本文写的内容已经过时。现在（2023年6月），建议选择的编译器是 &lt;a class=&#34;link&#34; href=&#34;https://github.com/mstorsjo/llvm-mingw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;llvm-mingw&lt;/a&gt;，并使用Clangd插件获取C/C++ 支持。mingw-w64较老，不建议使用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;时至今日，许多大学所使用的C++ IDE还是Dev-C++ 和VC++6.0等十分落后的软件，故作此文，以帮助各位使用更加方便易用的C++ 开发环境。&lt;/p&gt;
&lt;h2 id=&#34;为什么要用vscode&#34;&gt;为什么要用vscode？
&lt;/h2&gt;&lt;p&gt;Visual Studio Code是微软出品的一个编辑器，界面美观、打开文件流畅。同时，它具有大量的插件，而大量的插件使它有极高的可扩展性，可用于几乎任何语言的开发，还可以打游戏、听音乐、看PDF。&lt;/p&gt;
&lt;p&gt;作为微软的产品，当家功能IntelliSense必不可少。在你写代码时，它可以自动为你补全函数名、括号、变量名等字段，再也不用因太长的变量名敲起来麻烦而烦躁了。&lt;/p&gt;
&lt;p&gt;同时，它还与WSL（Linux Windows子系统）高度兼容，在Windows环境内编程，在Linux环境下编译与调试。也可以通过SSH直连你的服务器，借用服务器的资源与性能。&lt;/p&gt;
&lt;p&gt;另外，vscode是开源项目，这意味着你甚至可以将它移植，做一个自己的版本出来。&lt;/p&gt;
&lt;h2 id=&#34;安装vscode&#34;&gt;安装vscode
&lt;/h2&gt;&lt;p&gt;我使用的环境是一个虚拟机，8个AMD Zen 2线程、6.5G RAM、外置机械硬盘、Windows 10 x64 20H2 19042.508。理论上只有系统版本会影响一些步骤，但是20H2或者21H1版本所使用的步骤应该基本类似。&lt;/p&gt;
&lt;p&gt;先在 &lt;a class=&#34;link&#34; href=&#34;http://code.visualstudio.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;官方网站&lt;/a&gt; 上点击 “Download for Windows” 按钮下载vscode安装包。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/vscode-themephoto.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;官方网站&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;下载安装包之后安装，建议将如下图的 “添加到PATH” 选中。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/install-vscode.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;安装界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;vscode本体就安装完成了。&lt;/p&gt;
&lt;h2 id=&#34;安装编译器&#34;&gt;安装编译器
&lt;/h2&gt;&lt;p&gt;vscode毕竟只是个编辑器，说白了就是个高级的记事本，想要调试，必须配合插件和编译器。这里讲述如何安装编译器。&lt;/p&gt;
&lt;p&gt;GCC/G++ 编译器是Linux平台上非常流行的C/C++ 编译器，但它与Windows不兼容，于是有人用它的源代码构建了各种Windows变种，功能同样丰富。&lt;/p&gt;
&lt;p&gt;我这里使用mingw-w64，8.1.0版本，以与微软官方教程达到最大匹配。你也可以选择TDM-GCC，基于G++ 9.2，版本更新，但是请自行对照下面的部分修改你的安装路径。&lt;/p&gt;
&lt;p&gt;在 &lt;a class=&#34;link&#34; href=&#34;https://sourceforge.net/projects/mingw-w64/files&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;SourceForge&lt;/a&gt; 下载MinGW-W64-install.exe。也可以下载x86_64-posix-seh包，然后手动按照下面所提到的安装路径解压。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/download-mingw.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;下载 MinGW&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;下载之后打开，然后按照下图选择版本。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/install-mingw.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;安装 MinGW&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;然后点击Next，程序会自动下载在线安装包。在某些网络环境下，下载可能很慢，所以建议留出充足的时间，或者挂VPN下载。&lt;/p&gt;
&lt;p&gt;安装完成之后，打开PowerShell或者CMD，输入g++ -v并回车，检查是否正确显示了G++ 的版本。&lt;/p&gt;
&lt;p&gt;（PS：推荐安装 &lt;a class=&#34;link&#34; href=&#34;https://github.com/PowerShell/PowerShell&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;新版 PowerShell&lt;/a&gt; 和&lt;a class=&#34;link&#34; href=&#34;https://aka.ms/terminal&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Windows Terminal&lt;/a&gt;，更美观，使用起来更有效率。当然，不装也没什么坏处）&lt;/p&gt;
&lt;p&gt;如果出现下图中的情况，则还需要配置环境变量。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/not-in-path.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;不在 PATH&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;如果你的输出类似于下面那样，COLLECT_GCC的路径和gcc version也完全相同，那么可以直接跳过下一步。如果那两项不太一样，也请看下一步。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/in-path.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;在 PATH&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;配置环境变量&#34;&gt;配置环境变量
&lt;/h2&gt;&lt;p&gt;先讲原理。如果我们要调用G++，按理说应该在PowerShell或者CMD中输入完整路径并运行。这样的输出是正确的。（注意语句后面有一个 - v，不太明显）&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/gcc-full-path.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;使用完整路径调用 GCC&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;但每次打命令都需要输命令，那也太麻烦了。而Windows的PATH环境变量能够解决这个问题。加入PATH的目录中的程序使用时，可以将前面的目录省去，直接使用文件名。在调用时，会自动检索PATH文件夹，找到符合这个名字的文件夹并调用。将编译器加入环境变量后，就可以看到上一步最后的效果。&lt;/p&gt;
&lt;p&gt;打开Windows设置 - 系统 - 关于 - 高级系统设置，点击 “环境变量”。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/add-environment-variable.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;高级系统设置&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在弹出窗口中选择PATH。如果你选择 “用户变量“中的PATH，则这个编译器快捷方式只对你一个人有效；否则，就对整个电脑有效。然后点击” 新建“，粘贴g++.exe所在的路径（如果你上面全程按照我的方法安装，则填入C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin）。全都点击确定，如下图。&lt;/p&gt;
&lt;p&gt;如果你之前安装过其他版本G++（包括Dev-C++ 可能附带的），环境变量中出现了那个路径，而又不知道后面该怎么修改，建议将刚刚添加的上移到原有的那一个上方。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/add-environment-variable-2.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;环境变量&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;再输入g++ -v回车，查看效果。&lt;/p&gt;
&lt;h2 id=&#34;安装插件&#34;&gt;安装插件
&lt;/h2&gt;&lt;p&gt;vscode的灵魂就是丰富的插件。刚安装完的vscode是类似于这样的：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/vscode-just-installed.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;全新安装 VS Code&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;对于C++ 编程，我建议下载下面的插件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C/C++&lt;/li&gt;
&lt;li&gt;Chinese (Simpified) Language Pack for Visual Studio Code&lt;/li&gt;
&lt;li&gt;Better C++ Syntax&lt;/li&gt;
&lt;li&gt;C/C++ Themes&lt;/li&gt;
&lt;li&gt;CMake&lt;/li&gt;
&lt;li&gt;CMake Tools&lt;/li&gt;
&lt;li&gt;C++ IntelliSense&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;非必需：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rainbow Brackets&lt;/li&gt;
&lt;li&gt;GitLens - Git supercharged（当你有Git时，没有的话不必要）&lt;/li&gt;
&lt;li&gt;Remote - WSL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安装完成后重启vscode。&lt;/p&gt;
&lt;h2 id=&#34;配置json首选项&#34;&gt;配置JSON首选项
&lt;/h2&gt;&lt;p&gt;在vscode左边的资源管理器中打开一个文件夹，右下角会提示下载一些文件，可以等一下。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;vscode-cpp-windows/vscode-open-folder.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;打开文件夹&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;打开后的文件夹形成了一个工作区。在里面再新建一个名为. vscode的文件夹。然后在文件夹里新建launch.json和tasks.json两个文件。&lt;/p&gt;
&lt;p&gt;在tasks.json中粘贴这段代码：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;version&amp;#34;: &amp;#34;2.0.0&amp;#34;,
  &amp;#34;tasks&amp;#34;: [
    {
      &amp;#34;type&amp;#34;: &amp;#34;shell&amp;#34;,
      &amp;#34;label&amp;#34;: &amp;#34;C/C&amp;#43;&amp;#43;: g&amp;#43;&amp;#43;.exe build active file&amp;#34;,
      &amp;#34;command&amp;#34;: &amp;#34;C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g&amp;#43;&amp;#43;.exe&amp;#34;,
      &amp;#34;args&amp;#34;: [&amp;#34;-g&amp;#34;, &amp;#34;${file}&amp;#34;,&amp;#34;-o&amp;#34;,&amp;#34;${fileDirname}\\${fileBasenameNoExtension}.exe&amp;#34;],
      &amp;#34;options&amp;#34;: {
        &amp;#34;cwd&amp;#34;: &amp;#34;${workspaceFolder}&amp;#34;
      },
      &amp;#34;problemMatcher&amp;#34;: [&amp;#34;$gcc&amp;#34;],
      &amp;#34;group&amp;#34;: {
        &amp;#34;kind&amp;#34;: &amp;#34;build&amp;#34;,
        &amp;#34;isDefault&amp;#34;: true
      }
    }
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;tasks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C/C++: g++.exe build active file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-g&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${file}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-o&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;${fileDirname}\\${fileBasenameNoExtension}.exe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;problemMatcher&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;$gcc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;isDefault&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;在launch.json中粘贴这段代码：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;version&amp;#34;: &amp;#34;0.2.0&amp;#34;,
  &amp;#34;configurations&amp;#34;: [
    {
      &amp;#34;name&amp;#34;: &amp;#34;g&amp;#43;&amp;#43;.exe - Build and debug active file&amp;#34;,
      &amp;#34;type&amp;#34;: &amp;#34;cppdbg&amp;#34;,
      &amp;#34;request&amp;#34;: &amp;#34;launch&amp;#34;,
      &amp;#34;program&amp;#34;: &amp;#34;${fileDirname}\\${fileBasenameNoExtension}.exe&amp;#34;,
      &amp;#34;args&amp;#34;: [],
      &amp;#34;stopAtEntry&amp;#34;: false,
      &amp;#34;cwd&amp;#34;: &amp;#34;${workspaceFolder}&amp;#34;,
      &amp;#34;environment&amp;#34;: [],
      &amp;#34;externalConsole&amp;#34;: false,
      &amp;#34;MIMode&amp;#34;: &amp;#34;gdb&amp;#34;,
      &amp;#34;miDebuggerPath&amp;#34;: &amp;#34;C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\gdb.exe&amp;#34;,
      &amp;#34;setupCommands&amp;#34;: [
        {
          &amp;#34;description&amp;#34;: &amp;#34;Enable pretty-printing for gdb&amp;#34;,
          &amp;#34;text&amp;#34;: &amp;#34;-enable-pretty-printing&amp;#34;,
          &amp;#34;ignoreFailures&amp;#34;: true
        }
      ],
      &amp;#34;preLaunchTask&amp;#34;: &amp;#34;C/C&amp;#43;&amp;#43;: g&amp;#43;&amp;#43;.exe build active file&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;g++.exe - Build and debug active file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cppdbg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;program&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${fileDirname}\\${fileBasenameNoExtension}.exe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;stopAtEntry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;environment&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;externalConsole&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;MIMode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;miDebuggerPath&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C:\\Program Files\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\bin\\gdb.exe&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;setupCommands&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Enable pretty-printing for gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-enable-pretty-printing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;preLaunchTask&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;C/C++: g++.exe build active file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后保存。”.vscode“文件夹保存的是vscode的配置文件，程序不需要存放在这个目录里。&lt;/p&gt;
&lt;h2 id=&#34;vscode使用初步&#34;&gt;vscode使用初步
&lt;/h2&gt;&lt;p&gt;之后，新建一个test.cpp，随便写点啥。如果一切正常的话，这个时候自动补全功能就该生效了。当光标右下方出现自动补全栏的时候，上下方向键选择候选项，按tab自动补全。可以补全的内容包括但不限于函数名、变量名、语句、include文件。&lt;/p&gt;
&lt;p&gt;如果发现代码可能有问题，vscode会自动检测出来，然后显示在底部 “问题” 栏中。&lt;/p&gt;
&lt;p&gt;按下F5，开始调试，这和其他的IDE没什么不同。不过，每次启动vscode之后，第一次调试时，底栏都会自动跳到”调试控制台 “，那是输入GDB命令的地方，如果不需要的话就得手动切换到” 终端“栏。&lt;/p&gt;
&lt;p&gt;vscode的调试输入输出都会放在内置终端中，实际上就是调用了系统的CMD或者PowerShell（也可以自定义终端）。如果你在那里看到了你所期望的输出，那说明你成功了。Enjoy!&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://code.visualstudio.com/docs/cpp/config-mingw&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Get Started with C++ and Mingw-w64 in Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>HNU 校园网 IPv6 免流折腾实录</title>
        <link>https://cyp0633.com/post/hnu-ipv6-bypass-billing/</link>
        <pubDate>Fri, 19 Feb 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/hnu-ipv6-bypass-billing/</guid>
        <description>&lt;p&gt;谨以此文章献给饱受校园网流量不足之苦的同学们。本实录中的步骤仅在HNU校园网环境尝试过复现，其他学校不保证可以使用。同时，理论上也不是每一步都是必要的，仅仅表明这种方法可行。&lt;/p&gt;
&lt;p&gt;绕过校园网流量计费不代表可以不花钱上网。事实上，一台性能还凑合的路由器花了我200元，再加上服务器，每个月也要花费5美元，还有大量的隐性时间成本。一旦校园网开始真的限制40G，这篇文章的意义或许才显现出来；而为了绕过20G以上的收费，40G每个月对你够用的话，并没有必要去大费周章。&lt;/p&gt;
&lt;p&gt;建议有一定玩机基础与一点点网络基础的人仿照着做，或者在熟悉的朋友现场指导与帮助下实施。&lt;strong&gt;博主对可能造成的问题不负责任，请周知。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;由于本文写得实在过于杂乱，现阶段建议去阅读 &lt;a class=&#34;link&#34; href=&#34;https://cyp0633.icu/archives/681&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;HNU 校园网 IPv6 免流教程 2.0&lt;/a&gt;。&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;一&#34;&gt;一
&lt;/h2&gt;&lt;p&gt;2021年新年到了，学校的个人门户也换了一副新的模样。变的不止个人门户，而且还有流量监控页面。&lt;/p&gt;
&lt;p&gt;现在，新版的流量监控可以查看每日流量消耗，甚至上了哪家的网站都能显示出来。缴费页面也出现了前几个月的欠费信息（虽然不能缴费），让人不禁担心随时会开始计费。&lt;/p&gt;
&lt;p&gt;直到某日，某兄透露称，流量计费系统调试好了就会开始工作，我才开始考虑如何搞到更多的流量，毕竟20G每月免费、40G每月封顶，实在是很恶心人，要是天天和宋浩老师一起学习的话怎么受得了啊。&lt;/p&gt;
&lt;p&gt;运营商宽带固然是一个解决办法，但是价格太贵，带宽也并不高，还限制设备，所以它成了我的备选方案，而将重心放在绕开校园网的流量监测上。&lt;/p&gt;
&lt;h2 id=&#34;二&#34;&gt;二
&lt;/h2&gt;&lt;p&gt;阅读一下校园网使用规则，可以很容易地发现IPv6是免流量的。那么我们的思路就确定了：将终端全部连接至IPv6的远程服务器，绕过IPv4，再由服务器代替我们访问外网，再把得到的数据传回来就可以了。虚拟专用网络等方式可以将所有流量加密，通过IPv6传输给远程服务器，这并不影响IPv4资源的访问。只是校内资源，比如抢课，需要把它关掉。&lt;/p&gt;
&lt;p&gt;中国大陆并没有适合的双栈（IPv6+IPv4）VPS提供商，再加上不能明说的原因，我选择了Vultr的西雅图服务器。5美元一个月的主机，可以提供一个IPv4、一个IPv6（需要自己勾选），配置也够用，1000G的流量近乎于无限。&lt;/p&gt;
&lt;p&gt;将SSR客户端配置好，把电脑连上之后，似乎没有什么问题。在之后的宋浩测试（指看了一天宋浩）之中，发现观看1080p哔哩哔哩视频没有任何压力，同时校园网一天只计了20M流量，可能是iPad偷跑的（手机关闭WiFi）。&lt;/p&gt;
&lt;p&gt;这个结果无疑是很令人惊喜的，但是之后我遇到了一些问题。&lt;/p&gt;
&lt;h2 id=&#34;三&#34;&gt;三
&lt;/h2&gt;&lt;p&gt;电脑上的测试成功了，但是其他设备上的测试都遇到了些问题：连不上IPv6的SSR。&lt;/p&gt;
&lt;p&gt;后来发现，我的两台Android手机（小米10 Pro和运行Pixel Experience的小米5s）全都无法获取校园网IPv6地址，而iPad则更难搞——国区搞不到SSR客户端。&lt;/p&gt;
&lt;p&gt;我的流量需求，电脑当然占大头，但是手机和iPad需求量也很大。不看视频，手机一天能够使用300M左右；而iPad开启了GoodNotes的iCloud与OneDrive同步，一天下来最多可以消耗掉2-3G流量。当然，大部分是上行，这个问题不大。&lt;/p&gt;
&lt;p&gt;也请求舍友使用 &lt;a class=&#34;link&#34; href=&#34;https://test-ipv6.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://test-ipv6.com&lt;/a&gt; 测试IPv6获取情况，发现有一位舍友的手机获取到了IPv6，而所有人都只有一台设备能获取。由此排除了DHCPv6不受Android设备支持的原因。&lt;/p&gt;
&lt;h2 id=&#34;四&#34;&gt;四
&lt;/h2&gt;&lt;p&gt;为了让所有设备都能免流校园网，我在考虑使用一个路由（或者类似路由的东西），广播一个全局经过IPv6的网络。我考虑过用备用机当热点，手机接收校园网WiFi信号，全局开SSR，然后将这个隧道经由热点分享出去。手机功耗够低，不太引人注目，而且性能够强。但是缺点也很明显：不够稳定，设备一多就不太好。&lt;/p&gt;
&lt;p&gt;于是我买了一台小米AC2100路由器，通过有线连接学校网络。AC2100是小米路由器的口碑翻身之作，5GHz信号覆盖据说非常不错，也有大量的第三方固件，而第三方固件可以支持安装SSR等插件。同价位也有小米AC2350，性能更强，但是第三方固件少；而价位更低的红米AC2100（套娃机）和腾达AC9，则主要因为外观的原因没有被我选中。&lt;/p&gt;
&lt;p&gt;我选择使用Padavan（也被称为老毛子）固件 [1]。不得不说，万能的恩山无线论坛真是什么关于路由器的玩意都有……&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing/padavan.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Padavan 主界面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;刷入固件之后，能够很明显地感觉到信号好了非常多，即使在厕所也不会断连了。（笑）而在桌前，甚至可以达到 -30dbm。&lt;/p&gt;
&lt;h2 id=&#34;五&#34;&gt;五
&lt;/h2&gt;&lt;p&gt;我将路由器连入学校的网口，却发现网口并没有提供校园网拨号宽带，除非办理运营商的宽带业务。&lt;/p&gt;
&lt;p&gt;正当我一筹莫展之时，我发现了Padavan固件设置中有一个 “无线桥接”，可以接收其他WiFi信号并作为WAN，然后经过路由器再发射出去。&lt;/p&gt;
&lt;p&gt;将2.4GHz和5GHz全部设为桥接之后，连接SSR，就可以直接访问Google等外网了。但是即使能够设置全局通过IPv6的SSR访问网络，通过测速等一系列手段（IPv4限速约10Mbps，IPv6无限速），还是发现有一部分流量无法通过IPv6，而是通过校园网的v4访问的。&lt;/p&gt;
&lt;p&gt;也就是说，这个时候只能把它当作全局访问外网的一个工具。&lt;/p&gt;
&lt;h2 id=&#34;六&#34;&gt;六
&lt;/h2&gt;&lt;p&gt;当我将电脑、手机、iPad接入路由器的时候，发现了同样的问题：电脑可以访问IPv6，而手机只有v4连接。兜兜转转，又回到了最开始的情况。&lt;/p&gt;
&lt;p&gt;排查一下情况，发现在使用IPv4的SSR节点。当我切换到IPv6的SSR节点时，打开任何页面都遭到了Connection Reset。不得已只能切换回IPv4节点，而且电脑也无法访问国内网站。难道是GFW List的问题？或者，既然电脑是唯一一个能够访问IPv6的设备，会不会是v6和v4代理的问题……？&lt;/p&gt;
&lt;h2 id=&#34;七&#34;&gt;七
&lt;/h2&gt;&lt;p&gt;打开路由器的外网状态页面，发现外网IPv6地址根本无法获取。一番搜索之后发现了借由 &lt;a class=&#34;link&#34; href=&#34;https://code.google.com/archive/p/napt66/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;NAPT66&lt;/a&gt; 获取内网与外网IPv6的方法 [2]。它是一个由北邮大佬开发的在IPv6环境下使用NAT的工具。在高级设置 - 外部网络 - IPv6设置中，这样设置各选项。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing/ipv6-settings.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;IPv6 设置样例&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;其中，DNSv6服务器可以自己选择，一些公共的DNSv6服务器可以在 &lt;a class=&#34;link&#34; href=&#34;https://dns.icoa.cn/ipv6/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;这里&lt;/a&gt; 找到。&lt;/p&gt;
&lt;p&gt;注意 “获取IPv6外网地址” 一定要选“从两端”，否则不能获取到外网地址！[3]&lt;/p&gt;
&lt;p&gt;然后到高级设置 - 系统管理 - 服务，打开 “启用NAPT66” 然后重启路由器，应该就可以获取到IPv6地址了。&lt;/p&gt;
&lt;p&gt;这里可以用 &lt;a class=&#34;link&#34; href=&#34;http://test-ipv6.com&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;test-ipv6.com&lt;/a&gt; 获取IPv6连接情况。如果你已经连上IPv6互联网，那么&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing/phone-ipv6-screenshot.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;Android&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;hnu-ipv6-bypass-billing/ipad-ipv6-screenshot.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;iPad&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;电脑当然也没有问题了。&lt;/p&gt;
&lt;p&gt;期间我的服务器IPv6地址突然ping不通了，然后等了半天多又好了，真的是玄学……&lt;/p&gt;
&lt;h2 id=&#34;八&#34;&gt;八
&lt;/h2&gt;&lt;p&gt;剩下的当然就是在路由器开启全局SSR了。请注意：如果你使用SS或者V2ray，那么可能需要一些配置才能用IPv6连接；SSR则原生支持IPv6。&lt;/p&gt;
&lt;p&gt;导入SSR之后，记得手动切换成SSR协议，然后检查一下协议插件和混淆插件。Padavan的SSR设置似乎有点反人类。&lt;/p&gt;
&lt;p&gt;不过似乎连接之后，仍会产生IPv4下载流量，可以在 “系统管理” 的“控制台”中执行 &lt;code&gt;iptables -P INPUT DROP&lt;/code&gt; 如下命令&lt;/p&gt;
&lt;p&gt;来禁用IPv4下载。或者你也可以在系统管理 - 服务开启SSH，使用SSH客户端执行命令。&lt;/p&gt;
&lt;p&gt;即使有一点点v4上传流量也没关系，毕竟不收费。理论上，所有流量都应该走v6了。&lt;/p&gt;
&lt;p&gt;到此，主要内容就基本完成了。只要是透过路由器连接的网络，都可以免流；而对于宿舍之外，无法自行部署路由器的地方，建议搭配大流量手机卡使用。或者也可以用校园网——如果你用流量不是很多的话。如果连着校园网时能通过上述的那个网站查询到你的IPv6地址，那么开一个全局SSR也是不错的选择。我的iPad则是一直连着校园网，因为绝大部分的流量是笔记备份（上传流量），所以无需担心流量问题。&lt;/p&gt;
&lt;p&gt;未来如果IPv6全面普及，也许就不需要再通过SSR了，只需要那句iptables命令就可以了……SSR的作用，只是保证IPv4 only的网站正常访问。&lt;/p&gt;
&lt;h2 id=&#34;九&#34;&gt;九
&lt;/h2&gt;&lt;p&gt;有时候会遇到路由器无法获取到IPv6地址的情况。这时在前面给路由器刷入的Breed就有用处了：重启进Breed恢复控制台，修改设备的MAC地址（最好都改改），一般能够重新获取到IPv6。&lt;/p&gt;
&lt;p&gt;可以使用 &lt;a class=&#34;link&#34; href=&#34;https://miniwebtool.com/zh-cn/mac-address-generator/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MAC 地址生成器&lt;/a&gt; 生成地址，还可以使用 &lt;a class=&#34;link&#34; href=&#34;https://miniwebtool.com/zh-cn/mac-address-lookup/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;MAC 地址查找&lt;/a&gt; 来获取到特定制造商的地址前缀（如果在IEEE注册了，而且存在于网站的数据库中），比如Apple的前缀之一是0010FA，神舟电脑ODM蓝天的前缀是0090F5。&lt;/p&gt;
&lt;p&gt;也可以使用 &lt;a class=&#34;link&#34; href=&#34;https://github.com/cyp0633/MAC-Generator&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;我写的 MAC 地址生成器&lt;/a&gt; 直接生成一批不同的MAC地址。&lt;/p&gt;
&lt;h2 id=&#34;现存问题&#34;&gt;现存问题
&lt;/h2&gt;&lt;p&gt;现在SSR仍然会有间歇的断开现象，而且一断就很久连不上。但就如同我的离散数学老师说的，“计算机不存在玄学问题”，我只能说不知道为什么了……&lt;/p&gt;
&lt;p&gt;初期也出现过一开全局就特别慢的现象，还以为是路由器性能不足，后来速度突然提升，也不知道这个是为啥。&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.right.com.cn/forum/forum.php?mod=viewthread&amp;amp;tid=4054150&amp;amp;extra=page%3D1%26filter%3Dtypeid%26typeid%3D43&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;红米 (小米)AC2100 无需 Telnet 刷入 Breed 和 Padavan 固件教程&lt;/a&gt; - 恩山无线论坛&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://zhuanlan.zhihu.com/p/91901946&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;校园网路由器后设备使用 ipv6 经验分享&lt;/a&gt; - 知乎&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.right.com.cn/forum/thread-473835-1-1.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;h 大老毛子 ipv6 的 wan 口地址获取不到&lt;/a&gt; - 恩山无线论坛&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        <item>
        <title>从零开始搭建一个 iPad 上可用的 &#34;vscode&#34;</title>
        <link>https://cyp0633.com/post/use-vscode-on-ipad/</link>
        <pubDate>Fri, 19 Feb 2021 00:00:00 +0000</pubDate>
        
        <guid>https://cyp0633.com/post/use-vscode-on-ipad/</guid>
        <description>&lt;p&gt;&lt;strong&gt;本文已经两年没有更新，code-server也已有了较大的变化，建议阅读其他更新的文章。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;众所周知，iPad上没有官方的vscode客户端，我们所搭建的也不是一个真的vscode，而是基于vscode项目而衍生的 &lt;a class=&#34;link&#34; href=&#34;https://github.com/cdr/code-server&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;code-server&lt;/a&gt;。除了让它能够在服务器上运行之外，开发者并没有做太多的改动，所以你使用的时候并不会感觉到有多大异样。&lt;/p&gt;
&lt;p&gt;并且，code-server的本质是一个网站，这让你不只可以在iPad上访问，也可以在Android平板、手机，甚至树莓派等一切有现代网页浏览器支持的设备上使用。当然，在有微软vscode官方支持的平台，更建议用vscode直接通过SSH连接服务器。&lt;/p&gt;
&lt;h2 id=&#34;准备服务器环境&#34;&gt;准备服务器环境
&lt;/h2&gt;&lt;h3 id=&#34;租用服务器&#34;&gt;租用服务器
&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;如果你的PC有一个固定的公网IP，且可以运行Linux/macOS，可以直接跳到 “安装code-server”。&lt;/strong&gt; 但大部分人都没有，所以还是自己租服务器吧……&lt;/p&gt;
&lt;p&gt;我使用的是Vultr的服务器，单核，1024M内存，25G SSD，Ubuntu 20.04，加上自动备份（我手贱）一个月6美元，能用支付宝。这个配置低于官方推荐配置，不过足够让code-server流畅运行了。&lt;/p&gt;
&lt;p&gt;建议不要用Windows，授权费非常贵，而且运行起来也没有Linux有效率。推荐选择Ubuntu、CentOS、Debian等系统。&lt;/p&gt;
&lt;p&gt;国外（尤其是美国）的服务器，相比来说网络带宽比较高（比如vultr好像不限制带宽），有IPv6（某些校园网可以免流），也可以用来做一些不能明说的事情。国内的服务器提供商，如阿里、腾讯、华为，很多有学生优惠，10块钱一个月都能租到服务器；而且国内访问起来也会快很多。&lt;/p&gt;
&lt;p&gt;具体的购买服务器流程，这里不再赘述，选择配置可以与我的相似，或者更高点，如果还是有困难的话可以去搜索教程。&lt;/p&gt;
&lt;h3 id=&#34;ssh&#34;&gt;SSH
&lt;/h3&gt;&lt;p&gt;SSH客户端，我推荐Termius，界面美观，多平台同步。GitHub Student Developer Pack自带专业版授权，只要你还是学生，就可以白嫖。&lt;/p&gt;
&lt;p&gt;为了便捷访问服务器，少输密码，可以生成RSA密钥，将公钥存放在服务器之后SSH服务器就不需要输入密码了。这方面还是需要自行寻找教程，推荐探索一下使用Windows自带SSH命令的方法。&lt;/p&gt;
&lt;p&gt;有了SSH，我们就能够像是在自己电脑上输命令一样，在服务器上输命令了。当然，不配置其实也行，只不过每次都需要去云服务商管理后台来操控。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/28326dbe44d19e6e.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;SSH 客户端长这样，以 Termius 为例&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;Termius界面&lt;/p&gt;
&lt;p&gt;一些SSH客户端自带SFTP功能，可以便捷地在服务器与你的电脑之间传输文件。但是很多时候，速度不尽如人意，这时我推荐WinSCP客户端，传输速度会快很多。&lt;/p&gt;
&lt;p&gt;请注意，Linux的文件系统与Windows的有很大不同。如果你常用Android手机或者macOS电脑（其实是类UNIX），应该会觉得有点熟悉。&lt;/p&gt;
&lt;h2 id=&#34;安装与运行code-server&#34;&gt;安装与运行code-server
&lt;/h2&gt;&lt;p&gt;安装其实是最简单的。直接在终端中输入如下命令：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-0&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-0&#34; style=&#34;display:none;&#34;&gt;curl -fsSL https://code-server.dev/install.sh | sh&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://code-server.dev/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后你就可以看到code-server被安装到了你的服务器上。&lt;/p&gt;
&lt;p&gt;可以直接在终端中输入&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-1&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-1&#34; style=&#34;display:none;&#34;&gt;code-server&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;code-server&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;来运行code-server。它会监听8080端口，也就是说，你输入localhost:8080就可以访问了。&lt;/p&gt;
&lt;p&gt;这个时候只能使用服务器的内网访问，和本地的vscode没啥区别，如果想将它开放至Internet，随处都可以访问，可以在后面添加 &lt;code&gt;--host&lt;/code&gt; 参数。&lt;/p&gt;
&lt;p&gt;如果想用HTTPS访问，以获得最佳兼容性，可以加上 &lt;code&gt;--cert&lt;/code&gt; 参数。后面也可以加上你自己搞到的HTTPS证书（如果有）。&lt;/p&gt;
&lt;p&gt;后面可以接更多的参数，可以输入 &lt;code&gt;code-server --help&lt;/code&gt; 来查看。&lt;/p&gt;
&lt;p&gt;code-server运行的时候会占用当前终端，不会后台运行，所以可以在每次使用时链接SSH开启。或者也可以使用&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-2&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-2&#34; style=&#34;display:none;&#34;&gt;screen -S screen_namecode-server (options)&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;screen -S screen_namecode-server &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;options&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后按Ctrl+A+D使其后台运行。screen_name是screen的名字，（options）是自定义的参数。这样你就可以把code-server挂在后台，同时处理多项任务了。&lt;/p&gt;
&lt;p&gt;现在，你就可以使用服务器IP:8080来访问你的code-server。建议此处先使用桌面端浏览器来访问。&lt;/p&gt;
&lt;h2 id=&#34;配置开发环境&#34;&gt;配置开发环境
&lt;/h2&gt;&lt;p&gt;这一部分，用过vscode的同学应该不会陌生，大同小异罢了。主要面向C++ 和Python。&lt;/p&gt;
&lt;h3 id=&#34;编译器配置&#34;&gt;编译器配置
&lt;/h3&gt;&lt;p&gt;GCC、G++ 已经内置在了系统内，无需安装，但调试用的GDB需要安装:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;（下面的命令均以Ubuntu/Debian为例；如果用的是root用户登录，不需要再输sudo）&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-3&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-3&#34; style=&#34;display:none;&#34;&gt;sudo apt install gdb&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install gdb&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;有时候，Python也已经内置在系统内，但是版本较老。比如2021/2/2的最新版本是Python 3.9.1，就可以使用&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-4&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-4&#34; style=&#34;display:none;&#34;&gt;sudo apt install python3.9&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install python3.9&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;来安装新版本。如果你需要下载Python库，还需要&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;bash&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-5&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-5&#34; style=&#34;display:none;&#34;&gt;sudo apt install pip3&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo apt install pip3&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;以安装pip。&lt;/p&gt;
&lt;h3 id=&#34;插件&#34;&gt;插件
&lt;/h3&gt;&lt;p&gt;众所周知，vscode的灵魂在于插件。由于没有添加微软的一些专有代码，code-server并不能连接完整的微软插件商店，不过我们可以在 &lt;a class=&#34;link&#34; href=&#34;https://marketplace.visualstudio.com/vscode&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;网页版插件商店&lt;/a&gt; 中找到相应的插件，点击Download Extension，上传至服务器，然后手动安装就可以使用了。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/bf0ad32258fe6bb0.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;插件下载方法&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;在这里下载之后，将其传到服务器任意目录。打开你的code-server，按Ctrl+Shift+P，打开命令窗口，输入install from vsix，回车，然后手动浏览刚刚上传的插件并安装。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/8d2cde8868b757f9.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;如果有部分插件安装失败，可以试着用code-server自带的插件商店安装。&lt;/p&gt;
&lt;p&gt;这里推荐我使用的一些插件。&lt;/p&gt;
&lt;p&gt;C++：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Better C++ Syntax by jeff-hykin&lt;/li&gt;
&lt;li&gt;C/C++ by ms-vscode&lt;/li&gt;
&lt;li&gt;C/C++ Themes by ms-vscode&lt;/li&gt;
&lt;li&gt;C++ Intellisense by austin&lt;/li&gt;
&lt;li&gt;CMake by twxs&lt;/li&gt;
&lt;li&gt;CMake Tools by ms-vscode&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Python:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python by ms-python&lt;/li&gt;
&lt;li&gt;Pylance by ms-python&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其他：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub Pull Requests and Issues by GitHub&lt;/li&gt;
&lt;li&gt;GitLens by eamodio&lt;/li&gt;
&lt;li&gt;One Dark Pro by zhuangtongfa&lt;/li&gt;
&lt;li&gt;Rainbow Brackets by 2gua&lt;/li&gt;
&lt;li&gt;Chinese (Simplified) Language Pack for Visual Studio Code by MS-CEINTL&lt;/li&gt;
&lt;li&gt;markdownlint by DavidAnson&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;工作区-vscode文件夹&#34;&gt;工作区. vscode文件夹
&lt;/h3&gt;&lt;p&gt;这本应该是最难的一步，但是微软给了一个教程，我们可以直接抄作业。主要针对于配置十分繁杂的C++，Python的话应该很简单。&lt;/p&gt;
&lt;p&gt;首先在code-server中打开一个文件夹，这个文件夹就是你的一个工作区，你可以把代码文件存放在里面。你可以把其他位置的文件夹加入工作区（当然，应该必须是服务器上的），也可以打开不同的文件夹 / 工作区。&lt;/p&gt;
&lt;p&gt;然后在这个文件夹中新建名为. vscode的文件夹，用来存放code-server适用于该工作区的配置文件（你写的代码别放在这儿），新建launch.json和tasks.json两个文件。&lt;/p&gt;
&lt;p&gt;在launch.json中，输入：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-6&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-6&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;version&amp;#34;: &amp;#34;0.2.0&amp;#34;,
  &amp;#34;configurations&amp;#34;: [
    {
      &amp;#34;name&amp;#34;: &amp;#34;g&amp;#43;&amp;#43; build and debug active file&amp;#34;,
      &amp;#34;type&amp;#34;: &amp;#34;cppdbg&amp;#34;,
      &amp;#34;request&amp;#34;: &amp;#34;launch&amp;#34;,
      &amp;#34;program&amp;#34;: &amp;#34;${fileDirname}/${fileBasenameNoExtension}&amp;#34;,
      &amp;#34;args&amp;#34;: [],
      &amp;#34;stopAtEntry&amp;#34;: false,
      &amp;#34;cwd&amp;#34;: &amp;#34;${workspaceFolder}&amp;#34;,
      &amp;#34;environment&amp;#34;: [],
      &amp;#34;externalConsole&amp;#34;: false,
      &amp;#34;MIMode&amp;#34;: &amp;#34;gdb&amp;#34;,
      &amp;#34;setupCommands&amp;#34;: [
        {
          &amp;#34;description&amp;#34;: &amp;#34;Enable pretty-printing for gdb&amp;#34;,
          &amp;#34;text&amp;#34;: &amp;#34;-enable-pretty-printing&amp;#34;,
          &amp;#34;ignoreFailures&amp;#34;: true
        }
      ],
      &amp;#34;preLaunchTask&amp;#34;: &amp;#34;g&amp;#43;&amp;#43; build active file&amp;#34;,
      &amp;#34;miDebuggerPath&amp;#34;: &amp;#34;/usr/bin/gdb&amp;#34;
    }
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;0.2.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;configurations&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;g++ build and debug active file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;cppdbg&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;program&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${fileDirname}/${fileBasenameNoExtension}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;stopAtEntry&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${workspaceFolder}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;environment&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;externalConsole&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;MIMode&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;setupCommands&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Enable pretty-printing for gdb&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;-enable-pretty-printing&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;nt&#34;&gt;&amp;#34;ignoreFailures&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;preLaunchTask&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;g++ build active file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;miDebuggerPath&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/gdb&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;这些内容。然后在tasks.json中输入：&lt;/p&gt;
&lt;div class=&#34;codeblock&#34;&gt;
    &lt;header&gt;
        &lt;span class=&#34;codeblock-lang&#34;&gt;json&lt;/span&gt;
        &lt;button 
            class=&#34;codeblock-copy&#34;
            data-id=&#34;codeblock-id-7&#34;
            data-copied-text=&#34;已复制！&#34;
        &gt;
            复制代码
        &lt;/button&gt;
    &lt;/header&gt;
    &lt;code id=&#34;codeblock-id-7&#34; style=&#34;display:none;&#34;&gt;{
  &amp;#34;version&amp;#34;: &amp;#34;2.0.0&amp;#34;,
  &amp;#34;tasks&amp;#34;: [
    {
      &amp;#34;type&amp;#34;: &amp;#34;shell&amp;#34;,
      &amp;#34;label&amp;#34;: &amp;#34;g&amp;#43;&amp;#43; build active file&amp;#34;,
      &amp;#34;command&amp;#34;: &amp;#34;/usr/bin/g&amp;#43;&amp;#43;&amp;#34;,
      &amp;#34;args&amp;#34;: [&amp;#34;-g&amp;#34;, &amp;#34;${file}&amp;#34;,&amp;#34;-o&amp;#34;,&amp;#34;${fileDirname}/${fileBasenameNoExtension}&amp;#34;],
      &amp;#34;options&amp;#34;: {
        &amp;#34;cwd&amp;#34;: &amp;#34;/usr/bin&amp;#34;
      },
      &amp;#34;problemMatcher&amp;#34;: [&amp;#34;$gcc&amp;#34;],
      &amp;#34;group&amp;#34;: {
        &amp;#34;kind&amp;#34;: &amp;#34;build&amp;#34;,
        &amp;#34;isDefault&amp;#34;: true
      }
    }
  ]
}&lt;/code&gt;&lt;div class=&#34;&#34;&gt;&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;version&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;2.0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;tasks&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;shell&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;label&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;g++ build active file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin/g++&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-g&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;${file}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;-o&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;${fileDirname}/${fileBasenameNoExtension}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;options&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;cwd&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/bin&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;problemMatcher&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;$gcc&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;kind&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;build&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;isDefault&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;然后回到你的工作区根目录，新建一个cpp文件，写个hello world啥的。按下F5，可以开始调试。你所看到的应该是类似于这样的：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/ae4402790ba24af0.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;调试页面&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;每次打开code-server的第一次调试，都会跳到 “输出”tab，切回“终端” 就能看到输出结果了。&lt;/p&gt;
&lt;h2 id=&#34;在不同终端上的访问&#34;&gt;在不同终端上的访问
&lt;/h2&gt;&lt;p&gt;在Windows上，推荐使用Chromium内核的浏览器进行访问，包括但不限于Chrome、微软Edge、360等浏览器。vscode基于Electron，Electron又使用了Chromium，所以code-server在Chromium内核上理应表现更好。&lt;/p&gt;
&lt;p&gt;在Android上，可以随便找个浏览器访问（QQ浏览器不知道能不能完美使用，不知道那个X5内核本质上是什么）&lt;/p&gt;
&lt;p&gt;在iOS和iPadOS上，Safari对网站的安全要求有着诸多限制，所以最好使用 &lt;a class=&#34;link&#34; href=&#34;https://apps.apple.com/cn/app/servediter-for-code-server/id1504491325&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Servediter&lt;/a&gt; 应用来连接。下载后，使用self hosted server，然后这样填写：&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/a143af296f4a620e.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;p&gt;应该就可以正常使用了。&lt;/p&gt;
&lt;p&gt;macOS？饶了我吧，我的macOS虚拟机从开机卡到关机…… 好吧，我试了，没问题。&lt;/p&gt;
&lt;p&gt;建议在移动设备上配合外接键盘使用，总不会有人用触摸键盘写代码吧。并且，像我刚才说的一样，有官方vscode客户端的终端，如Linux、Windows、macOS，甚至Windows 10 ARM的Lumia 950 XL，都建议使用原版vscode连服务器，code-server的真正价值在于在没有vscode支持的终端上变相使用 “vscode”。&lt;/p&gt;
&lt;p&gt;&lt;figure style=&#34;max-width: 80%; margin: auto;&#34;&gt;
			&lt;img data-zoomable=&#34;true&#34; data-oss-key=&#34;use-vscode-on-ipad/a58e606e70d0d02a.avif&#34; src=&#34;data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==&#34; loading=&#34;lazy&#34;  alt=&#34;在原版 vscode 中的连接远程服务器选项&#34; 
				style=&#34;width: 100%; height: auto; max-height: 70vh; object-fit: contain;&#34;&gt;
			
		&lt;/figure&gt;&lt;/p&gt;
&lt;h2 id=&#34;参考文献&#34;&gt;参考文献
&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/liteng607/article/details/106601569&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;[code-server+VSApp] 在iPad上使用VSCode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/cdr/code-server/blob/v3.8.0/doc/install.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;code-server/install.md at v3.8.0 · cdr/codeserver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/cdr/code-server/blob/v3.8.0/doc/ipad.md&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;code-server/ipad.md at v3.8.0 · cdr/codeserver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://blog.csdn.net/zju_cf/article/details/102765085&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;在线 ide code-server 运行起来过程中踩到的坑及解决方法&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
        </item>
        
    </channel>
</rss>
