<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>🤪C&#39;est la vie</title>
    <link>https://www.cestlavie.moe/</link>
    <description>Recent content on 🤪C&#39;est la vie</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>zh</language>
    <lastBuildDate>Sat, 11 Nov 2023 11:30:55 +0800</lastBuildDate><atom:link href="https://www.cestlavie.moe/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>自建 Tailscale 的 DERP Server</title>
      <link>https://www.cestlavie.moe/posts/self-hosted-tailscale-derp-server/</link>
      <pubDate>Sat, 11 Nov 2023 11:30:55 +0800</pubDate>
      
      <guid>https://www.cestlavie.moe/posts/self-hosted-tailscale-derp-server/</guid>
      <description>有了自建 DERP Server，Tailscale 组网就是爽！</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>自从进入大学以来，作为一个工科学生，笔记本电脑一向是“告别 mac，平板本性能太拉”。平时背个游戏本怎么着也得是负重 5kg，所以日常的搭配都是 iPad mini + 键盘鼠标远程连到放在宿舍的游戏本。Tailscale 组网在校园网比较正常的时候延迟可以稳定在 3ms 左右，但是一旦出现网络波动或者在外访问，Tailscale 自带的 DERP Server 延迟又太高，于是就有了自建的想法。</p>
<h2 id="tailscale-的组网原理">Tailscale 的组网原理</h2>
<p>Tailscale 的终极目标是让两台<strong>处于网络上的任何位置</strong>的机器建立<strong>点对点连接</strong>（直连），但现实世界是复杂的，大部份情况下机器都位于 NAT 和防火墙后面，这时候就需要通过打洞来实现直连，也就是 NAT 穿透。</p>
<p>NAT 按照 <strong>NAT 映射行为</strong>和<strong>有状态防火墙行为</strong>可以分为多种类型，但对于 NAT 穿透来说根本不需要关心这么多类型，只需要看 <strong>NAT 或者有状态防火墙是否会严格检查目标 Endpoint</strong>，根据这个因素，可以将 NAT 分为 <strong>Easy NAT</strong> 和 <strong>Hard NAT</strong>。</p>
<ul>
<li><strong>Easy NAT</strong> 及其变种称为 “Endpoint-Independent Mapping” (<strong>EIM，终点无关的映射</strong>)<br>
这里的 Endpoint 指的是目标 Endpoint，也就是说，有状态防火墙只要看到有客户端自己发起的出向包，就会允许相应的入向包进入，<strong>不管这个入向包是谁发进来的都可以</strong>。</li>
<li><strong>hard NAT</strong> 以及变种称为 “Endpoint-Dependent Mapping”（<strong>EDM，终点相关的映射</strong>）<br>
这种 NAT 会针对每个目标 Endpoint 来生成一条相应的映射关系。 在这样的设备上，如果客户端向某个目标 Endpoint 发起了出向包，假设客户端的公网 IP 是 2.2.2.2，那么有状态防火墙就会打开一个端口，假设是 4242。那么只有来自该目标 Endpoint 的入向包才允许通过 <code>2.2.2.2:4242</code>，其他客户端一律不允许。这种 NAT 更加严格，所以叫 Hard NAT。</li>
</ul>
<p>对于 Easy NAT，我们只需要提供一个第三方的服务，它能够告诉客户端“它看到的客户端的公网 <code>ip:port</code> 是什么”，然后将这个信息以某种方式告诉通信对端（peer），后者就知道该和哪个地址建连了！这种服务就叫 <strong>STUN</strong> (Session Traversal Utilities for NAT，NAT会话穿越应用程序)。它的工作流程如下图所示：</p>
<ul>
<li>笔记本向 STUN 服务器发送一个请求：“从你的角度看，我的地址什么？”</li>
<li>STUN 服务器返回一个响应：“我看到你的 UDP 包是从这个地址来的：<code>ip:port</code>”。</li>
</ul>
<p><img loading="lazy" src="STUN.webp" alt=""  />
</p>
<h2 id="中继是什么">中继是什么</h2>
<p>对于 Hard NAT 来说，STUN 就不好使了，即使 STUN 拿到了客户端的公网 ip:port 告诉通信对端也于事无补，因为防火墙是和 STUN 通信才打开的缺口，这个缺口只允许 STUN 的入向包进入，其他通信对端知道了这个缺口也进不来。通常企业级 NAT 都属于 Hard NAT。</p>
<p>这种情况下打洞是不可能了，但也不能就此放弃，可以选择一种折衷的方式：创建一个中继服务器（relay server），客户端与中继服务器进行通信，中继服务器再将包中继（relay）给通信对端。</p>
<p>至于中继的性能，那就要看具体情况了：</p>
<ul>
<li>如果能直连，那显然没必要用中继方式；</li>
<li>如果无法直连，而中继路径又非常接近双方直连的真实路径，并且带宽足够大，那中继方式并不会明显降低通信质量。延迟肯定会增加一点，带宽会占用一些，但相比完全连接不上，还是可以接受的。</li>
</ul>
<p>事实上对于大部分网络而言，Tailscale 都可以通过各种黑科技打洞成功，只有极少数情况下才会选择中继，中继只是一种 fallback 机制。</p>
<h2 id="derp-又是什么">DERP 又是什么</h2>
<p>DERP 即 Detoured Encrypted Routing Protocol，这是 Tailscale 自研的一个协议：</p>
<ul>
<li>它是一个<strong>通用目的包中继协议，运行在 HTTP 之上</strong>，而大部分网络都是允许 HTTP 通信的。</li>
<li>它根据目的公钥（destination’s public key）来中继加密的流量（encrypted payloads）。</li>
</ul>
<p><img loading="lazy" src="DERP.webp" alt=""  />
</p>
<p>Tailscale 使用的算法很有趣，<strong>所有客户端之间的连接都是先选择 DERP 模式（中继模式），这意味着连接立即就能建立（优先级最低但 100% 能成功的模式），用户不用任何等待</strong>。然后开始并行地进行路径发现，通常几秒钟之后，我们就能发现一条更优路径，然后将现有连接透明升级（upgrade）过去，变成点对点连接（直连）。</p>
<p>因此，DERP 既是 Tailscale 在 NAT 穿透失败时的保底通信方式（此时的角色与 TURN 类似），也是在其他一些场景下帮助我们完成 NAT 穿透的旁路信道。 换句话说，它既是我们的保底方式，也是有更好的穿透链路时，帮助我们进行连接升级（upgrade to a peer-to-peer connection）的基础设施。</p>
<h2 id="自建私有-derp-server">自建私有 DERP server</h2>
<p>Tailscale 的私钥只会保存在当前节点，因此 DERP server 无法解密流量，它只能和互联网上的其他路由器一样，呆呆地将加密的流量从一个节点转发到另一个节点，只不过 DERP 使用了一个稍微高级一点的协议来防止滥用。</p>
<p>Tailscale 开源了 DERP 服务器的代码，如果你感兴趣，可以阅读 <a href="https://github.com/tailscale/tailscale/tree/main/derp">DERP 的源代码</a>。</p>
<p>Tailscale 官方内置了很多 DERP 服务器，分步在全球各地，<strong>惟独不包含中国大陆</strong>，原因你懂得。这就导致了一旦流量通过 DERP 服务器进行中继，延时就会非常高。而且官方提供的 DERP 服务器是万人骑，存在安全隐患。</p>
<p>为了实现低延迟、高安全性，我们可以参考 <a href="https://tailscale.com/kb/1118/custom-derp-servers/">Tailscale 官方文档</a>自建私有的 DERP 服务器。</p>
<p>使用自有域名部署需要满足以下几个条件：</p>
<ul>
<li>要有自己的域名，并且申请了 SSL 证书</li>
<li>需要准备一台或多台云主机</li>
<li>如果服务器在国内，域名需要备案</li>
<li>如果服务器在国外，则不需要备案</li>
</ul>
<p>如果以上条件都俱备，就可以按照下面的步骤开始部署了。</p>
<h3 id="安装-golang-并设置-goproxy">安装 golang 并设置 GOPROXY</h3>
<p>由于众所周知的网络原因，在安装 golang 时需要使用镜像源，我这里使用的是<a href="https://developer.aliyun.com/mirror/golang">阿里云的镜像</a>。</p>
<p>在 <a href="https://golang.google.cn/dl/">golang 官网</a>找到 golang 的最新版本并记录</p>
<p><img loading="lazy" src="golang.webp" alt=""  />
</p>
<p>随后登录云服务器，输入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ wget https://mirrors.aliyun.com/golang/go1.xx.x.linux-amd64.tar.gz <span class="c1"># x 换成刚刚记下的版本号	</span>
</span></span><span class="line"><span class="cl">$ sudo rm -rf /usr/local/go <span class="o">&amp;&amp;</span> tar -C /usr/local -xzf go1.21.4.linux-amd64.tar.gz <span class="c1"># 安装 golang</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">echo</span> <span class="s2">&#34;export PATH=</span><span class="nv">$PATH</span><span class="s2">:/usr/local/go/bin&#34;</span> &gt;&gt; ~/.bashrc <span class="o">&amp;&amp;</span> <span class="nb">source</span> ~/.bashrc <span class="c1"># 添加 golang 到环境变量</span>
</span></span><span class="line"><span class="cl">$ go env -w <span class="nv">GO111MODULE</span><span class="o">=</span>on
</span></span><span class="line"><span class="cl">$ go env -w <span class="nv">GOPROXY</span><span class="o">=</span>https://goproxy.cn,direct <span class="c1"># 设置 GOPROXY</span>
</span></span></code></pre></div><h3 id="安装-derper-并配置访问权限">安装 derper 并配置访问权限</h3>
<p>在云服务器中输入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ go install tailscale.com/cmd/derper@main <span class="c1"># 安装官方 derper</span>
</span></span><span class="line"><span class="cl">$ mv <span class="nv">$HOME</span>/go/bin/derper /usr/bin <span class="c1"># 移动至 /usr/bin，便于访问</span>
</span></span><span class="line"><span class="cl">$ sudo curl -fsSL https://tailscale.com/install.sh <span class="p">|</span> sudo sh <span class="c1"># （可选）安装 Tailscale，用于防止被白嫖 DERP Server</span>
</span></span><span class="line"><span class="cl">$ sudo tailscale up <span class="c1"># 此处按提示登录即可</span>
</span></span></code></pre></div><h3 id="配置-systemctl-服务">配置 systemctl 服务</h3>
<p>先创建 service 文件：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo touch /etc/systemd/system/tailscale-derper.service
</span></span></code></pre></div><p>然后在其中输入：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Tailscale DERP Server</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">derper --hostname=derp.yourdomain.com --verify-clients </span>
</span></span><span class="line"><span class="cl"><span class="c1"># 将 derp.yourdomain.com 替换为你的域名，若不需要防止白嫖则不需要使用 --verify-clients 参数</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">root</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></div><p>接着，重新加载<code>systemctl</code>配置：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo systemctl daemon-reload
</span></span></code></pre></div><p>启用开机自启并启动 <code>DERP Server</code>：！别忘了打开服务器的安全组哦！</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ sudo systemctl <span class="nb">enable</span> tailscale-derper.service
</span></span><span class="line"><span class="cl">$ sudo systemctl start tailscale-derper.service
</span></span></code></pre></div><p>若需要检查服务状态或查看日志，则请输入：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">sudo systemctl status tailscale-derper.service <span class="c1"># 查看服务状态</span>
</span></span><span class="line"><span class="cl">sudo journalctl -u tailscale-derper.service <span class="c1"># 查看日志</span>
</span></span></code></pre></div><h3 id="配置-derper-自动更新">配置 derper 自动更新</h3>
<p>在云服务器中输入 <code>crontab -e</code> （可能会需要选择编辑器）并在文件最后加入</p>
<pre tabindex="0"><code class="language-crontab" data-lang="crontab">0 0 * * * go install tailscale.com/cmd/derper@main &amp;&amp; mv $HOME/go/bin/derper /usr/bin -f &amp;&amp; systemctl restart tailscale-derper.service
</code></pre><p>保存退出即可</p>
<h3 id="在-tailscale-面板中配置-derp-server">在 Tailscale 面板中配置 DERP Server</h3>
<p>打开 <a href="https://login.tailscale.com/admin/acls/file">Tailscale - Access Controls</a>，在其中加入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 前略
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="nt">&#34;derpMap&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// 如果想要所有节点只使用自建中继的话，就启用这条配置
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="c1">// &#34;OmitDefaultRegions&#34;: true,
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>		<span class="nt">&#34;Regions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="nt">&#34;900&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;RegionID&#34;</span><span class="p">:</span>   <span class="mi">900</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;RegionCode&#34;</span><span class="p">:</span> <span class="s2">&#34;tsh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;RegionName&#34;</span><span class="p">:</span> <span class="s2">&#34;Shanghai&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;Nodes&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">					<span class="p">{</span>
</span></span><span class="line"><span class="cl">						    <span class="nt">&#34;Name&#34;</span><span class="p">:</span>     <span class="s2">&#34;Shanghai&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">						    <span class="nt">&#34;RegionID&#34;</span><span class="p">:</span> <span class="mi">900</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">						    <span class="nt">&#34;HostName&#34;</span><span class="p">:</span> <span class="s2">&#34;derp.mydomain.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">					<span class="p">},</span>
</span></span><span class="line"><span class="cl">					<span class="c1">// 如果有多个区域、多个节点，或者使用了自定义端口，那么可以参考这部分
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>			<span class="s2">&#34;901&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;RegionID&#34;</span><span class="p">:</span> <span class="mi">901</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;RegionCode&#34;</span><span class="p">:</span> <span class="s2">&#34;Oracle-OSAKA&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">				<span class="nt">&#34;Nodes&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">					    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;Name&#34;</span><span class="p">:</span> <span class="s2">&#34;Oracle-OSAKA-1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;RegionID&#34;</span><span class="p">:</span> <span class="mi">901</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;HostName&#34;</span><span class="p">:</span> <span class="s2">&#34;osaka1.derp.mydomain.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;DERPPort&#34;</span><span class="p">:</span> <span class="mi">4443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">					    <span class="p">},</span>
</span></span><span class="line"><span class="cl">					    <span class="p">{</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;Name&#34;</span><span class="p">:</span> <span class="s2">&#34;Oracle-OSAKA-1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;RegionID&#34;</span><span class="p">:</span> <span class="mi">901</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;HostName&#34;</span><span class="p">:</span> <span class="s2">&#34;osaka2.derp.mydomain.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                        <span class="nt">&#34;DERPPort&#34;</span><span class="p">:</span> <span class="mi">4443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">					    <span class="p">},</span>
</span></span><span class="line"><span class="cl">					<span class="p">]</span>
</span></span><span class="line"><span class="cl">				<span class="err">]</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">			<span class="p">},</span>
</span></span><span class="line"><span class="cl">		<span class="err">}</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">	<span class="err">}</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="err">}</span>
</span></span></code></pre></div><hr>
<hr>
<h2 id="参考文献">参考文献</h2>
<ol>
<li><a href="https://icloudnative.io/posts/custom-derp-servers/">Tailscale 基础教程：部署私有 DERP 中继服务器</a></li>
<li><a href="https://tailscale.com/kb/1118/custom-derp-servers/">Custom DERP Servers · Tailscale Docs</a></li>
<li><a href="https://tailscale.com/blog/how-tailscale-works/">How Tailscale works</a></li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>优雅地使用 Python requests 调用 Aria2 JSON-RPC </title>
      <link>https://www.cestlavie.moe/posts/python-aria2-jsonrpc/</link>
      <pubDate>Tue, 17 Jan 2023 15:08:29 +0000</pubDate>
      
      <guid>https://www.cestlavie.moe/posts/python-aria2-jsonrpc/</guid>
      <description>优雅地使用 Python 调用 Aria2 的 JSON-RPC</description>
      <content:encoded><![CDATA[<h2 id="背景">背景</h2>
<p>博主打算造一个能从 <a href="https://telegram.org">Telegram</a> 自动下载文件/媒体并自动上传至 <a href="https://drive.google.com/">Google Drive</a> 的轮子，自动上传的功能已经有现成的轮子可以拼上了，生成直链的轮子也找到了，就差联动<code>Aria2 JSON-RPC</code>和<code>Python</code>了，但是无奈找了半天都没有解决，最后还是问了大佬才搞定，遂记录。</p>
<p>其实本来看着<code>JSON-RPC</code>就比较复杂，相比之下<code>XML-RPC</code>就显得善良许多，但是不知道是版本问题还是什么原因，<code>XML-RPC</code>似乎不能使用，最后只好投奔复杂的<code>JSON-RPC</code>了。😭</p>
<p>说实话，我确实找到了不少现成的 Python 库可用，但是想着我只需要下个文件，没必要引入那么多不必要的代码，就想着自己写一小段了。🤔</p>
<p>还有一点就是，我看了好几个<code>PyPI</code>上的相关包，有的不支持新加入的<code>rpc-secret</code>属性，就没法用了。😒</p>
<h2 id="依赖">依赖</h2>
<p>依赖很少，甚至很多人早就安装好了。😂</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ pip install requests     <span class="c1">#Windows</span>
</span></span><span class="line"><span class="cl">$ pip3 install requests    <span class="c1">#MacOS or Linux</span>
</span></span></code></pre></div><h2 id="代码实现">代码实现</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">json</span><span class="o">,</span> <span class="nn">requests</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;jsonrpc&#34;</span><span class="p">:</span> <span class="s2">&#34;2.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;method&#34;</span><span class="p">:</span> <span class="s2">&#34;aria2.addUri&#34;</span><span class="p">,</span>        <span class="c1">#操作为添加下载链接</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;1&#34;</span><span class="p">,</span>        <span class="c1">#这个 id 没什么用，随便填一个就行，重复也无所谓</span>
</span></span><span class="line"><span class="cl"><span class="s2">&#34;params&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;token:&lt;Your rpc-secret&gt;&#34;</span><span class="p">,[</span><span class="s2">&#34;url&#34;</span><span class="p">]]</span>        <span class="c1">#有设置 rpc-secret 参数的将此处 &lt;Your rpc-secret&gt; 替换为自己的 rpc-secret</span>
</span></span><span class="line"><span class="cl"><span class="err">　　</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="n">dl_url</span> <span class="o">=</span> <span class="s1">&#39;https://dl.example.com/example.file&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span><span class="p">[</span><span class="s1">&#39;params&#39;</span><span class="p">][</span><span class="mi">0</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">dl_url</span>        <span class="c1">#自定义下载文件链接</span>
</span></span><span class="line"><span class="cl"><span class="n">url</span> <span class="o">=</span> <span class="s1">&#39;&#39;</span>        <span class="c1">#你的 Aria2 服务器完整链接，使用 HTTP(S) 协议，包含端口</span>
</span></span><span class="line"><span class="cl"><span class="c1">#例如 http://aria2.example.com:6800/jsonrpc</span>
</span></span><span class="line"><span class="cl"><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="n">response</span><span class="o">.</span><span class="n">text</span><span class="p">)</span>         <span class="c1">#显示请求结果</span>
</span></span></code></pre></div><p>返回结果示例：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span><span class="nt">&#34;id&#34;</span><span class="p">:</span><span class="s2">&#34;1&#34;</span><span class="p">,</span><span class="nt">&#34;jsonrpc&#34;</span><span class="p">:</span><span class="s2">&#34;2.0&#34;</span><span class="p">,</span><span class="nt">&#34;result&#34;</span><span class="p">:</span><span class="s2">&#34;a68bf66b2db28041&#34;</span><span class="p">}</span>    
</span></span></code></pre></div><p><code>&quot;result&quot;</code> 中即为该下载链接对应的 <code>GID</code></p>
]]></content:encoded>
    </item>
    
    <item>
      <title>使用 ACME.SH 申请 Google CA SSL 证书</title>
      <link>https://www.cestlavie.moe/posts/acme-gts-ssl/</link>
      <pubDate>Sun, 01 Jan 2023 14:22:16 +0000</pubDate>
      
      <guid>https://www.cestlavie.moe/posts/acme-gts-ssl/</guid>
      <description>我是这样使用 ACME.SH 申请 Google CA SSL 证书的</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>最近谷歌开放了自家的 GTS CA(Google Trust Services)，谷歌作为全球大厂那不得好好嫖一下！目前该服务进入了 <strong>Public Review</strong> 阶段，不再需要申请内测资格，而且支持<a href="https://github.com/acmesh-official/acme.sh">acme.sh</a>快速申请，那不就是嫖他的好日子来了吗！</p>
<h2 id="证书简介">证书简介</h2>
<p>GTS SSL 证书的特点是</p>
<ul>
<li>
<p>支持 IP 地址块持有者申请 <strong>IP</strong> <strong>地址证书</strong></p>
</li>
<li>
<p>根 CA 为<a href="https://www.globalsign.com/"><strong>GlobalSign</strong></a>，根 CA 的支持性和兼容性比<a href="https://letsencrypt.org/"><code>Let's Encrypt</code></a>好</p>
</li>
<li>
<p>支持安全性和性能更好的<strong>ECC 证书</strong></p>
</li>
<li>
<p>支持<strong>多域名</strong>、<strong>泛域名</strong>证书申请（例如<code>*.cestlavie.moe</code>）</p>
</li>
<li>
<p>有效期为 <strong>90 天</strong></p>
</li>
<li>
<p>支持的 ACME 验证方式为<code>TLS-ALPN-01</code>、<code>HTTP-01</code>、和 <code>DNS-01</code></p>
</li>
<li>
<p><strong>暂不支持</strong>邮箱验证方式申请</p>
</li>
<li>
<p><strong>暂不支持</strong>以<a href="https://zh.m.wikipedia.org/wiki/%E5%9B%BD%E9%99%85%E5%8C%96%E5%9F%9F%E5%90%8D%E7%BC%96%E7%A0%81">国际化域名编码</a>的域名</p>
</li>
</ul>
<h2 id="申请步骤">申请步骤</h2>
<h3 id="获取注册密钥">获取注册密钥</h3>
<p>打开<a href="https://shell.cloud.google.com">shell.cloud.google.com</a>，输入以下代码</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ gcloud beta publicca external-account-keys create <span class="c1">#创建凭据</span>
</span></span></code></pre></div><p>回显为</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ gcloud beta publicca external-account-keys create
</span></span><span class="line"><span class="cl">API <span class="o">[</span>publicca.googleapis.com<span class="o">]</span> not enabled on project <span class="o">[</span>&lt;projectid&gt;<span class="o">]</span>. Would you like to <span class="nb">enable</span> and retry <span class="o">(</span>this will take a few minutes<span class="o">)</span>? <span class="o">(</span>y/N<span class="o">)</span>?  y <span class="c1">#允许创建 publica API</span>
</span></span><span class="line"><span class="cl">Enabling service <span class="o">[</span>publicca.googleapis.com<span class="o">]</span> on project <span class="o">[</span>&lt;projectid&gt;<span class="o">]</span>...
</span></span><span class="line"><span class="cl">Operation <span class="s2">&#34;operations/acat.p2-&lt;projectid&gt;-&lt;uuid&gt;&#34;</span> finished successfully.
</span></span><span class="line"><span class="cl">Created an external account key
</span></span><span class="line"><span class="cl"><span class="o">[</span>b64MacKey: &lt;hmac_key&gt;
</span></span><span class="line"><span class="cl">keyId: &lt;keyid&gt;<span class="o">]</span>
</span></span></code></pre></div><p><strong>保存好输出的<code>&lt;hmac_key&gt;</code>和<code>&lt;keyid&gt;</code>，接下来要用</strong></p>
<h3 id="安装acmesh">安装<code>acme.sh</code></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ curl  https://get.acme.sh <span class="p">|</span> sh -s   <span class="c1"># 请确保已安装 curl</span>
</span></span></code></pre></div><p>显示<code>Install success!</code>即为安装成功</p>
<h3 id="使用凭据注册">使用凭据注册</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ acme.sh --set-default-ca --server google <span class="c1">#切换默认 CA 为 Google</span>
</span></span><span class="line"><span class="cl">$ acme.sh --server https://dv.acme-v02.api.pki.goog/directory <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--register-account  --accountemail &lt;Your_Email&gt; --eab-kid &lt;keyid&gt; --eab-hmac-key &lt;hmac_key&gt; <span class="c1"># 使用刚刚获取凭据注册账号</span>
</span></span></code></pre></div><h3 id="签发证书">签发证书</h3>
<ol>
<li>使用 TXT 记录手动验证 DNS</li>
</ol>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ acme.sh  --issue  --dns   -d yourdomain.com <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--yes-I-know-dns-manual-mode-enough-go-ahead-please
</span></span></code></pre></div><p>然后根据回显中</p>
<pre tabindex="0"><code>Add the following TXT record:
Domain: &#39;_acme-challenge.yourdomain.com&#39;
TXT value: &#39;&lt;TXT_value&gt;&#39;
</code></pre><p>设置 DNS 记录，完成后输入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ acme.sh  --renew   -d yourdomain.com <span class="se">\
</span></span></span><span class="line"><span class="cl"><span class="se"></span>--yes-I-know-dns-manual-mode-enough-go-ahead-please
</span></span></code></pre></div><p>完成证书申请</p>
<p>显示<code>Cert success</code>即为申请成功</p>
<p>可以在<code>~/.acme.sh/yourdomain.com/</code>下获取证书</p>
<ol start="2">
<li>使用 Cloudflare API 自动验证 DNS<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup></li>
</ol>
<p>首先获取你的<code>Global API Key</code>，<a href="https://dash.cloudflare.com/profile/api-tokens">可在此处获取</a></p>
<p>然后在终端中输入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">CF_Key</span><span class="o">=</span><span class="s1">&#39;&lt;YourGlobalAPIKey&gt;&#39;</span>
</span></span><span class="line"><span class="cl">$ <span class="nb">export</span> <span class="nv">CF_Email</span><span class="o">=</span><span class="s2">&#34;&lt;YourEmail&gt;&#34;</span>
</span></span></code></pre></div><p>接下来申请证书，输入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ acme.sh --issue --dns dns_cf -d yourdomain.com <span class="c1">#单域名</span>
</span></span><span class="line"><span class="cl">$ acme.sh --issue --dns dns_cf -d *.yourdomain.com <span class="c1">#泛域名</span>
</span></span><span class="line"><span class="cl">$ acme.sh --issue --dns dns_cf -d sub1.yourdomain.com -d sub2.yourdomain.com <span class="c1">#多域名</span>
</span></span><span class="line"><span class="cl">$ acme.sh --issue --dns dns_cf -d yourdomain.com --ecc <span class="c1">#ECC 证书</span>
</span></span></code></pre></div><p>看到回显<code>Cert success</code>即为申请成功，可以在<code>~/.acme.sh/yourdomain.com/</code>下获取证书</p>
<ul>
<li>此时 Cloudflare 凭据会自动存储至<code>~/.acme.sh/account.conf</code>用于续期目的</li>
</ul>
<p>附：申请下的证书路径</p>
<p><img loading="lazy" src="chain.png" alt=""  />
</p>
<blockquote>
<p><em>文中部分信息已做脱敏处理</em></p>
</blockquote>
<hr>
<h2 id="参考文献">参考文献</h2>
<ol>
<li>
<p><a href="https://github.com/acmesh-official/acme.sh/wiki">acme.sh Wiki - github.com</a></p>
</li>
<li>
<p><a href="https://cloud.google.com/blog/products/identity-security/automate-public-certificate-lifecycle-management-via--acme-client-api">Automate Public Certificates Lifecycle Management via RFC 8555 (ACME) - google.com</a></p>
</li>
</ol>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>这里默认使用了 Cloudflare 来演示自动申请证书，详细的支持列表及申请方法可以在<a href="https://github.com/acmesh-official/acme.sh/wiki/dnsapi">这里</a>找到&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>版权声明</title>
      <link>https://www.cestlavie.moe/copyright/</link>
      <pubDate>Fri, 30 Dec 2022 23:43:00 +0800</pubDate>
      
      <guid>https://www.cestlavie.moe/copyright/</guid>
      <description>Copyright</description>
      <content:encoded><![CDATA[<p><em>更新于 2022 年 12 月 30 日</em></p>
<blockquote>
<p>为了互联网上知识共享的开放性、匿名性和自由性，本网站 (<a href="https://www.cestlavie.moe/">www.cestlavie.moe</a>) 在 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">CC BY-NC-SA 4.0</a> 协议下允许符合规定的知识共享</p>
</blockquote>
<h1 id="署名-非商业性使用-方式共享-40-国际协议">署名-非商业性使用-方式共享 4.0 国际协议</h1>
<h2 id="您可以自由地">您可以自由地：</h2>
<ul>
<li><strong>共享</strong> — 在任何媒介以任何形式复制、发行本作品</li>
<li><strong>演绎</strong> — 修改、转换或以本作品为基础进行创作</li>
</ul>
<p><em>只要你遵守许可协议条款，许可人就无法收回你的这些权利</em></p>
<h2 id="惟须遵守下列条件">惟须遵守下列条件：</h2>
<ul>
<li><strong>署名</strong> - 您必须给出适当的署名<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>，提供指向本许可协议的链接，同时标明是否（对原始作品）作了修改<sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup>。您可以用任何合理的方式来署名，但是不得以任何方式暗示许可人为您或您的使用背书。</li>
<li><strong>非商业性使用</strong> - 您不得将本作品用于商业目的<sup id="fnref:3"><a href="#fn:3" class="footnote-ref" role="doc-noteref">3</a></sup>。</li>
<li><strong>相同方式共享</strong> - 如果您再混合、转换或基于本作品进行创作，您必须基于与原先许可协议相同的许可<sup id="fnref:4"><a href="#fn:4" class="footnote-ref" role="doc-noteref">4</a></sup>协议分发您贡献的作品。</li>
</ul>
<p><strong>没有附加限制</strong> - 你不得适用法律术语或者技术限制<sup id="fnref:5"><a href="#fn:5" class="footnote-ref" role="doc-noteref">5</a></sup> 从而限制其他人做许可协议允许的事情。</p>
<h2 id="声明">声明</h2>
<p>您不必因为公共领域的作品要素而遵守许可协议，或者您的使用被可适用的例外或限制<sup id="fnref:6"><a href="#fn:6" class="footnote-ref" role="doc-noteref">6</a></sup>所允许。</p>
<p>不提供担保。许可协议可能不会给与您意图使用的所必须的所有许可，例如，其他权利比如形象权、隐私权或人格权<sup id="fnref:7"><a href="#fn:7" class="footnote-ref" role="doc-noteref">7</a></sup> 可能限制您如何使用作品。</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>如果已提供，您必须提供创作者和署名者的姓名或名称、版权标识、许可协议标识、免责标识和作品链接。&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>如果您修改作品和保留以前修改的说明，您必须明确说明。&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:3">
<p>商业使用是指主要目的为获得商业优势或金钱回报。&#160;<a href="#fnref:3" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:4">
<p>您也可以使用以下列举的 <a href="https://creativecommons.org/compatiblelicenses">兼容协议</a>。&#160;<a href="#fnref:4" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:5">
<p>该协议禁止使用，<a href="https://www.wipo.int/">世界知识产权组织</a> 版权公约第 11 条定义的有效技术措施。&#160;<a href="#fnref:5" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:6">
<p>根据法律的例外和限制性规定，使用者拥有的权利，例如，合理使用（和公平交易），不受 CC 许可协议的影响 | <a href="https://creativecommons.org/faq/#Do_Creative_Commons_licenses_affect_exceptions_and_limitations_to_copyright.2C_such_as_fair_dealing_and_fair_use.3F">更多信息</a>&#160;<a href="#fnref:6" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:7">
<p>在按照您的需要使用该作品前，您可能需要得到更多许可。&#160;<a href="#fnref:7" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>关于</title>
      <link>https://www.cestlavie.moe/about/</link>
      <pubDate>Fri, 30 Dec 2022 22:28:06 +0800</pubDate>
      
      <guid>https://www.cestlavie.moe/about/</guid>
      <description>更新于 2023.04.15 嘿！欢迎来到这里~ 关于我 我是 Jonathan Zhang，很高兴认识你！ 在现实中我是一个热爱科技、音乐和运动的高三学生，会在空闲时间研究研究有趣的 GitHub</description>
      <content:encoded><![CDATA[<p><em>更新于 2023.04.15</em></p>
<p>嘿！欢迎来到这里~</p>
<h2 id="关于我">关于我</h2>
<p>我是 Jonathan Zhang，很高兴认识你！</p>
<p>在现实中我是一个热爱科技、音乐和运动的高三学生，会在空闲时间研究研究有趣的 GitHub 项目，或是写点小文章分享自己的所见所闻或学习笔记。</p>
<blockquote>
<p>怕什么真理无穷，进一寸有一寸的欢喜。</p>
</blockquote>
<p>我对 Linux 系统有基础的了解，目前还在继续学习。我会一点 Python 和 C++，但是我还是更喜欢 Python 的简洁易用。我打算有空的时候学习一下前端开发，造点小轮子；想学习 Golang 但是一直没行动。</p>
<p>我比较喜欢各种容器化和 Serverless 的应用，也在深度学习 Docker 的应用中。</p>
<h2 id="个人标签">个人标签</h2>
<p><code>男</code>/<code>双子座</code>/<code>松鼠党</code>/<code>网络吃瓜乐子人</code>/<code>拖延症晚期</code>/<code>HiFi 业余</code>/<code>音乐爱好者</code>/<code>体育爱好者</code>/<code>垃圾佬</code>/<code>隐私保护主义者</code>/<code>阅读爱好者</code></p>
<h2 id="关于博客">关于博客</h2>
<blockquote>
<p>每一个不曾起舞的日子，都是对生命的辜负。</p>
</blockquote>
<p>人在这世上走过一遭，总要留下些什么。这个博客主要会用于分享数码产品上手经历、GitHub 优质项目及搭建教程、学习笔记和生活日常，它是我的备忘录、记录手册、记忆库。</p>
<p>我一开始接触服务器是腾讯云的学生计划，像大多数人一样，我漫无目的的搭建了一个基于 WordPress 的博客，但当时只是「三分钟热度」搭建完就再也没有使用过了，最后无疾而终。</p>
<p>接下来我接触到 Azure 和 AWS 的服务器，也开始尝试使用 Azure Web App 配合 Typecho 搭建博客，但也只是搭建完就不管了，无疾而终。</p>
<p>接下来就开始使用基于 Golang 的 Hugo 框架搭建静态博客，它很快并且完全满足我的需求。静态博客的优点有很多，部署方便快捷，高可用，不需要自己的服务器，有很多免费且可供选择的静态托管平台<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>，不需要担心安和维护全问题等等等等。</p>
<p>希望这次我的博客能坚持下去，分享更多有价值的内容给大家。</p>
<p>有时候回头看自己以前的文章，会感觉到无知和肤浅的尴尬，但这都是过往珍贵的记忆，都弥足珍贵。</p>
<blockquote>
<p>凡是过往，皆为序章</p>
</blockquote>
<p>希望自己能保持<strong>好奇</strong>、<strong>无知</strong>、<strong>热情</strong>和<strong>敬畏</strong></p>
<hr>
<p>博客取名为<strong>Cestlavie</strong>，原为法语单词<code>C'est la vie</code>，中文为「这就是生活」，意在记录自己生活的喜、怒、哀、乐。</p>
<p>这个博客仅作为个人爱好，因此更新频率视个人心情与状态而定，不过我会尽量保持更新频率。</p>
<p>此外，博客仅发表个人言论，如无特殊声明，言论与本人过去、现在所处的集体无关。</p>
<p>如果不想错过我的更新，或许你可以用以下方式订阅这个博客：</p>
<ul>
<li>
<p><a href="https://www.cestlavie.moe/index.xml">通过 RSS 订阅</a></p>
</li>
<li>
<p><a href="https://t.me/CestlavieBlog">通过 Telegram 频道订阅</a></p>
</li>
</ul>
<p>同时，在我的<a href="https://t.me/CestlavieBlog">Telegram 频道</a>中，也会分享一些有意思的项目和时事信息，<del>但是可能不会分享我的搭建教程</del>。</p>
<h2 id="联系我">联系我</h2>
<p>如果您发现文章描述存在错误或侵犯您的利益，欢迎您通过以下方式和我联系。</p>
<p>我个人及其讨厌垃圾邮件和垃圾话，欢迎正式的、友好的、清晰的交流。</p>
<ul>
<li>
<p><a href="mailto:admin@cestlavie.moe">电子邮件</a></p>
</li>
<li>
<p><a href="https://t.me/CestlaviePMbot">Telegram</a></p>
</li>
<li>
<p><a href="https://m.cestlavie.moe/@Cestlavie">Mastodon</a></p>
</li>
<li>
<p>文章评论系统 <sup id="fnref:2"><a href="#fn:2" class="footnote-ref" role="doc-noteref">2</a></sup></p>
</li>
</ul>
<h2 id="版权">版权</h2>
<p>除特别声明外，本站所有内容在 <a href="https://www.cestlavie.moe/copyright">姓名标示-非商业性-相同方式分享 4.0 国际 (CC BY-NC-SA 4.0) 协议</a> 下进行许可。</p>
<blockquote>
<p>感谢阅读到此处，祝您生活愉快、万事胜意！</p>
</blockquote>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>现在博客源码托管在 GitHub 私有仓库，静态网站由 Cloudflare Pages 托管。&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
<li id="fn:2">
<p>博客使用 Giscus 评论系统，它支持 Markdown 和 Emoji 反应，但是需要登录 GitHub 账号才能评论。&#160;<a href="#fnref:2" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    <item>
      <title>Hello Hugo——记Hugo博客搭建</title>
      <link>https://www.cestlavie.moe/posts/hello-hugo/</link>
      <pubDate>Thu, 29 Dec 2022 12:04:03 +0000</pubDate>
      
      <guid>https://www.cestlavie.moe/posts/hello-hugo/</guid>
      <description>一次Hugo &amp;amp; PaperMod 博客的搭建历程</description>
      <content:encoded><![CDATA[<h2 id="前言">前言</h2>
<p>突发奇想想做个博客，受到 <a href="https://www.dejavu.moe">Dejavu</a> 的启发选择了 <a href="https://gohugo.io">Hugo</a> + <a href="https://github.com/adityatelange/hugo-PaperMod">PaperMod</a> 。因为想要做到真正的<em><strong>高可用</strong></em>，所以选择了 <a href="https://pages.cloudflare.com/">Cloudflare Pages</a><sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> 。实际上，在使用过程中，Cloudflare Pages 的编译和发布速度都相当的快。</p>
<h2 id="安装-hugo">安装 Hugo</h2>
<p>我使用的是 Ubuntu 下的<code>snap</code>进行快速安装</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ snap install hugo
</span></span></code></pre></div><p>在 Windows 系统下，我还是建议 使用 <code>scoop</code> 管理 Windows 下的软件和开发环境，安装 <code>Hugo</code> 也很简单</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ scoop install hugo-extended
</span></span></code></pre></div><h2 id="初始化博客">初始化博客</h2>
<p>这步是在本地新建一个 <code>blog</code>目录存放博客相关的文件，并初始化 git</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ hugo new site blog
</span></span><span class="line"><span class="cl">$ <span class="nb">cd</span> blog  <span class="o">&amp;&amp;</span>  git init
</span></span></code></pre></div><p>设置默认分支为 <code>main</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ git config --global init.defaultBranch main
</span></span></code></pre></div><h2 id="安装主题">安装主题</h2>
<p>博客使用 git 进行版本管理，所以如果使用 git 方式安装主题的话，要将主题添加给 git 子模块</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1">## Git 方式安装主题</span>
</span></span><span class="line"><span class="cl">$ git clone https://github.com/adityatelange/hugo-PaperMod themes/PaperMod --depth<span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 添加 Hugo-Papermod 主题为子模块</span>
</span></span><span class="line"><span class="cl">$ git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
</span></span><span class="line"><span class="cl"><span class="c1"># 如果以后从 Git 托管平台克隆博客的时候，子模块可能不会被克隆（比如 GitHub）</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 修改子模块中的文件在`git commit`时无效</span>
</span></span><span class="line"><span class="cl">$ git submodule update --init --recursive
</span></span></code></pre></div><p>现在这个博客路径如下</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">blog:.
</span></span><span class="line"><span class="cl">│   .gitmodules      <span class="c1"># Git 子模块</span>
</span></span><span class="line"><span class="cl">│   config.toml      <span class="c1"># Hugo 配置文件，建议转换成 Yaml 格式</span>
</span></span><span class="line"><span class="cl">├───archetypes     <span class="c1"># 模板，类似于 Hexo 的 scaffolds</span>
</span></span><span class="line"><span class="cl">│       default.md   <span class="c1"># 默认模板</span>
</span></span><span class="line"><span class="cl">├───content        <span class="c1"># 内容路径，文章和页面的 Markdown 文件都放这里</span>
</span></span><span class="line"><span class="cl">├───data           <span class="c1"># 储存供模板调用的数据文件？暂时用不上不管它</span>
</span></span><span class="line"><span class="cl">├───layouts        <span class="c1"># 布局目录</span>
</span></span><span class="line"><span class="cl">├───static         <span class="c1"># 静态文件目录(构建时全部拷贝到 /public 里，相当于网站资源的根目录)</span>
</span></span><span class="line"><span class="cl">└───themes         <span class="c1"># 主题目录</span>
</span></span></code></pre></div><h2 id="修改配置">修改配置</h2>
<p>博主习惯使用<code>yaml</code>而不是默认的<code>toml</code>，所以使用了<code>config.yaml</code>并删除了原有的<code>config.toml</code></p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ rm config.toml
</span></span><span class="line"><span class="cl">$ touch config.yaml
</span></span><span class="line"><span class="cl">$ vim config.yaml <span class="c1">#使用 vim 编辑，你也可以选择使用 vi, nano 等</span>
</span></span></code></pre></div><p>配置文件</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="c">#基础配置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">baseURL</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;https://www.cestlavie.moe&#34;</span><span class="c">#站点地址</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;C&#39;est la vie&#34;</span><span class="c">#站点标题</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">languageCode</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;zh&#34;</span><span class="w"> </span><span class="c"># 语 言 编 码 (如 简 体 中 文 : zh)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">DefaultContentLanguage</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;zh&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">hasCJKLanguage</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">  </span><span class="c"># 检 测  CJK</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">paginate</span><span class="p">:</span><span class="w"> </span><span class="m">6</span><span class="w">           </span><span class="c"># 每 个 分 页 文 章 数</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">paginatePath</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;page&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">permalinks</span><span class="p">:</span><span class="w">           </span><span class="c"># 永 久 连 结 格 式</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">post</span><span class="p">:</span><span class="w"> </span><span class="l">/:slug/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">page</span><span class="p">:</span><span class="w"> </span><span class="l">/:filename/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">theme</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;PaperMod&#34;</span><span class="c">#使用的主题</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">enableInlineShortcodes</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 短 代 码 支 持</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">enableRobotsTXT</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 启 用  Robots.txt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildDrafts</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="c">#不生成标记为草稿的文章</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildFuture</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">buildExpired</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">enableEmoji</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">enableGitInfo</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">pygmentsUseClasses</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c">#高级配置</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">outputs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">home</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="l">HTML</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="l">JSON</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="l">RSS </span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ShowFullTextinRSS</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c">#启用 RSS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">env</span><span class="p">:</span><span class="w"> </span><span class="l">production</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">defaultTheme</span><span class="p">:</span><span class="w"> </span><span class="l">auto</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">disableScrollToTop</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ShowWordCount</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ShowShareButtons</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ShareButtons</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;telegram&#39;</span><span class="p">]</span><span class="w"> </span><span class="c">#显示分享按钮 可选 twitter, linkedin, reddit, facebook, whatsapp, telegram</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">socialIcons</span><span class="p">:</span><span class="w"> </span><span class="c">#社交平台小图标 支持列表 https://adityatelange.github.io/hugo-PaperMod/posts/papermod/papermod-icons/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;github&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://www.github.com/Jonathan523</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;telegram&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://t.me/azureforstudent</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;email&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">mailto:admin@cestlavie.moe</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;rss&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://www.cestlavie.moe/index.xml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;pgp&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">https://pgp.cestlavie.moe/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">homeInfoParams</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">Title</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;Hi there \U0001F44B&#34;</span><span class="w"> </span><span class="c">#博客主页上的大标题</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">Content</span><span class="p">:</span><span class="w"> </span><span class="l">I am **Jonathan Zhang**. Welcome</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="l">to my personal blog! Here I share my **thoughts**, **opinions** and **life journal**</span><span class="w"> </span><span class="c">#博客主页上的介绍</span><span class="w">
</span></span></span></code></pre></div><p>其他的配置参考 <a href="https://gohugo.io/documentation/">Hugo 文档</a> &amp; <a href="https://adityatelange.github.io/hugo-PaperMod/">Papermod 主题文档</a> 就好啦~</p>
<h1 id="添加评论系统">添加评论系统</h1>
<h2 id="在配置文件中添加启用评论">在配置文件中添加启用评论。</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">params</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">comments</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span></code></pre></div><h3 id="选择评论系统">选择评论系统</h3>
<p>博主此处选择的是支持支持多语言、自定义主题、高级配置的<code>giscus</code>。</p>
<h3 id="配置评论系统">配置评论系统</h3>
<h3 id="创建用于存储评论的-github-存储库">创建用于存储评论的 GitHub 存储库</h3>
<p>我们需要创建一个<strong>公开</strong>的 GitHub 存储库并在存储库设置中启用<code>Discussions</code>功能。</p>
<h4 id="安装-giscus-app">安装 Giscus App</h4>
<p>打开浏览器，点击 <a href="https://github.com/apps/giscus">安装 Giscus App</a>，如果不想授权所有 GitHub 存储库，可以只选择用于评论的存储库。
在 <a href="https://giscus.app/zh-CN">Giscus Website</a> 设置语言、GitHub 存储库和个性化配置，博主使用的是 <code>pathname</code>
在下面可以看到启用 Giscus 的配置，比如我的就是：</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://giscus.app/client.js&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-repo</span><span class="o">=</span><span class="s">&#34;Jonathan523/CestlavieMoe&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-repo-id</span><span class="o">=</span><span class="s">&#34;R_kgDOIsRLLA&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-category</span><span class="o">=</span><span class="s">&#34;General&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-category-id</span><span class="o">=</span><span class="s">&#34;DIC_kwDOIsRLLM4CTTw2&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-mapping</span><span class="o">=</span><span class="s">&#34;pathname&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-strict</span><span class="o">=</span><span class="s">&#34;1&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-reactions-enabled</span><span class="o">=</span><span class="s">&#34;1&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-emit-metadata</span><span class="o">=</span><span class="s">&#34;1&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-input-position</span><span class="o">=</span><span class="s">&#34;top&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-theme</span><span class="o">=</span><span class="s">&#34;preferred_color_scheme&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-lang</span><span class="o">=</span><span class="s">&#34;zh-CN&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">data-loading</span><span class="o">=</span><span class="s">&#34;lazy&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">crossorigin</span><span class="o">=</span><span class="s">&#34;anonymous&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="na">async</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><h4 id="配置-hugo">配置 Hugo</h4>
<p>只需要在博客根目录的<code>/layouts/partials</code>/ 下新建一个 <code>comments.html</code> 文件，将上一步启用 Giscus 时的配置粘贴进去保存</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ mkdir -p /layouts/partials/
</span></span><span class="line"><span class="cl">$ vim comments.html
</span></span></code></pre></div><h2 id="创建菜单">创建菜单</h2>
<p>配置文件中添加以下内容</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">menu</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">main</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">home</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">首页</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">categories</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">分类</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/categories/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">tags</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">标签</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/tags/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">archives</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">归档</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/archives/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">search</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">搜索</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/search/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">links</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">友链</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/links/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">5</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span>- <span class="nt">identifier</span><span class="p">:</span><span class="w"> </span><span class="l">about</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">关于</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">url</span><span class="p">:</span><span class="w"> </span><span class="l">/about/</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">weight</span><span class="p">:</span><span class="w"> </span><span class="m">4</span><span class="w">
</span></span></span></code></pre></div><p>然后生成对应文件，<code>tags</code>和<code>categories</code>无需生成
在博客根目录下运行</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">$ hugo new archives.md
</span></span><span class="line"><span class="cl">$ hugo new search.md
</span></span></code></pre></div><p>然后在 <code>/content/archives.md</code> 写入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;归档&#34;
</span></span><span class="line"><span class="cl">layout: &#34;archives&#34;
</span></span><span class="line"><span class="cl">url: &#34;/archives/&#34;
</span></span><span class="line"><span class="cl">summary: archives
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></div><p>在  <code>/content/search.md</code> 写入</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;搜索&#34; # in any language you want
</span></span><span class="line"><span class="cl">layout: &#34;search&#34; # is necessary
</span></span><span class="line"><span class="cl">url: &#34;/search&#34;
</span></span><span class="line"><span class="cl">description: &#34;输入关键词以检索内容&#34;
</span></span><span class="line"><span class="cl">summary: &#34;search&#34;
</span></span><span class="line"><span class="cl">placeholder: &#34;搜索&#34;
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></div><h2 id="配置菜单页的中文标题">配置菜单页的中文标题</h2>
<p>默认情况下，菜单也中的分类和标签页的默认标题为英文。为了将其自定义为中文，我们需要在<code>/content</code>目录中新建<code>/tags</code>和<code>/categories</code>目录，并配置好<code>_index.md</code>。
例如</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">---
</span></span><span class="line"><span class="cl">title: &#34;标签&#34;
</span></span><span class="line"><span class="cl">---
</span></span></code></pre></div><h2 id="完成后提交生成即可">完成后提交生成即可</h2>
<h2 id="参考文献">参考文献</h2>
<ul>
<li><a href="https://www.dejavu.moe/posts/hexo-to-hugo/">记录一次博客从 Hexo 迁移到 Hugo - Dejavu Moe </a></li>
</ul>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p>Cloudflare Pages还有无限流量、部署方便快速、全球低延迟访问的特点&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content:encoded>
    </item>
    
    
    
    <item>
      <title>友链</title>
      <link>https://www.cestlavie.moe/links/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>https://www.cestlavie.moe/links/</guid>
      <description>Dejavu&amp;#39;s Blog 与君初相见，犹如故人归 Sulv&amp;#39;s Blog 一个记录技术、阅读、生活的博客 P3TERX ZONE 一个萌新的博客</description>
      <content:encoded><![CDATA[<a target="_blank" href=https://www.dejavu.moe title=Dejavu&#39;s&#32;Blog class="friendurl">
  <div class="frienddiv">
    <div class="frienddivleft">
      <img class="myfriend" src=https://www.cestlavie.moe/image/links/dejavu.moe.webp />
    </div>
    <div class="frienddivright">
      <div class="friendname">Dejavu&#39;s Blog</div>
      <div class="friendinfo">与君初相见，犹如故人归</div>
    </div>
  </div>
</a>
<a target="_blank" href=https://www.sulvblog.cn/ title=Sulv&#39;s&#32;Blog class="friendurl">
  <div class="frienddiv">
    <div class="frienddivleft">
      <img class="myfriend" src=https://www.cestlavie.moe/image/links/sulvblog.gif />
    </div>
    <div class="frienddivright">
      <div class="friendname">Sulv&#39;s Blog</div>
      <div class="friendinfo">一个记录技术、阅读、生活的博客</div>
    </div>
  </div>
</a>
<a target="_blank" href=https://p3terx.com/ title=P3TERX&#32;ZONE class="friendurl">
  <div class="frienddiv">
    <div class="frienddivleft">
      <img class="myfriend" src=https://www.cestlavie.moe/image/links/p3terx.com.webp />
    </div>
    <div class="frienddivright">
      <div class="friendname">P3TERX ZONE</div>
      <div class="friendinfo">一个萌新的博客</div>
    </div>
  </div>
</a>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
