<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>miuo</title>
    <description>记录文章、笔记、实验和暂时不想丢掉的内容。</description>
    <link>https://miuo.me/</link>
    <atom:link href="https://miuo.me/rss.xml" rel="self" type="application/rss+xml"/>
    
    <item>
      <title>VMISS LA TRI Basic 1C1G Benchmark</title>
      <link>https://miuo.me/posts/vmiss-la-tri-basic</link>
      <guid isPermaLink="true">https://miuo.me/posts/vmiss-la-tri-basic</guid>
      <description>VMISS 洛杉矶三网优化 Basic 1 核 1G 性能基准测试：硬件、IP、网络与回程路由一览。</description>
      <content:encoded><![CDATA[<p>:::: tabs
::: tab-item 💻基本信息</p>
<p><img src="https://img.miuo.me/file/s/2b0RvP02.webp" alt="image"></p>
<p>:::
::: tab-item 🎬IP质量</p>
<p><img src="https://img.miuo.me/file/s/J8i8qO3j.webp" alt="image"></p>
<p>:::
::: tab-item 🌐网络质量</p>
<p><img src="https://img.miuo.me/file/s/a3zwZBac.webp" alt="image"></p>
<p>:::
::: tab-item 📍回程路由</p>
<p><img src="https://img.miuo.me/file/s/pVSidCLJ.webp" alt="image"></p>
<p>:::
::::</p>
]]></content:encoded>
      <pubDate>Wed, 22 Jul 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Minecraft 最速极简开服指南</title>
      <link>https://miuo.me/posts/minecraft-fast-server-setup</link>
      <guid isPermaLink="true">https://miuo.me/posts/minecraft-fast-server-setup</guid>
      <description>基于 MCSManager 面板的 Minecraft 极简开服教程，从面板安装到性能优化与插件配置。</description>
      <content:encoded><![CDATA[<h2>1. 安装 MCSManager 面板</h2>
<p>极简攻略首选面板，推荐 <a href="https://mcsmanager.com/">MCSManager</a>。</p>
<p>第一步安装 Debian 系统和各种初始化可以参见 <a href="/posts/vps-setup-from-scratch">VPS 从零开始</a> 这篇文章，不用安装 1Panel 面板以节省性能。</p>
<p>网络允许的话可以用：</p>
<pre><code class="language-bash">wget -qO- https://script.mcsmanager.com/setup.sh | bash
</code></pre>
<p>国内网络不允许的话：</p>
<pre><code class="language-bash"># 1. 回到主目录并临时关闭 wget 证书检查
cd ~
echo &quot;check_certificate = off&quot; &gt; ~/.wgetrc

# 2. 运行国内版一键脚本
wget -qO- https://script.mcsmanager.com/setup_cn.sh | bash

# 3. 安装完成后删除临时规则，保持系统纯净
rm ~/.wgetrc
</code></pre>
<h2>2. 放行端口</h2>
<p>放行以下端口：</p>
<ul>
<li><code>23333</code> — MCSManager 面板 Web 端（访问 <code>http://你的IP:23333</code>）</li>
<li><code>24444</code> — MCSManager 守护进程通信端口（面板与后端之间）</li>
<li><code>25565</code> — Java 版默认联机端口，玩家连接用</li>
</ul>
<p>如果配置了 UFW：</p>
<pre><code class="language-bash">sudo ufw allow 23333/tcp
sudo ufw allow 24444/tcp
sudo ufw allow 25565/tcp
</code></pre>
<p>查看放行状态确认：</p>
<pre><code class="language-bash">sudo ufw status
</code></pre>
<p>如果看到三个端口都显示 <code>ALLOW Anywhere</code>，说明系统层面的防火墙已全部放行。</p>
<h2>3. 创建实例</h2>
<p>模板市场直接搜 <strong>Paper</strong>，这个比较轻量。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711123722h23uPu.webp" alt="">
<img src="https://s3.2731515.xyz/PicGo/202607111238266jy5cJ.webp" alt=""></p>
<p>网络允许的话选择需要的版本下载即可。由于我的服务器没有代理，所以手动安装。</p>
<p>举例想玩 26.1.2 版本，先下载对应的 Java 25：</p>
<pre><code class="language-bash">sudo apt update
sudo apt install openjdk-25-jre-headless -y
</code></pre>
<p>然后创建实例，选择直接创建。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711124304vglkNo.webp" alt=""></p>
<p>实例名称随意，示例类型选择 <strong>MC Java 版服务器</strong>。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711124347O01scT.webp" alt=""></p>
<h3>3.1 配置 Java 环境</h3>
<p>进入实例信息面板，第一步点 <strong>Java 环境管理</strong>，选择安装好的 Java 25。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711124545VYMHu2.webp" alt=""></p>
<p>名称随意，路径一般是 <code>/usr/bin/java</code>，也可以 SSH 输入：</p>
<pre><code class="language-bash">which java
</code></pre>
<p>查看 Java 安装路径。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711124635A0TrHm.webp" alt=""></p>
<h3>3.2 上传 Paper 文件</h3>
<p>进入 <a href="https://papermc.io/">Paper 官网</a>，下载对应版本的 jar 文件。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711125118qSp7aP.webp" alt=""></p>
<p>点击实例信息面板的 <strong>文件管理</strong>，直接把下载好的 paper jar 文件拖入。</p>
<p>接着点击实例信息面板的 <strong>应用示例设置</strong>，启动命令改成：</p>
<pre><code class="language-bash">java -Xms3500M -Xmx3500M -jar paper-26.1.2-74.jar nogui
</code></pre>
<p><code>Xms</code> 和 <code>Xmx</code> 根据服务器内存自行替换，建议两个设成一样。其他全部不用动。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260711125500E20D8Q.webp" alt=""></p>
<h3>3.3 启动实例</h3>
<p>回到控制台点击右上角的 <strong>启动</strong>，会发现刚启动立刻终止。接着点击 <strong>文件管理</strong>，找到 <code>eula.txt</code> 文件，把 <code>eula=false</code> 改成 <code>eula=true</code> 然后保存（Mojang 的最终用户许可协议，改完即表示同意）。</p>
<p>再次点击启动即可。</p>
<h2>4. 性能优化</h2>
<h3>4.1 修改 <code>server.properties</code></h3>
<p>找到并双击打开 <code>server.properties</code>，修改以下数值，改完记得点保存：</p>
<ul>
<li><code>view-distance=6</code> （视距调低）</li>
<li><code>simulation-distance=6</code> （模拟距离调低）</li>
<li><code>network-compression-threshold=64</code> （优化网络包）</li>
</ul>
<h3>4.2 修改 <code>paper-world-defaults.yml</code></h3>
<p>找到对应字段改成下面的值：</p>
<ul>
<li><code>hopper.disable-move-event:</code> <code>false</code> → <code>true</code>（漏斗优化）</li>
<li><code>collisions.max-entity-collisions:</code> <code>8</code> → <code>4</code>（实体碰撞上限）</li>
<li><code>environment.optimize-explosions:</code> <code>false</code> → <code>true</code>（爆炸优化）</li>
<li><code>chunks.entity-per-chunk-save-limit.arrow:</code> <code>-1</code> → <code>16</code>（限制箭矢堆积）</li>
<li><code>chunks.entity-per-chunk-save-limit.experience_orb:</code> <code>-1</code> → <code>16</code>（限制经验球堆积）</li>
</ul>
<blockquote>
<p>[!note]
以上几项均为安全优化，基本不影响普通生存。但对于红石机器、TNT 复制等高精度生电设施可能有影响，生电玩家建议按需保持默认值。</p>
</blockquote>
<h2>5. 插件推荐</h2>
<h3>Chunky</h3>
<p><a href="https://modrinth.com/plugin/chunky">https://modrinth.com/plugin/chunky</a></p>
<p>可以预渲染地图存到硬盘，防止跑图卡顿。设置半径 5000 格并开始预生成：</p>
<pre><code>chunky radius 5000
chunky start
</code></pre>
<p>查看进度：</p>
<pre><code>chunky progress
</code></pre>
<h3>AuthMe</h3>
<p><a href="https://github.com/AuthMe/AuthMeReloaded">https://github.com/AuthMe/AuthMeReloaded</a></p>
<p>负责强制每个人进服时输入密码（<code>/register</code> 和 <code>/login</code>），防止别人冒充名字进服。</p>
<h2>6. 常用命令</h2>
<h3>自带白名单</h3>
<p>开启白名单功能：</p>
<pre><code>whitelist on
</code></pre>
<p>添加白名单（假设朋友游戏名叫 <code>steve</code>）：</p>
<pre><code>whitelist add steve
</code></pre>
<p>查看白名单：</p>
<pre><code>whitelist list
</code></pre>
<p>移除白名单：</p>
<pre><code>whitelist remove 名字
</code></pre>
<h3>其他</h3>
<ul>
<li><code>server.properties</code> 里 <code>online-mode=false</code> 关闭正版验证，防止朋友进不来</li>
<li><code>op 名字</code> 设为管理员权限</li>
<li>域名加 <code>25565</code> 端口进入服务器</li>
</ul>
]]></content:encoded>
      <pubDate>Fri, 10 Jul 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Windows 终端美化</title>
      <link>https://miuo.me/posts/windows-terminal-beautify</link>
      <guid isPermaLink="true">https://miuo.me/posts/windows-terminal-beautify</guid>
      <description>基于 YouTube 教程改进，使用 scoop 安装 JetBrainsMono Nerd Font、Fastfetch、chafa 等工具美化 Windows 终端。</description>
      <content:encoded><![CDATA[<blockquote>
<p>本教程基于 <a href="https://www.youtube.com/watch?v=z3NpVq-y6jU">YouTube: Your Terminal is Boring… Fix It</a> 改进，所有工具均通过 scoop 安装。</p>
</blockquote>
<p>因为有轻量预览 Markdown 文件的需求，准备尝试一下 Neovim，发现默认样式很丑。接着看 Windows 默认的 PowerShell 也不顺眼，顺便一起改了。</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260704171443qID1HK.webp" alt=""></p>
<h2>1. 字体基础配置</h2>
<p>所有美化前提是拥有一款支持 Nerd Font 的字体，才能正确渲染图标。</p>
<pre><code class="language-powershell">scoop bucket add nerd-fonts
scoop install JetBrainsMono-NF
</code></pre>
<p>Windows Terminal 中设置 <code>JetBrainsMonoNL Nerd Font</code>，并在 JSON 配置中将 <code>cellHeight</code> 设为 <code>1.2</code>。</p>
<h2>2. Windows Terminal 界面美化</h2>
<p><code>Ctrl + ,</code> 打开设置，编辑 <code>settings.json</code>：</p>
<pre><code class="language-json">{
    &quot;$help&quot;: &quot;https://aka.ms/terminal-documentation&quot;,
    &quot;$schema&quot;: &quot;https://aka.ms/terminal-profiles-schema&quot;,
    &quot;actions&quot;: [
        {
            &quot;command&quot;: {
                &quot;action&quot;: &quot;copy&quot;,
                &quot;singleLine&quot;: false
            },
            &quot;id&quot;: &quot;User.copy.644BA8F2&quot;
        },
        {
            &quot;command&quot;: &quot;paste&quot;,
            &quot;id&quot;: &quot;User.paste&quot;
        },
        {
            &quot;command&quot;: &quot;find&quot;,
            &quot;id&quot;: &quot;User.find&quot;
        },
        {
            &quot;command&quot;: {
                &quot;action&quot;: &quot;splitPane&quot;,
                &quot;split&quot;: &quot;auto&quot;,
                &quot;splitMode&quot;: &quot;duplicate&quot;
            },
            &quot;id&quot;: &quot;User.splitPane.A6751878&quot;
        }
    ],
    &quot;alwaysOnTop&quot;: false,
    &quot;copyFormatting&quot;: &quot;none&quot;,
    &quot;copyOnSelect&quot;: false,
    &quot;defaultProfile&quot;: &quot;{61c54bbd-c2c6-5271-96e7-009a87ff44bf}&quot;,
    &quot;keybindings&quot;: [
        {
            &quot;id&quot;: &quot;User.copy.644BA8F2&quot;,
            &quot;keys&quot;: &quot;ctrl+c&quot;
        },
        {
            &quot;id&quot;: &quot;User.find&quot;,
            &quot;keys&quot;: &quot;ctrl+shift+f&quot;
        },
        {
            &quot;id&quot;: &quot;User.paste&quot;,
            &quot;keys&quot;: &quot;ctrl+v&quot;
        },
        {
            &quot;id&quot;: &quot;User.splitPane.A6751878&quot;,
            &quot;keys&quot;: &quot;alt+shift+d&quot;
        }
    ],
    &quot;newTabMenu&quot;: [
        {
            &quot;type&quot;: &quot;remainingProfiles&quot;
        }
    ],
    &quot;profiles&quot;: {
        &quot;defaults&quot;: {
            &quot;colorScheme&quot;: &quot;Catppuccin Mocha&quot;,
            &quot;cursorShape&quot;: &quot;filledBox&quot;,
            &quot;experimental.retroTerminalEffect&quot;: false,
            &quot;font&quot;: {
                &quot;builtinGlyphs&quot;: true,
                &quot;cellHeight&quot;: &quot;1.2&quot;,
                &quot;colorGlyphs&quot;: true,
                &quot;face&quot;: &quot;JetBrainsMonoNL Nerd Font&quot;,
                &quot;size&quot;: 10,
                &quot;weight&quot;: &quot;extra-black&quot;
            },
            &quot;intenseTextStyle&quot;: &quot;all&quot;,
            &quot;opacity&quot;: 80,
            &quot;padding&quot;: &quot;8&quot;,
            &quot;useAcrylic&quot;: true
        },
        &quot;list&quot;: [
            {
                &quot;commandline&quot;: &quot;%SystemRoot%\\System32\\WindowsPowerShell\\v1.0\\powershell.exe&quot;,
                &quot;guid&quot;: &quot;{61c54bbd-c2c6-5271-96e7-009a87ff44bf}&quot;,
                &quot;hidden&quot;: false,
                &quot;name&quot;: &quot;Windows PowerShell&quot;
            },
            {
                &quot;commandline&quot;: &quot;%SystemRoot%\\System32\\cmd.exe&quot;,
                &quot;guid&quot;: &quot;{0caa0dad-35be-5f56-a8ff-afceeeaa6101}&quot;,
                &quot;hidden&quot;: false,
                &quot;name&quot;: &quot;Command Prompt&quot;
            },
            {
                &quot;guid&quot;: &quot;{b453ae62-4e3d-5e58-b989-0a998ec441b8}&quot;,
                &quot;hidden&quot;: false,
                &quot;name&quot;: &quot;Azure Cloud Shell&quot;,
                &quot;source&quot;: &quot;Windows.Terminal.Azure&quot;
            }
        ]
    },
    &quot;schemes&quot;: [
        {
            &quot;background&quot;: &quot;#1E1E2E&quot;,
            &quot;black&quot;: &quot;#45475A&quot;,
            &quot;blue&quot;: &quot;#89B4FA&quot;,
            &quot;brightBlack&quot;: &quot;#585B70&quot;,
            &quot;brightBlue&quot;: &quot;#89B4FA&quot;,
            &quot;brightCyan&quot;: &quot;#94E2D5&quot;,
            &quot;brightGreen&quot;: &quot;#A6E3A1&quot;,
            &quot;brightPurple&quot;: &quot;#F5C2E7&quot;,
            &quot;brightRed&quot;: &quot;#F38BA8&quot;,
            &quot;brightWhite&quot;: &quot;#A6ADC8&quot;,
            &quot;brightYellow&quot;: &quot;#F9E2AF&quot;,
            &quot;cursorColor&quot;: &quot;#F5E0DC&quot;,
            &quot;cyan&quot;: &quot;#94E2D5&quot;,
            &quot;foreground&quot;: &quot;#CDD6F4&quot;,
            &quot;green&quot;: &quot;#A6E3A1&quot;,
            &quot;name&quot;: &quot;Catppuccin Mocha&quot;,
            &quot;purple&quot;: &quot;#F5C2E7&quot;,
            &quot;red&quot;: &quot;#F38BA8&quot;,
            &quot;selectionBackground&quot;: &quot;#585B70&quot;,
            &quot;white&quot;: &quot;#BAC2DE&quot;,
            &quot;yellow&quot;: &quot;#F9E2AF&quot;
        },
        {
            &quot;background&quot;: &quot;#000000&quot;,
            &quot;black&quot;: &quot;#0C0C0C&quot;,
            &quot;blue&quot;: &quot;#0037DA&quot;,
            &quot;brightBlack&quot;: &quot;#767676&quot;,
            &quot;brightBlue&quot;: &quot;#3B78FF&quot;,
            &quot;brightCyan&quot;: &quot;#61D6D6&quot;,
            &quot;brightGreen&quot;: &quot;#16C60C&quot;,
            &quot;brightPurple&quot;: &quot;#B4009E&quot;,
            &quot;brightRed&quot;: &quot;#E74856&quot;,
            &quot;brightWhite&quot;: &quot;#F2F2F2&quot;,
            &quot;brightYellow&quot;: &quot;#F9F1A5&quot;,
            &quot;cursorColor&quot;: &quot;#FFFFFF&quot;,
            &quot;cyan&quot;: &quot;#3A96DD&quot;,
            &quot;foreground&quot;: &quot;#FFFFFF&quot;,
            &quot;green&quot;: &quot;#13A10E&quot;,
            &quot;name&quot;: &quot;Color Scheme 15&quot;,
            &quot;purple&quot;: &quot;#881798&quot;,
            &quot;red&quot;: &quot;#C50F1F&quot;,
            &quot;selectionBackground&quot;: &quot;#FFFFFF&quot;,
            &quot;white&quot;: &quot;#CCCCCC&quot;,
            &quot;yellow&quot;: &quot;#C19C00&quot;
        },
        {
            &quot;background&quot;: &quot;#282A36&quot;,
            &quot;black&quot;: &quot;#21222C&quot;,
            &quot;blue&quot;: &quot;#BD93F9&quot;,
            &quot;brightBlack&quot;: &quot;#6272A4&quot;,
            &quot;brightBlue&quot;: &quot;#D6ACFF&quot;,
            &quot;brightCyan&quot;: &quot;#A4FFFF&quot;,
            &quot;brightGreen&quot;: &quot;#69FF94&quot;,
            &quot;brightPurple&quot;: &quot;#FF92DF&quot;,
            &quot;brightRed&quot;: &quot;#FF6E6E&quot;,
            &quot;brightWhite&quot;: &quot;#FFFFFF&quot;,
            &quot;brightYellow&quot;: &quot;#FFFFA5&quot;,
            &quot;cursorColor&quot;: &quot;#F8F8F2&quot;,
            &quot;cyan&quot;: &quot;#8BE9FD&quot;,
            &quot;foreground&quot;: &quot;#F8F8F2&quot;,
            &quot;green&quot;: &quot;#50FA7B&quot;,
            &quot;name&quot;: &quot;Dracula&quot;,
            &quot;purple&quot;: &quot;#FF79C6&quot;,
            &quot;red&quot;: &quot;#FF5555&quot;,
            &quot;selectionBackground&quot;: &quot;#44475A&quot;,
            &quot;white&quot;: &quot;#F8F8F2&quot;,
            &quot;yellow&quot;: &quot;#F1FA8C&quot;
        }
    ],
    &quot;tabWidthMode&quot;: &quot;titleLength&quot;,
    &quot;themes&quot;: [],
    &quot;useAcrylicInTabRow&quot;: true
}
</code></pre>
<h2>3. PowerShell 配置文件</h2>
<p><code>$PROFILE</code> 查看 PowerShell 配置文件路径。</p>
<p>如果文件夹为空，执行：</p>
<pre><code class="language-powershell">New-Item -Path $profile.CurrentUserAllHosts -Type File -Force
</code></pre>
<p>编辑 <code>profile.ps1</code>：</p>
<pre><code class="language-powershell"># Minimal profile: UTF‑8 + Oh My Posh (if installed) + Fastfetch with explicit config path
try {
    [Console]::InputEncoding  = [System.Text.Encoding]::UTF8
    [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
    $OutputEncoding = [System.Text.UTF8Encoding]::new($false)
    chcp 65001 &gt; $null
} catch {}

Clear-Host

# Force Fastfetch to use YOUR config every time (bypass path confusion)
if (Get-Command fastfetch -ErrorAction SilentlyContinue) {
    fastfetch -c &quot;C:/Users/Sakura/.config/fastfetch/config.jsonc&quot;
}
</code></pre>
<h2>4. <a href="https://github.com/fastfetch-cli/fastfetch">Fastfetch</a></h2>
<p>系统信息展示工具，类似 Neofetch，每次打开终端时显示系统概览。</p>
<pre><code class="language-powershell">scoop install fastfetch
</code></pre>
<p>创建 <code>C:\Users\Sakura\.config\fastfetch\</code>，目录下放两个文件。</p>
<p><code>config.jsonc</code>：</p>
<pre><code class="language-jsonc">{
  &quot;$schema&quot;: &quot;https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json&quot;,
  &quot;logo&quot;: {
    &quot;type&quot;: &quot;file&quot;,
    &quot;source&quot;: &quot;C:/Users/Sakura/.config/fastfetch/ascii.txt&quot;,
    &quot;color&quot;: {
      &quot;1&quot;: &quot;#F5E0DC&quot;,
      &quot;2&quot;: &quot;#F2CDCD&quot;,
      &quot;3&quot;: &quot;#F5C2E7&quot;,
      &quot;4&quot;: &quot;#FAB387&quot;,
      &quot;5&quot;: &quot;#F9E2AF&quot;,
      &quot;6&quot;: &quot;#A6E3A1&quot;,
      &quot;7&quot;: &quot;#94E2D5&quot;,
      &quot;8&quot;: &quot;#89DCEB&quot;,
      &quot;9&quot;: &quot;#74C7EC&quot;
    },
    &quot;padding&quot;: {
      &quot;top&quot;: 1,
      &quot;right&quot;: 3
    }
  },
  &quot;display&quot;: {
    &quot;separator&quot;: &quot; &quot;
  },
  &quot;modules&quot;: [
    &quot;break&quot;,
    {
      &quot;type&quot;: &quot;title&quot;,
      &quot;color&quot;: {
        &quot;user&quot;: &quot;#F5C2E7&quot;,
        &quot;at&quot;: &quot;#CDD6F4&quot;,
        &quot;host&quot;: &quot;#89DCEB&quot;
      }
    },
    &quot;break&quot;,
    {
      &quot;type&quot;: &quot;os&quot;,
      &quot;key&quot;: &quot;&quot;,
      &quot;keyColor&quot;: &quot;#89DCEB&quot;
    },
    {
      &quot;type&quot;: &quot;cpu&quot;,
      &quot;key&quot;: &quot;&quot;,
      &quot;keyColor&quot;: &quot;#F5C2E7&quot;
    },
    {
      &quot;type&quot;: &quot;board&quot;,
      &quot;key&quot;: &quot;󰚗&quot;,
      &quot;keyColor&quot;: &quot;#FAB387&quot;
    },
    {
      &quot;type&quot;: &quot;memory&quot;,
      &quot;key&quot;: &quot;&quot;,
      &quot;keyColor&quot;: &quot;#A6E3A1&quot;,
      &quot;format&quot;: &quot;{used} / {total} ({percentage})&quot;
    },
    {
      &quot;type&quot;: &quot;disk&quot;,
      &quot;key&quot;: &quot;&quot;,
      &quot;keyColor&quot;: &quot;#94E2D5&quot;
    },
    &quot;break&quot;,
    {
      &quot;type&quot;: &quot;colors&quot;,
      &quot;symbol&quot;: &quot;circle&quot;
    }
  ]
}
</code></pre>
<p><code>ascii.txt</code> 放 ASCII 字符画，我的字符画效果见开头的截图，具体文件在 <a href="https://github.com/mistn/dotfiles/blob/master/fastfetch/ascii.txt">dotfiles/fastfetch/ascii.txt</a>。</p>
<p>记得把路径里的 <code>Sakura</code> 改成你的用户名。</p>
<h2>5. <a href="https://github.com/hpjansson/chafa">chafa</a> 字符画</h2>
<p>将图片转换为 ANSI 字符画，用来生成 Fastfetch 的 ASCII logo。</p>
<pre><code class="language-powershell">scoop install chafa
</code></pre>
<p>将图片转换为 ANSI 字符画：</p>
<pre><code class="language-powershell">cmd /c &#39;chafa --size 40x20 --colors full --symbols block &quot;C:\图片路径\xxx.jpg&quot; &gt; &quot;C:\Users\Sakura\.config\fastfetch\ascii.txt&quot;&#39;
</code></pre>
<p>PowerShell 重定向默认使用 Unicode，会导致 ANSI 字符损坏。用 <code>cmd /c</code> 走 cmd 的重定向能保持原始字节不变。</p>
<h2>6. 完整配置</h2>
<p>以上所有配置文件均托管在 <a href="https://github.com/mistn/dotfiles">mistn/dotfiles</a>。</p>
]]></content:encoded>
      <pubDate>Fri, 03 Jul 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>隐私邮箱推荐：Disroot 和 Autistici</title>
      <link>https://miuo.me/posts/privacy-email-disroot-autistici</link>
      <guid isPermaLink="true">https://miuo.me/posts/privacy-email-disroot-autistici</guid>
      <description>介绍两个注重隐私和去中心化的邮箱服务——Disroot 和 Autistici，包含注册流程和功能展示。</description>
      <content:encoded><![CDATA[<blockquote>
<p><a href="https://webmail.disroot.org/">Disroot</a> 侧重于开放网络与去中心化，提供友好的免追踪邮箱与协作工具；<a href="https://www.autistici.org/">Autistici</a> 则坚持独立与去商品化，以社区自治的方式维护基础通信安全。</p>
</blockquote>
<h2>1. Disroot 邮箱</h2>
<blockquote>
<p><strong>空间容量</strong>：2 GB，更大的空间需要向 Disroot 进行捐赠</p>
<p><strong>保号要求</strong>：每六个月登录进行保号</p>
<p><strong>申请要求</strong>：人工审核</p>
</blockquote>
<h3>1.1 注册流程</h3>
<p> <a href="https://user.disroot.org/pwm/public/newuser">注册地址</a></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260702220057YXq4fB.webp" alt=""></p>
<p>周六日休息不会审核，48 小时内没有审核通过一般默认失败</p>
<h3>1.2 邮箱页面展示</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260702220541V21X8W.webp" alt=""></p>
<h3>1.3 其他配套服务</h3>
<p><a href="https://disroot.org/#services">地址</a></p>
<p><img src="https://s3.2731515.xyz/PicGo/202607022211274hQvQs.webp" alt=""></p>
<h2>2. Autistici 邮箱</h2>
<blockquote>
<p><strong>空间容量</strong>：无限制，但是最好不要滥用</p>
<p><strong>保号要求</strong>：如果连续 12 个月未登录阅读邮件，账号将被停用，且其中的所有内容都会被彻底删除。</p>
<p><strong>申请要求</strong>：人工审核，需要写明理由，证明自己非商业用途，且认同其反监控、捍卫隐私的极客理念</p>
</blockquote>
<details>
<summary>autistici 官方宣言</summary><p>Autistici/Inventati 是一个承认并提倡反资本主义、反种族主义、反法西斯主义、反性别歧视、反军国主义，且拒绝威权与等级制度的集体。</p>
</details><h3>2.1 注册流程</h3>
<p><a href="https://services.autistici.org/">注册地址</a></p>
<ul>
<li>第一步：服务类型选择 Email 即可</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260702224213HxIGoM.webp" alt=""></p>
<ul>
<li>第二步：选择邮箱前缀和后缀</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260702224414weSeyL.webp" alt=""></p>
<ul>
<li>申请小作文只接受<strong>英语和意大利语</strong>，要写一个简短的自我介绍，再写一下申请原因（不需要透露个人信息），由于是<strong>志愿者审核</strong>，所以可能审核很长时间</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260702224518TLW4HU.webp" alt=""></p>
<h3>2.2 邮箱页面展示</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260702221820QI1Jwz.webp" alt=""></p>
<h2>3. 参考文档</h2>
<ul>
<li><a href="https://howto.disroot.org/en">Disroot 官方文档</a></li>
<li><a href="https://www.autistici.org/">Autistici 官方文档</a></li>
</ul>
]]></content:encoded>
      <pubDate>Thu, 02 Jul 2026 15:19:00 GMT</pubDate>
    </item>
    <item>
      <title>为 Artalk 接入 Resend 发信服务与自定义模板方案</title>
      <link>https://miuo.me/posts/artalk-resend-email</link>
      <guid isPermaLink="true">https://miuo.me/posts/artalk-resend-email</guid>
      <description>使用 Resend 为 Artalk 评论系统配置邮件通知，并自定义发信模板的完整方案。</description>
      <content:encoded><![CDATA[<p>目前评论区收到评论之后不会通知，传统的 SMTP（如 QQ 邮箱，网易邮箱）又不个性化，自己的 <code>noreply@yourdomain.com</code> 邮箱通知，我认为是一个比较好的个性化方案</p>
<h2>1. 为什么选择 Resend</h2>
<blockquote>
<p><strong>Resend</strong> 是一个专为开发者打造的现代电子邮件发送平台，主要用于发送验证码、订单通知、重置密码等事务性邮件以及营销邮件。它因极佳的开发者体验、现代化的 API 和高送达率，成为了目前独立开发者和 SaaS 团队的首选工具之一</p>
</blockquote>
<ul>
<li><p>首先配置方便，只需要在 <a href="https://resend.com/">Resend 官网</a>绑定域名，设置一个 API key 即可</p>
</li>
<li><p>其次有免费额度，每日发信 100 封，每月 3000 封，发信额度对个人博客来说完全够用</p>
</li>
<li><p>最后送达率很高，个人实测除了 Outlook 有时候 Spam，其他邮件基本都能进收件箱</p>
</li>
</ul>
<h2>2. Resend 配置</h2>
<h3>2.1 添加域名</h3>
<p>按图示，填写域名和选择地区，点击 <code>Add domain</code></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260629105759VODizR.webp" alt="Resend 添加域名页面"></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260629105900LjOY8f.webp" alt="域名信息填写"></p>
<p>域名托管在 Cloudflare 的话可以自动配置 DNS 记录</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260629110027UYeK9X.webp" alt="Cloudflare 自动配置 DNS"></p>
<p>之后直接点击授权，等待 DNS 传播</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260629110627j19JTL.webp" alt="DNS 授权页面"></p>
<h3>2.2 发信 API 设置</h3>
<p>添加 API key</p>
<p><img src="https://s3.2731515.xyz/PicGo/202606291116481WZ18P.webp" alt="Resend API key 创建页面"></p>
<p>根据最小权限原则可以选择仅发送权限，Name 随便写，域名选择想发信的域名</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260629111900xi1kDa.webp" alt="API key 权限选择"></p>
<p>因为 API key 只会出现一次，所以可以记到记事本里，之后还会用到。至此需要 Resend 的步骤全部配置完毕</p>
<h2>3. Artalk 后台配置</h2>
<ul>
<li>勾选启用邮件通知</li>
<li>发送方式填 smtp</li>
<li>发信人昵称填 <code>{{reply_nick}}</code></li>
<li>发信人地址填 <code>noreply@yourdomain.com</code></li>
<li>邮件标题填 <code>[{{site_name}}] 您收到了来自 @{{reply_nick}} 的回复</code></li>
<li>邮件模板文件可以先填 <code>./data/custom_email.html</code>，后面再在服务器里创建<code>custom_email.html</code> 模板文件</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260629112513H2Etgc.webp" alt="Artalk 后台邮件配置界面"></p>
<h2>4. SMTP 设置</h2>
<ul>
<li>发信地址填 <code>smtp.resend.com</code></li>
<li>发件端口可以填 <code>465</code>，如果要使用加密 / TLS 连接，可以用 <code>2465</code>，<code>587</code> 和 <code>2587</code> 端口</li>
<li>用户名必须填 <code>resend</code></li>
<li>密码填上面申请保存到记事本的 API key</li>
<li><strong>最后记得一定要点应用按钮</strong></li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260629113654cyKoZy.webp" alt="Artalk SMTP 设置界面"></p>
<h2>5. 发信模板</h2>
<p>在 Artalk 的 data 文件夹里创建 <code>custom_email.html</code> 文件</p>
<p>填入以下内容：</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;zh-CN&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;邮件通知&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 0;
        }
        .container {
            width: 100%;
            max-width: 600px;
            margin: 30px auto;
            background-color: #ffffff;
            border-radius: 10px;
            box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
        }
        .header {
            background-color: #007bff;
            color: #ffffff;
            padding: 20px;
            border-radius: 10px 10px 0 0;
            text-align: center;
        }
        .header h1 {
            margin: 0;
            font-size: 24px;
        }
        .content {
            padding: 20px;
            line-height: 1.6;
        }
        .content h2 {
            font-size: 18px;
            color: #333333;
            margin-top: 0;
        }
        .content p {
            font-size: 14px;
            color: #555555;
        }
        .content a {
            color: #007bff;
            text-decoration: none;
        }
        .comment {
            background-color: #f9f9f9;
            border-radius: 5px;
            padding: 15px;
            margin-bottom: 20px;
        }
        .comment .author {
            font-weight: bold;
            color: #333333;
        }
        .comment .text {
            margin-top: 10px;
            color: #555555;
        }
        .footer {
            text-align: center;
            padding: 20px;
            background-color: #f4f4f4;
            border-radius: 0 0 10px 10px;
            font-size: 12px;
            color: #888888;
        }
        .footer a {
            color: #007bff;
            text-decoration: none;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;div class=&quot;header&quot;&gt;
            &lt;h1&gt;您有新的回复&lt;/h1&gt;
        &lt;/div&gt;
        &lt;div class=&quot;content&quot;&gt;
            &lt;h2&gt;Hi, {{nick}}!&lt;/h2&gt;
            &lt;p&gt;您在 &lt;a href=&quot;{{page_url}}&quot; target=&quot;_blank&quot;&gt;{{page_title}}&lt;/a&gt; 上的留言有人回复了。&lt;/p&gt;
            &lt;div class=&quot;comment&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;您曾经的评论：&lt;/div&gt;
                &lt;div class=&quot;text&quot;&gt;{{content}}&lt;/div&gt;
            &lt;/div&gt;
            &lt;div class=&quot;comment&quot;&gt;
                &lt;div class=&quot;author&quot;&gt;{{reply_nick}} 回复您：&lt;/div&gt;
                &lt;div class=&quot;text&quot;&gt;{{reply_content}}&lt;/div&gt;
            &lt;/div&gt;
            &lt;p&gt;点击 &lt;a href=&quot;{{link_to_reply}}&quot; target=&quot;_blank&quot;&gt;这里&lt;/a&gt; 前往站点查看完整回复。&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class=&quot;footer&quot;&gt;
            &lt;p&gt;本邮件为系统自动发送，请勿直接回复。&lt;/p&gt;
            &lt;p&gt;Copyright © 2026 &lt;a href=&quot;https://miuo.me&quot; target=&quot;_blank&quot;&gt;miuo&lt;/a&gt;&lt;/p&gt;
        &lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<h2>6. 通知效果展示</h2>
<p><img src="https://s3.2731515.xyz/PicGo/20260629114332FddthA.webp" alt="邮件通知效果展示"></p>
<p>配置完收工，之后有人评论就能收到好看的邮件通知了</p>
]]></content:encoded>
      <pubDate>Sun, 28 Jun 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>SNI 分流与 443 端口冲突解决</title>
      <link>https://miuo.me/posts/sni-stream-split</link>
      <guid isPermaLink="true">https://miuo.me/posts/sni-stream-split</guid>
      <description>OpenResty 443 端口冲突解决与 SNI 分流配置记录。</description>
      <content:encoded><![CDATA[<blockquote>
<p>系统环境：1Panel + OpenResty (Docker) + 3x-ui + Cloudflare</p>
<p>目标：通过 Nginx <code>stream</code> 模块实现 443 端口复用，根据 SNI 自动分流 隧道流量与建站流量。</p>
<p>报错：网站访问出现 Cloudflare 525 Error (SSL handshake failed)，OpenResty 容器不断崩溃，陷入 <code>is restarting</code> 死循环。面板也随之失联。</p>
</blockquote>
<h2>修复 Docker 网络层转发</h2>
<p>OpenResty 运行在容器内，隧道流量直接转发至 <code>127.0.0.1</code> 无法触达宿主机的 3x-ui。</p>
<p>获取 1Panel 网络网关（通常为 <code>172.18.0.1</code>）：</p>
<pre><code class="language-bash">docker network inspect 1panel-network | grep Gateway
</code></pre>
<h2>完善 Stream 分流配置</h2>
<p>修改 <code>/usr/local/openresty/nginx/conf/nginx.conf</code>，将前端 443 流量分发至后端 4443 (建站) 和宿主机 8443 (隧道)：</p>
<pre><code class="language-nginx">stream {
    map $ssl_preread_server_name $backend_name {
        [www.microsoft.com](https://www.microsoft.com)  proxy_backend;
        default            web_backend;    # 正常建站域名
    }
    upstream proxy_backend {
        server 172.18.0.1:8443; # 指向 Docker 网关，穿出容器
    }
    upstream web_backend {
        server 127.0.0.1:4443;  # 网站配置与 Nginx 同容器，保留本地回环
    }
    server {
        listen 443;
        listen [::]:443;
        proxy_pass $backend_name;
        ssl_preread on; 
    }
}
</code></pre>
<h2>解决 Nginx 443 端口冲突</h2>
<p>stream 和 http 模块都在同一个容器里，都想去抢 443 端口，内核直接报 Address already in use。Nginx 一挂，1Panel 的守护机制就拼命重启容器，结果就是死循环，面板也连不上。</p>
<p>宿主机修改默认配置（将 443 改为 4443）：</p>
<pre><code class="language-bash">sed -i &#39;s/listen 443 ssl http2;/listen 4443 ssl http2;/g&#39; /opt/1panel/apps/openresty/openresty/conf/conf.d/00.default.conf
</code></pre>
<p>手动修改所有已建网站（如 wallos）的 Nginx 配置文件，将 <code>listen 443 ssl http2;</code> 替换为 <code>listen 4443 ssl http2;</code>。</p>
<p>验证配置并重启容器：</p>
<pre><code class="language-bash">docker exec -it &lt;1Panel-openresty容器名&gt; nginx -t
docker restart &lt;1Panel-openresty容器名&gt;
</code></pre>
<h2>获取真实访客 IP</h2>
<p>经过 stream 转发后后端收到全是 <code>127.0.0.1</code>。在网站 Nginx 配置的 http 块加入 Cloudflare 真实 IP 规则：</p>
<pre><code class="language-nginx"># ================= 真实 IP 全局配置 =================
    # 1. 信任本地回环和 Docker 网关转发的 Header
    set_real_ip_from 127.0.0.1;
    set_real_ip_from 172.18.0.1;

    # 2. 信任 Cloudflare 的公网 CDN 节点 IP 段
    set_real_ip_from 103.21.244.0/22;
    set_real_ip_from 103.22.200.0/22;
    set_real_ip_from 103.31.4.0/22;
    set_real_ip_from 104.16.0.0/13;
    set_real_ip_from 104.24.0.0/14;
    set_real_ip_from 108.162.192.0/18;
    set_real_ip_from 131.0.72.0/22;
    set_real_ip_from 141.101.64.0/18;
    set_real_ip_from 162.158.0.0/15;
    set_real_ip_from 172.64.0.0/13;
    set_real_ip_from 173.245.48.0/20;
    set_real_ip_from 188.114.96.0/20;
    set_real_ip_from 190.93.240.0/20;
    set_real_ip_from 197.234.240.0/22;
    set_real_ip_from 198.41.128.0/17;

    # 3. 指定从 Cloudflare 专属的 Header 字段中提取用户真实公网 IP
    real_ip_header CF-Connecting-IP;
    # ===================================================
</code></pre>
<p>保存并使其生效</p>
]]></content:encoded>
      <pubDate>Tue, 16 Jun 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Azure HK B1s 1C1G Benchmark</title>
      <link>https://miuo.me/posts/azure-hk-b1s</link>
      <guid isPermaLink="true">https://miuo.me/posts/azure-hk-b1s</guid>
      <description>Azure 香港 B1s 1 核 1G 性能基准测试：硬件、IP、网络与回程路由一览。</description>
      <content:encoded><![CDATA[<p>:::: tabs
::: tab-item 💻基本信息</p>
<p><img src="https://img.miuo.me/file/s/AA8fLyl4.webp" alt="image"></p>
<p>:::
::: tab-item 🎬IP质量</p>
<p><img src="https://img.miuo.me/file/s/43ReMjGl.webp" alt="image"></p>
<p>:::
::: tab-item 🌐网络质量</p>
<p><img src="https://img.miuo.me/file/s/VJrPzBpW.webp" alt="image"></p>
<p>:::
::: tab-item 📍回程路由</p>
<p><img src="https://img.miuo.me/file/s/zVpRmoeX.webp" alt="image"></p>
<p>:::
::::</p>
]]></content:encoded>
      <pubDate>Sat, 13 Jun 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>从零开始的 VPS 生活</title>
      <link>https://miuo.me/posts/vps-setup-from-scratch</link>
      <guid isPermaLink="true">https://miuo.me/posts/vps-setup-from-scratch</guid>
      <description>从 Azure 创建虚拟机到 1Panel 面板配置、服务器安全加固与优化的完整记录。</description>
      <content:encoded><![CDATA[<h2>1. Azure 创建虚拟机</h2>
<ul>
<li><strong>创建资源 &gt; 虚拟机</strong></li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611195857a2dex3.webp" alt=""></p>
<ul>
<li><strong>区域</strong> &gt; <strong>East Asia</strong>，<strong>映像</strong> &gt; <strong>Debian 12</strong>，端口开放 22 和 443</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611201030NrgNf4.webp" alt=""></p>
<ul>
<li>保存好下载的 pem 私钥文件</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611202030gWrWQd.webp" alt=""></p>
<h2>2. Termius 设置</h2>
<h3>2.1 连接服务器</h3>
<ul>
<li>按序号直接拖入之前下载的私钥文件</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611202750lrBs2h.webp" alt=""></p>
<ul>
<li>Address 填写服务器 ip ，Username 输入创建时的用户名，Keys 选择刚才导入的密钥，点击 connect 连接</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611203203rvYdcq.webp" alt=""></p>
<ul>
<li>成功进入终端</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611203304eLyDUm.webp" alt=""></p>
<h3>2.2 安装 1Panel 面板</h3>
<ul>
<li>第一步：切换到 root 用户</li>
</ul>
<pre><code class="language-bash">sudo -i
</code></pre>
<ul>
<li>第二步：更新系统并安装基础依赖</li>
</ul>
<pre><code class="language-bash">apt update -y &amp;&amp; apt upgrade -y
apt install curl wget sudo -y
</code></pre>
<ul>
<li>第三步：运行 1Panel 一键安装脚本</li>
</ul>
<pre><code class="language-bash">curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh &amp;&amp; bash quick_start.sh
</code></pre>
<h3>2.3 Azure 添加入站端口规则</h3>
<p><strong>网络设置 &gt; 创建端口规则 &gt; 入站端口规则 &gt; 目标端口范围</strong>
填入刚才在 1Panel 安装时生成的面板端口号</p>
<h2>3. 1Panel 初始设置</h2>
<h3>3.1 安装 openresty</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260611205416sk5ChK.webp" alt=""></p>
<h3>3.2 创建反向代理</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260611205608Mc3iuC.webp" alt=""></p>
<h3>3.3 Cloudflare 添加 DNS 记录</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260611205933xSbhBX.webp" alt=""></p>
<h3>3.4 Cloudflare 申请证书</h3>
<ul>
<li>选择<strong>编辑区域 DNS</strong> 的令牌模板</li>
<li>区域资源选择要申请证书的域名</li>
<li>创建后记得保存 Cloudflare API，因为退出后不再显示</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611210502Rk0uEI.webp" alt=""></p>
<ul>
<li>接下来返回1Panel，点击<strong>证书 &gt; DNS 账户</strong></li>
<li>按图依次填写</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260611211020MmZHUT.webp" alt=""></p>
<h3>3.5 创建 Acme 账户</h3>
<p><img src="https://s3.2731515.xyz/PicGo/202606112112511vF799.webp" alt=""></p>
<h3>3.6 申请证书</h3>
<p><strong>主域名</strong>选择 <code>*.+域名</code></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611211733129pSJ.webp" alt=""></p>
<h3>3.7 设置 HTTPS</h3>
<p>选择刚刚设置的证书</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611211931MGgJJu.webp" alt=""></p>
<h3>3.8 面板域名提醒</h3>
<blockquote>
<p>[!tip]
面板绑定域名时，URL 末尾记得加上安装 1Panel 时输出的安全入口后缀（在 Termius 安装日志里可以找到）</p>
</blockquote>
<h2>4. 服务器安全</h2>
<h3>4.1 安装 Fail2ban</h3>
<pre><code class="language-bash"># 1. 更新软件源并同时安装 fail2ban 和 rsyslog（-y 表示自动确认运行）
sudo apt-get update &amp;&amp; sudo apt-get install fail2ban rsyslog -y

# 2. 启动 Fail2ban 服务
sudo systemctl start fail2ban

# 3. 设置开机自启，保证服务器重启后依然生效
sudo systemctl enable fail2ban

# 4. 重启系统日志服务，确保 Fail2ban 能读到最新的日志
sudo systemctl restart rsyslog
</code></pre>
<p>查看运行状态</p>
<pre><code class="language-bash">sudo systemctl status fail2ban
</code></pre>
<h3>4.2 开启面板两步验证</h3>
<p><strong>面板 &gt; 安全 &gt; 两步验证</strong>
推荐 Google Authenticator 和 Bitwarden</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611213825oZaqct.webp" alt=""></p>
<h3>4.3 安装 ufw</h3>
<ul>
<li>更新包列表并安装 UFW：</li>
</ul>
<pre><code class="language-bash">sudo apt update &amp;&amp; sudo apt install ufw -y
</code></pre>
<ul>
<li>放行 SSH 端口</li>
</ul>
<pre><code class="language-bash">sudo ufw allow 22/tcp
</code></pre>
<ul>
<li>放行建站必须的 Web 端口</li>
</ul>
<pre><code class="language-bash">sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
</code></pre>
<ul>
<li>放行 1Panel 面板专属端口
<code>12345</code> 替换成刚才安装 1Panel 时设置的真实端口号</li>
</ul>
<pre><code class="language-bash">sudo ufw allow 12345/tcp
</code></pre>
<ul>
<li>启动并激活 UFW</li>
</ul>
<pre><code class="language-bash">sudo ufw enable
</code></pre>
<ul>
<li>检查运行状态</li>
</ul>
<pre><code class="language-bash">sudo ufw status verbose
</code></pre>
<h3>4.4 修改默认的 22 端口</h3>
<ol>
<li><p>在 Azure 面板放行新端口
找一个随机高位端口<strong>添加入站端口规则</strong></p>
</li>
<li><p>在 1Panel 面板放行新端口</p>
</li>
</ol>
<p><img src="https://s3.2731515.xyz/PicGo/20260611215330Tsl4wO.webp" alt=""></p>
<ol start="3">
<li>修改 SSH 配置文件</li>
</ol>
<pre><code class="language-bash">sudo nano /etc/ssh/sshd_config
</code></pre>
<p>在文件里往下找，找到 <code>#Port 22</code> 这一行
把前面的 <code>#</code>（注释符）删掉，并把 <code>22</code> 改成的新端口，变成：</p>
<pre><code class="language-bash">Port 54321
</code></pre>
<p>按 <code>Ctrl + O</code> 保存，敲回车确认文件名，然后按 <code>Ctrl + X</code> 退出编辑器</p>
<ol start="4">
<li>重启 SSH 服务让配置生效：</li>
</ol>
<pre><code class="language-bash">sudo systemctl restart ssh
</code></pre>
<ol start="5">
<li>删除 22 端口</li>
</ol>
<h2>5. 安装应用</h2>
<h3>5.1 安装 komari 探针</h3>
<p>默认端口 25774 ，进行反向代理</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611221920NwyBdx.webp" alt=""></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611225058WiMVLp.webp" alt=""></p>
<h3>5.2 后续补充</h3>
<h2>6. 服务器优化</h2>
<h3>6.1 开启虚拟内存（Swap）</h3>
<p>打开 1Panel 面板 &gt; 左侧菜单点击 <strong>工具箱</strong> &gt; 选择 <strong>快速设置</strong></p>
<p>设置 2048 MB</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611224027FCFkhr.webp" alt=""></p>
<h3>6.2 开启 BBR 拥塞控制算法</h3>
<pre><code class="language-bash">echo &quot;net.core.default_qdisc=fq&quot; | sudo tee -a /etc/sysctl.conf
echo &quot;net.ipv4.tcp_congestion_control=bbr&quot; | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
</code></pre>
<p>验证</p>
<pre><code class="language-bash">sudo sysctl net.ipv4.tcp_congestion_control
</code></pre>
<h3>6.3 校准服务器时区</h3>
<pre><code class="language-bash">sudo timedatectl set-timezone Asia/Shanghai
</code></pre>
<h2>7. 服务器备份</h2>
<h3>7.1 添加 WebDav</h3>
<p><strong>面板设置 &gt; 备份账号 &gt; 添加 WebDav</strong></p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611220956K1f3LY.webp" alt=""></p>
<blockquote>
<p>推荐 <a href="https://infini-cloud.net/en/index.html">Infini-Cloud</a> ，注册免费 20 GB 空间</p>
</blockquote>
<p>My Page 页面图中三个照填即可</p>
<p><img src="https://s3.2731515.xyz/PicGo/2026061122131261QSCW.webp" alt=""></p>
<h3>7.2 添加计划任务</h3>
<p>应用计划备份</p>
<p><img src="https://s3.2731515.xyz/PicGo/20260611225914lE3T0I.webp" alt=""></p>
]]></content:encoded>
      <pubDate>Wed, 10 Jun 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>SaveAny-Bot 自动转存 TG 视频到加密云盘</title>
      <link>https://miuo.me/posts/saveany-bot-tg-crypt</link>
      <guid isPermaLink="true">https://miuo.me/posts/saveany-bot-tg-crypt</guid>
      <description>SaveAny-Bot 配合 Rclone 与 OpenList，实现 Telegram 视频自动转存到加密云盘的完整教程。</description>
      <content:encoded><![CDATA[<blockquote>
<p><strong><a href="https://github.com/krau/SaveAny-Bot">SaveAny-Bot</a> 把 Telegram 上的文件转存到多种存储端</strong></p>
</blockquote>
<h2>1. SaveAny-Bot 特性</h2>
<ul>
<li>支持文档/视频/图片/贴纸…甚至还有 <a href="https://telegra.ph/">Telegraph</a></li>
<li>破解禁止保存的文件</li>
<li>批量下载</li>
<li>流式传输</li>
<li>多用户使用</li>
<li>基于存储规则的自动整理</li>
<li>监听并自动转存指定聊天的消息, 支持过滤</li>
<li>在不同存储端之间转存文件</li>
<li>集成 yt-dlp, 从所支持的网站下载并转存媒体文件</li>
<li>集成 Aria2, 支持直链/磁力下载和转存</li>
<li>使用 js 编写解析器插件以转存任意网站的文件</li>
<li>存储端支持:<ul>
<li>Alist</li>
<li>S3</li>
<li>WebDAV</li>
<li>本地磁盘</li>
<li>Rclone</li>
<li>Telegram (重传回指定聊天)</li>
</ul>
</li>
</ul>
<h2>2. Rclone 安装</h2>
<p>一键安装</p>
<pre><code class="language-bash">curl https://rclone.org/install.sh | sudo bash
</code></pre>
<p>Docker 部署</p>
<pre><code class="language-bash">docker run -d --name rclone --restart=always \
  -v /path/to/config:/config/rclone \
  -v /path/to/data:/data \
  rclone/rclone:latest
</code></pre>
<p>验证版本</p>
<pre><code class="language-bash">rclone --version
</code></pre>
<p>配置命令</p>
<pre><code class="language-bash">rclone config
</code></pre>
<h2>3. Openlist Crypt 设置</h2>
<pre><code class="language-text">驱动：Crypt
挂载路径：/tg
文件名加密：标准
文件夹名称加密：是
加密后文件存储路径：/onedrive/tg
密码：随机128位
加盐：随机128位
加密后缀：.bin
文件名编码：Base32
</code></pre>
<h2>4. Vps Rclone 设置</h2>
<h3>4.1 配置 OneDrive</h3>
<p>打开 Termius</p>
<pre><code class="language-bash">rclone config
</code></pre>
<ul>
<li>按 <code>n</code> 创建 New remote</li>
<li><code>name&gt;</code> 填 <code>onedrive</code></li>
<li><code>Storage&gt;</code> 填 <code>onedrive</code></li>
<li><code>client_id&gt;</code> 回车</li>
<li><code>client_secret</code> 回车</li>
<li><code>region&gt;</code> 选 <code>1(global)</code></li>
<li><code>tenant&gt;</code> 回车</li>
<li><code>Edit advanced config?</code> 按 <code>n</code></li>
<li><code>Use web browser to automatically authenticate rclone with remote?</code> 按 <code>n</code></li>
</ul>
<p>本地终端运行</p>
<pre><code class="language-bash">rclone authorize &quot;onedrive&quot;
</code></pre>
<ul>
<li>跳转到浏览器登录微软账号，复制终端里的 token</li>
<li><code>config_token&gt;</code> 填复制的密钥</li>
</ul>
<h3>4.2 配置 Crypt</h3>
<pre><code class="language-bash">rclone config
</code></pre>
<ul>
<li>按<code>n</code> 创建 New remote</li>
<li><code>name&gt;</code> 填 <code>tg_crypt</code></li>
<li><code>Storage&gt;</code> 填 <code>crypt</code></li>
<li><code>remote&gt;</code> 填 <code>onedrive:/tg</code></li>
<li><code>filename_encryption&gt;</code> 填 <code>1 (standard)</code></li>
<li><code>directory_name_encryption&gt;</code> 填 <code>1 (ture)</code></li>
<li><code>password&gt;</code> 按 <code>y</code> 输两次</li>
<li><code>password_salt&gt;</code> 按 <code>y</code> 输两次</li>
<li><code>Edit advanced config?</code> 按 <code>n</code></li>
<li><code>Keep this &quot;tg_crypt&quot; remote</code> 按 <code>y</code></li>
</ul>
<p>创建测试文件看是否连通</p>
<pre><code class="language-bash">echo &quot;Hello, perfect match!&quot; &gt; /root/newtest.txt &amp;&amp; rclone copy /root/newtest.txt tg_crypt:/ --ignore-times
</code></pre>
<h2>5. 部署 SaveAny-Bot</h2>
<h3>5.1 Telegram 官方机器人创建</h3>
<ul>
<li>Telegram 搜索官方机器人 <code>@BotFather</code></li>
<li>点击 <code>Open</code> 创建机器人，用户名用 <code>_bot</code> 结尾</li>
</ul>
<h3>5.2 用户 ID 查看</h3>
<ul>
<li>Telegram 搜索官方机器人 <code>@userinfobot</code></li>
<li>输入 <code>/start</code></li>
</ul>
<h3>5.3 后端接入参数配置</h3>
<p>路径 <code>/opt/1panel/docker/compose/saveany-bot</code></p>
<p>创建文件 <code>config.toml</code> 并填入以下内容:</p>
<pre><code class="language-toml">lang = &quot;zh&quot;

# 你的 Bot Token, 在 @BotFather 获取
token = &quot;&quot;

[[storages]]
name = &quot;tg_crypt&quot;
type = &quot;alist&quot;  # 保持 alist 驱动不变
enable = true
# 填写你 VPS 的公网 IP 和 OpenList 端口
url = &quot;http://127.0.0.1:5244&quot; 
# 填写你的 OpenList 管理后台 Token
token = &quot;&quot; 
# 对应加密盘的挂载路径
base_path = &quot;/tg&quot; 

[[users]]
id = 112233 # 你的纯数字 ID
storages = [&quot;tg_crypt&quot;]
blacklist = false
</code></pre>
<h2>6. 创建编排</h2>
<pre><code class="language-yaml">version: &#39;3.8&#39;
services:
  saveany-bot:
    image: ghcr.io/krau/saveany-bot:latest
    container_name: saveany-bot
    restart: unless-stopped
    network_mode: &quot;host&quot; # 加上这一行！让容器直接共享宿主机网络
    volumes:
      - ./config.toml:/app/config.toml
      - ./downloads:/app/downloads
</code></pre>
<h2>7. Telegram 自动设置</h2>
<blockquote>
<p>设置自动存储规则实现转发文件自动转存到  OneDrive 加密盘</p>
</blockquote>
<ul>
<li><p><code>/start</code> 开始使用</p>
</li>
<li><p><code>/silent</code> 切换静默模式</p>
</li>
<li><p><code>/storage</code> 选择默认位置 tg_crypt</p>
</li>
<li><p><code>/rule</code> 管理自动存储规则</p>
</li>
<li><p><code>/rule switch</code> 开启规则模式</p>
</li>
<li><p>视频自动保存到 /tg/video 文件夹</p>
</li>
</ul>
<pre><code class="language-text">/rule add FILENAME-REGEX (?i)\.(mp4|mkv|ts|avi|flv|mov|wmv)$ tg_crypt /tg/video
</code></pre>
<ul>
<li>图片自动保存到 /tg/image 文件夹</li>
</ul>
<pre><code class="language-text">/rule add FILENAME-REGEX (?i)\.(png|jpg|jpeg|gif|webp|bmp)$ tg_crypt /tg/image
</code></pre>
<ul>
<li>文档自动保存到 /tg/document 文件夹</li>
</ul>
<pre><code class="language-text">rule add FILENAME-REGEX (?i)\.(txt|pdf|doc|docx|xls|xlsx|ppt|pptx)$ tg_crypt /tg/document
</code></pre>
<ul>
<li>命名规则</li>
</ul>
<pre><code class="language-text">/fnametmpl {{.msgdate}}_{{.origname}}
</code></pre>
<h2>8. 参考文档</h2>
<ul>
<li><ol>
<li><a href="https://github.com/krau/SaveAny-Bot/tree/main">Github主页</a></li>
</ol>
</li>
<li><ol start="2">
<li><a href="https://sabot.unv.app/">官方文档</a></li>
</ol>
</li>
</ul>
]]></content:encoded>
      <pubDate>Thu, 21 May 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>用 Rclone 自动备份小狼毫配置到 WebDAV</title>
      <link>https://miuo.me/posts/rclone-rime-webdav-backup</link>
      <guid isPermaLink="true">https://miuo.me/posts/rclone-rime-webdav-backup</guid>
      <description>记录在 Windows 下配置 Rclone WebDAV、编写 Rime 配置备份脚本，并通过计划任务定时备份到云端的过程。</description>
      <content:encoded><![CDATA[<h2>1. Rclone 配置 webdav</h2>
<p>scoop 下载 rclone</p>
<pre><code class="language-powershell">scoop install rclone
</code></pre>
<pre><code class="language-powershell">rclone version
</code></pre>
<pre><code class="language-powershell">rclone config
</code></pre>
<p>我用的是 openlist 自建的 webdav，其他 webdav 参考官方规范填写</p>
<pre><code class="language-text">name: list
type: webdav
url: https://list.miuo.me/dav/
vendor: other
user: 你的 OpenList 用户名
password: 你的 OpenList 密码
</code></pre>
<pre><code class="language-text">bearer_token&gt;
Enter跳过即可
</code></pre>
<pre><code class="language-text">Edit advanced config?
n
</code></pre>
<pre><code class="language-text">Keep this &quot;list&quot; remote?
y
</code></pre>
<pre><code class="language-text">q
</code></pre>
<p>测试</p>
<pre><code class="language-powershell">rclone lsd list:
</code></pre>
<p>出现全部列表</p>
<pre><code class="language-powershell">PS C:\Users\Sakura&gt; rclone lsd list:
          -1 2026-03-04 18:22:52        -1  infini-cloud
          -1 2026-03-29 20:15:30        -1 Cloudflare R2
          -1 2026-05-01 12:09:55        -1 mihon
          -1 2026-05-01 12:20:14        -1 mistn
          -1 2026-01-19 13:10:05        -1 onedrive
          -1 2026-05-01 12:21:05        -1 private
          -1 2026-01-19 13:31:07        -1 quark
PS C:\Users\Sakura&gt;
</code></pre>
<h2>2. 创建 Rime 备份脚本</h2>
<p>ps1脚本，按需自行修改</p>
<pre><code class="language-powershell">$ErrorActionPreference = &quot;Stop&quot;

# Paths
$Source = &quot;C:\Users\xxx\AppData\Roaming\Rime&quot;
$TempDir = &quot;C:\Users\xxx\rclone-temp&quot;
$LogDir = &quot;C:\Users\xxx\rclone-logs&quot;
$RemoteDir = &quot;list:backup/rime-archives&quot;

# File names
$Time = Get-Date -Format &quot;yyyyMMdd-HHmmss&quot;
$ZipName = &quot;rime-$Time.zip&quot;
$ZipPath = Join-Path $TempDir $ZipName

# Logs
$LogFile = Join-Path $LogDir &quot;rime-backup.log&quot;
$RcloneLogFile = Join-Path $LogDir &quot;rime-rclone.log&quot;

# Create folders
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null
New-Item -ItemType Directory -Force -Path $LogDir | Out-Null

function Write-Log {
    param([string]$Message)

    $Now = Get-Date -Format &quot;yyyy-MM-dd HH:mm:ss&quot;
    &quot;[$Now] $Message&quot; | Out-File -FilePath $LogFile -Append -Encoding utf8
}

function Write-Step {
    param([string]$Message)

    $Now = Get-Date -Format &quot;HH:mm:ss&quot;
    Write-Host &quot;[$Now] $Message&quot; -ForegroundColor Cyan
    Write-Log $Message
}

function Write-Ok {
    param([string]$Message)

    $Now = Get-Date -Format &quot;HH:mm:ss&quot;
    Write-Host &quot;[$Now] OK: $Message&quot; -ForegroundColor Green
    Write-Log &quot;OK: $Message&quot;
}

function Write-Warn {
    param([string]$Message)

    $Now = Get-Date -Format &quot;HH:mm:ss&quot;
    Write-Host &quot;[$Now] WARN: $Message&quot; -ForegroundColor Yellow
    Write-Log &quot;WARN: $Message&quot;
}

function Write-Fail {
    param([string]$Message)

    $Now = Get-Date -Format &quot;HH:mm:ss&quot;
    Write-Host &quot;[$Now] ERROR: $Message&quot; -ForegroundColor Red
    Write-Log &quot;ERROR: $Message&quot;
}

function Show-TextProgress {
    param(
        [string]$Title,
        [int]$Current,
        [int]$Total
    )

    if ($Total -le 0) {
        return
    }

    $Percent = [math]::Floor(($Current / $Total) * 100)
    $BarLength = 30
    $FilledLength = [math]::Floor($Percent * $BarLength / 100)
    $EmptyLength = $BarLength - $FilledLength

    $Bar = (&quot;#&quot; * $FilledLength) + (&quot;-&quot; * $EmptyLength)
    Write-Host &quot;`r$Title [$Bar] $Percent%  ($Current/$Total files)&quot; -NoNewline -ForegroundColor Yellow
}

function Compress-FolderWithTextProgress {
    param(
        [string]$SourceDir,
        [string]$DestinationZip
    )

    Add-Type -AssemblyName System.IO.Compression
    Add-Type -AssemblyName System.IO.Compression.FileSystem

    if (Test-Path $DestinationZip) {
        Remove-Item $DestinationZip -Force
    }

    $Files = Get-ChildItem -Path $SourceDir -Recurse -File -Force
    $Total = $Files.Count

    if ($Total -eq 0) {
        throw &quot;No files found in source folder: $SourceDir&quot;
    }

    $Zip = [System.IO.Compression.ZipFile]::Open($DestinationZip, [System.IO.Compression.ZipArchiveMode]::Create)

    try {
        $Index = 0

        foreach ($File in $Files) {
            $Index++

            $RelativePath = $File.FullName.Substring($SourceDir.Length).TrimStart(&quot;\&quot;)
            $EntryName = $RelativePath -replace &quot;\\&quot;, &quot;/&quot;

            [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
                $Zip,
                $File.FullName,
                $EntryName,
                [System.IO.Compression.CompressionLevel]::Optimal
            ) | Out-Null

            if (($Index % 5 -eq 0) -or ($Index -eq $Total)) {
                Show-TextProgress -Title &quot;Compressing&quot; -Current $Index -Total $Total
            }
        }

        Write-Host &quot;&quot;
    }
    finally {
        $Zip.Dispose()
    }
}

Clear-Host
Write-Host &quot;&quot;
Write-Host &quot;========================================&quot; -ForegroundColor DarkCyan
Write-Host &quot; Rime Backup to Cloud Storage - Keep 3&quot; -ForegroundColor Cyan
Write-Host &quot;========================================&quot; -ForegroundColor DarkCyan
Write-Host &quot;&quot;

Write-Log &quot;========== Rime backup start ==========&quot;
Write-Log &quot;Source: $Source&quot;
Write-Log &quot;Remote: $RemoteDir&quot;
Write-Log &quot;ZipPath: $ZipPath&quot;
Write-Log &quot;RcloneLog: $RcloneLogFile&quot;

if (!(Test-Path $Source)) {
    Write-Fail &quot;Rime folder not found: $Source&quot;
    throw &quot;Rime folder not found: $Source&quot;
}

# Detect WeaselServer path
$WeaselPath = $null
$WeaselProcess = Get-Process -Name &quot;WeaselServer&quot; -ErrorAction SilentlyContinue | Select-Object -First 1

if ($WeaselProcess -and $WeaselProcess.Path) {
    $WeaselPath = $WeaselProcess.Path
    Write-Log &quot;Found WeaselServer: $WeaselPath&quot;
}

# Fallback paths
if (!$WeaselPath) {
    $PossiblePaths = @(
        &quot;C:\Program Files\Rime\weasel-0.17.4\WeaselServer.exe&quot;,
        &quot;C:\Program Files\Rime\weasel-0.16.3\WeaselServer.exe&quot;,
        &quot;C:\Program Files (x86)\Rime\weasel-0.17.4\WeaselServer.exe&quot;,
        &quot;C:\Program Files (x86)\Rime\weasel-0.16.3\WeaselServer.exe&quot;,
        &quot;C:\Program Files\Rime\WeaselServer.exe&quot;,
        &quot;C:\Program Files (x86)\Rime\WeaselServer.exe&quot;
    )

    foreach ($Path in $PossiblePaths) {
        if (Test-Path $Path) {
            $WeaselPath = $Path
            Write-Log &quot;Using fallback WeaselServer path: $WeaselPath&quot;
            break
        }
    }
}

$UploadSucceeded = $false

try {
    Write-Step &quot;[1/6] Stopping Weasel processes...&quot;
    Get-Process -Name &quot;WeaselServer&quot; -ErrorAction SilentlyContinue | Stop-Process -Force
    Get-Process -Name &quot;WeaselDeployer&quot; -ErrorAction SilentlyContinue | Stop-Process -Force
    Start-Sleep -Seconds 2
    Write-Ok &quot;Weasel processes stopped&quot;

    Write-Step &quot;[2/6] Preparing temporary zip...&quot;
    if (Test-Path $ZipPath) {
        Remove-Item $ZipPath -Force
        Write-Log &quot;Old temp zip removed&quot;
    }
    Write-Ok &quot;Temp path ready&quot;

    Write-Step &quot;[3/6] Compressing Rime folder...&quot;
    Compress-FolderWithTextProgress -SourceDir $Source -DestinationZip $ZipPath

    $ZipSizeMB = [math]::Round((Get-Item $ZipPath).Length / 1MB, 2)
    Write-Ok &quot;Compress done: $ZipName ($ZipSizeMB MB)&quot;

    Write-Step &quot;[4/6] Uploading backup to cloud storage...&quot;
    Write-Host &quot;File size: $ZipSizeMB MB&quot; -ForegroundColor DarkGray
    Write-Host &quot;&quot;

    rclone copy $ZipPath $RemoteDir `
        --progress `
        --stats 1s `
        --stats-one-line `
        --log-file $RcloneLogFile `
        --log-level INFO

    if ($LASTEXITCODE -ne 0) {
        throw &quot;rclone upload failed with exit code $LASTEXITCODE&quot;
    }

    $UploadSucceeded = $true
    Write-Ok &quot;Upload done&quot;

    Write-Step &quot;[5/6] Keeping only latest 3 backups...&quot;
    $Files = rclone lsf $RemoteDir --files-only | Where-Object { $_ -like &quot;rime-*.zip&quot; } | Sort-Object -Descending

    if ($LASTEXITCODE -ne 0) {
        throw &quot;rclone lsf failed with exit code $LASTEXITCODE&quot;
    }

    $FilesToDelete = $Files | Select-Object -Skip 3

    if ($FilesToDelete.Count -eq 0) {
        Write-Ok &quot;No old backups need deleting&quot;
    } else {
        foreach ($File in $FilesToDelete) {
            Write-Warn &quot;Deleting old backup: $File&quot;

            rclone deletefile &quot;$RemoteDir/$File&quot; `
                --log-file $RcloneLogFile `
                --log-level INFO

            if ($LASTEXITCODE -ne 0) {
                throw &quot;rclone deletefile failed for $File with exit code $LASTEXITCODE&quot;
            }
        }

        Write-Ok &quot;Old backups deleted&quot;
    }

    Write-Step &quot;[6/6] Cleaning local temp file...&quot;

    if ($UploadSucceeded -and (Test-Path $ZipPath)) {
        Remove-Item $ZipPath -Force
        Write-Ok &quot;Local temp zip removed&quot;
    } else {
        Write-Warn &quot;Upload failed, local zip kept: $ZipPath&quot;
    }

    Write-Host &quot;&quot;
    Write-Host &quot;Backup success!&quot; -ForegroundColor Green
    Write-Host &quot;Remote folder: $RemoteDir&quot; -ForegroundColor DarkGray
    Write-Host &quot;Script log: $LogFile&quot; -ForegroundColor DarkGray
    Write-Host &quot;Rclone log: $RcloneLogFile&quot; -ForegroundColor DarkGray
    Write-Host &quot;&quot;

    Write-Log &quot;========== Rime backup success ==========&quot;
}
catch {
    Write-Fail &quot;Backup failed: $($_.Exception.Message)&quot;
    Write-Log &quot;BACKUP FAILED: $($_.Exception.Message)&quot;

    if (Test-Path $ZipPath) {
        Write-Warn &quot;Local zip kept for retry: $ZipPath&quot;
        Write-Log &quot;Local zip kept for retry: $ZipPath&quot;
    }

    throw
}
finally {
    if ($WeaselPath -and (Test-Path $WeaselPath)) {
        Write-Step &quot;Restarting WeaselServer...&quot;
        Start-Process $WeaselPath
        Write-Ok &quot;WeaselServer started&quot;
    } else {
        Write-Warn &quot;WeaselServer path not found, skipped restart&quot;
    }

    Write-Log &quot;========== Rime backup end ==========&quot;
}
</code></pre>
<h2>3. 设置 windows 定时备份任务</h2>
<p>每周日 22:10 跑一次，错过后下次开机补跑，失败后每 10 分钟重试一次最多 3 次，超过 1 小时停止，不启动重复实例</p>
<pre><code class="language-powershell">$TaskName = &quot;Backup Rime to R2 Keep3&quot;
$ScriptPath = &quot;C:\Users\Sakura\Scripts\backup_rime_to_r2_keep3.ps1&quot;

# Delete old task if exists
schtasks /Delete /TN $TaskName /F 2&gt;$null

# Create action
$Action = New-ScheduledTaskAction `
    -Execute &quot;powershell.exe&quot; `
    -Argument &quot;-NoProfile -ExecutionPolicy Bypass -File `&quot;$ScriptPath`&quot;&quot;

# Run every Sunday at 22:10
$Trigger = New-ScheduledTaskTrigger `
    -Weekly `
    -DaysOfWeek Sunday `
    -At 22:10

# Settings
$Settings = New-ScheduledTaskSettingsSet `
    -AllowStartIfOnBatteries `
    -DontStopIfGoingOnBatteries `
    -StartWhenAvailable `
    -RestartCount 3 `
    -RestartInterval (New-TimeSpan -Minutes 10) `
    -ExecutionTimeLimit (New-TimeSpan -Hours 1) `
    -MultipleInstances IgnoreNew

# Register task
Register-ScheduledTask `
    -TaskName $TaskName `
    -Action $Action `
    -Trigger $Trigger `
    -Settings $Settings `
    -Description &quot;Backup Rime config to Cloudflare R2 weekly, keep latest 3 archives.&quot; `
    -Force
</code></pre>
<p>检查</p>
<pre><code class="language-powershell">schtasks /Query /TN &quot;Backup Rime to R2 Keep3&quot; /V /FO LIST
</code></pre>
<h2>4. Rime 具体配置</h2>
<h3>4.1 使用 <code>[</code> / <code>]</code> 切换候选项</h3>
<p>配置文件路径：</p>
<pre><code class="language-text">C:\Users\Sakura\AppData\Roaming\Rime\default.custom.yaml
</code></pre>
<p>如果没有 <code>default.custom.yaml</code> 就新建一个。不要直接改 <code>default.yaml</code>，更新方案时更容易被覆盖。</p>
<pre><code class="language-yaml">patch:
  # 原本 [ ] 被 Lua 的“以词定字”占用
  # 如果要用 [ ] 翻页，需要先把“以词定字”改成别的快捷键
  key_binder/select_first_character: &quot;Control+bracketleft&quot;
  key_binder/select_last_character: &quot;Control+bracketright&quot;

  key_binder/bindings/+:
    - { when: has_menu, accept: bracketleft, send: Page_Up }
    - { when: has_menu, accept: bracketright, send: Page_Down }
</code></pre>
<h3>4.2 小狼毫皮肤配置</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260510125659ShsZRR.webp" alt=""></p>
<p>配置文件路径：</p>
<pre><code class="language-text">C:\Users\Sakura\AppData\Roaming\Rime\weasel.custom.yaml
</code></pre>
<p>如果没有 <code>weasel.custom.yaml</code> 就新建一个。不要直接改 <code>weasel.yaml</code>，更新配置时更容易被覆盖。</p>
<pre><code class="language-yaml">patch:
  style/color_scheme: purity_of_form_custom

  preset_color_schemes/purity_of_form_custom:
    name: &quot;uo&quot;
    author: &quot;miuo&quot;

    # 小狼毫颜色是 BGR，不是网页常见的 RGB；黑白灰不受影响。
    text_color: 0x000000
    back_color: 0xFFFFFF
    border_color: 0xE5E5E5
    shadow_color: 0x20000000

    label_color: 0x666666
    candidate_text_color: 0x333333
    comment_text_color: 0x888888

    hilited_text_color: 0x000000
    hilited_candidate_text_color: 0x000000
    hilited_candidate_label_color: 0x333333
    hilited_comment_text_color: 0x666666
    hilited_candidate_back_color: 0xFFFFFF
    hilited_candidate_border_color: 0xFFFFFF

    # 左侧高亮标记，0xD47800 对应接近 Windows 蓝色。
    hilited_mark_color: 0xD47800
</code></pre>
<p>重新部署即可</p>
<h2>5. 雾凇词库更新</h2>
<pre><code class="language-bash">git status
</code></pre>
<pre><code class="language-bash">git pull
</code></pre>
<p>重新部署即可</p>
]]></content:encoded>
      <pubDate>Sun, 10 May 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>Windows 自用软件与设置（长期更新）</title>
      <link>https://miuo.me/posts/windows-software-settings</link>
      <guid isPermaLink="true">https://miuo.me/posts/windows-software-settings</guid>
      <description>记录 Windows 日常自用软件、外观设置和常用网站清单，方便重装系统或整理环境时参考。</description>
      <content:encoded><![CDATA[记录 Windows 日常自用软件、外观设置和常用网站清单，方便重装系统或整理环境时参考。]]></content:encoded>
      <pubDate>Sat, 04 Jul 2026 10:05:00 GMT</pubDate>
    </item>
    <item>
      <title>Obsidian LiveSync 部署和插件推荐</title>
      <link>https://miuo.me/posts/obsidian-livesync-deploy-plugins</link>
      <guid isPermaLink="true">https://miuo.me/posts/obsidian-livesync-deploy-plugins</guid>
      <description>Obsidian LiveSync 部署教程，涵盖 CouchDB 配置、跨设备同步与实用插件推荐。</description>
      <content:encoded><![CDATA[<p>插件在精不在多，所以移动端只有 <a href="https://github.com/vrtmrz/obsidian-livesync">Self-hosted LiveSync</a> 插件，其余插件均在 Windows 平台</p>
<p>Obsidian LiveSync 可实现跨设备秒级同步</p>
<h2>1. 安装 LiveSync</h2>
<ul>
<li>1panel 面板应用商店直接安装即可</li>
<li><a href="/posts/1panel-reverse-proxy">反向代理</a> SSL证书参考之前文章</li>
</ul>
<h2>2. CouchDB 数据库</h2>
<ul>
<li>访问 <code>http://ob.yourdomain.com/_utils</code></li>
<li>点击 [Create Database]创建数据库即可
<img src="https://s3.2731515.xyz/PicGo/20260403200715brheQu.webp" alt=""></li>
</ul>
<h2>3. Obsidian 配置</h2>
<h3>3.1 安装插件</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260403201800dLKPsC.webp" alt=""></p>
<h3>3.2 配置</h3>
<ol>
<li>跟随引导
<img src="https://s3.2731515.xyz/PicGo/20260403202442Xa8Wye.webp" alt=""></li>
<li>手动填写服务器信息
<img src="https://s3.2731515.xyz/PicGo/20260403202715WVb6yw.webp" alt=""></li>
<li>开启E2EE加密
<img src="https://s3.2731515.xyz/PicGo/20260403202937d9Vc23.webp" alt=""></li>
<li>选择CouchDB
<img src="https://s3.2731515.xyz/PicGo/20260403202959iPdqy0.webp" alt=""></li>
<li>依次填写
<img src="https://s3.2731515.xyz/PicGo/20260403203042jqSxAv.webp" alt=""></li>
<li>其他设备扫描QR码即可
<img src="https://s3.2731515.xyz/PicGo/20260403204104lgLV2b.webp" alt=""></li>
<li>开启 LiveSync，核心功能实时同步
<img src="https://s3.2731515.xyz/PicGo/20260403204847H7ISLL.webp" alt=""></li>
</ol>
<h2>4. 插件推荐</h2>
<ol>
<li><p>Git
备份到私有仓库防止数据丢失</p>
</li>
<li><p>Image auto upload
粘贴自动上传图片到图床</p>
</li>
<li><p>Quiet Outline
专业导航栏</p>
</li>
<li><p>Self-hosted LiveSync
实时跨设备同步</p>
</li>
</ol>
]]></content:encoded>
      <pubDate>Thu, 02 Apr 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>部署 OpenList 聚合网盘</title>
      <link>https://miuo.me/posts/openlist-aggregate-netdisk</link>
      <guid isPermaLink="true">https://miuo.me/posts/openlist-aggregate-netdisk</guid>
      <description>OpenList 部署与聚合网盘教程，包含 1Panel 安装、反向代理与存储挂载配置。</description>
      <content:encoded><![CDATA[<h2>1. 前置</h2>
<h3>1.1 服务器</h3>
<p>推荐 SSH 密钥
创建服务器时获取私钥文件</p>
<h3>1.2 SSH 连接</h3>
<p>推荐 <a href="https://termius.com/index.html">Termius</a> 客户端</p>
<ol>
<li>Keychain 导入私钥文件
<img src="https://s3.2731515.xyz/PicGo/20260403102941066qfk.webp" alt=""></li>
<li>NEW HOST 添加导入的私钥连接即可
<img src="https://s3.2731515.xyz/PicGo/20260403103105FW6wBA.webp" alt=""></li>
</ol>
<h2>2. 安装</h2>
<h3>2.1 1panel 安装</h3>
<p>我个人选择 1panel 面板</p>
<ul>
<li>脚本一键安装 1Panel</li>
</ul>
<pre><code class="language-bash">bash -c &quot;$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)&quot;
</code></pre>
<p>登录面板</p>
<ul>
<li>应用商店直接安装 Openlist 即可
<img src="https://s3.2731515.xyz/PicGo/20260403101732ahN8Q0.webp" alt=""></li>
</ul>
<h3>2.2 Docker 安装</h3>
<p>参考官方<a href="https://doc.oplist.org.cn/guide/installation/docker">教程</a></p>
<h3>2.3 反向代理</h3>
<p>参考我的 <a href="/posts/1panel-reverse-proxy">1panel 反向代理</a></p>
<h2>3. Openlist 设置</h2>
<ul>
<li>容器列表点击 <code>终端</code> 按钮，进入容器内执行命令设置密码。</li>
<li><strong>生成随机密码</strong>: <code>./openlist admin random</code></li>
<li><strong>手动设置密码</strong>: <code>./openlist admin set NEW_PASSWORD</code></li>
</ul>
<h3>3.1 内部设置</h3>
<ul>
<li>可以修改密码和用户名
<img src="https://s3.2731515.xyz/PicGo/20260403104350IL6PxB.webp" alt=""></li>
<li>[用户] -&gt; [编辑] 按需修改权限
<img src="https://s3.2731515.xyz/PicGo/202604031047081iqCXP.webp" alt=""></li>
</ul>
<h3>3.2 添加存储</h3>
<h4>3.2.1 以 Cloudflare R2 为例</h4>
<ul>
<li>驱动选择对象存储</li>
<li>挂载路径随意</li>
<li>参考我之前文章的 <a href="/posts/obsidian-sync/#03-cloudflare-r2-%E5%9B%BE%E5%BA%8A%E9%85%8D%E7%BD%AE">R2 配置</a>选择存储桶，端点，地区，访问密钥ID，访问密钥</li>
<li><strong>自定义主机</strong>可以选择自己绑定在 R2 的域名</li>
<li>其余默认即可
挂载成功点击首页即可</li>
</ul>
<h4>3.2.2 加密盘</h4>
<p>加密盘驱动选择 Crypt，开启文件名加密，设置随机长密码和盐值，记得保存</p>
<h4>3.2.3 备份</h4>
<p>备份与还原里，推荐按时备份
最终效果
<img src="https://s3.2731515.xyz/PicGo/20260403110452pUMeiA.webp" alt=""></p>
<h2>4. 参考官方文档</h2>
<ul>
<li><a href="https://doc.oplist.org/">Openlist</a></li>
<li><a href="https://1panel.cn/">1panel</a></li>
</ul>
]]></content:encoded>
      <pubDate>Tue, 31 Mar 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>1Panel 反向代理</title>
      <link>https://miuo.me/posts/1panel-reverse-proxy</link>
      <guid isPermaLink="true">https://miuo.me/posts/1panel-reverse-proxy</guid>
      <description>1Panel 反向代理实操记录，包含 Cloudflare DNS、证书申请与 HTTPS 配置步骤。</description>
      <content:encoded><![CDATA[<h2>1. 域名</h2>
<h3>1.1 Cloudflare</h3>
<p>我是在 Spaceship 买的域名托管到 Cloudflare</p>
<ol>
<li><p>点击<code>添加</code> -&gt; <code>连接域</code>，选择<code>免费计划</code>
<img src="https://s3.2731515.xyz/PicGo/202604031113518OQtiB.webp" alt=""></p>
</li>
<li><p>复制这两个
<img src="https://s3.2731515.xyz/PicGo/20260403111254PCnqi7.webp" alt=""></p>
</li>
</ol>
<h3>1.2 Spaceship</h3>
<p>购买域名可以支付宝支付，6-7 位数字 xyz 域名 10 年 50 人民币左右</p>
<ul>
<li>点击 <code>Launchpad</code></li>
<li>选择<code>高级 DNS</code> -&gt; <code>自定义名称服务器</code></li>
<li>将 Cloudflare 的粘贴到这里
<img src="https://s3.2731515.xyz/PicGo/20260403112237VTEtBO.webp" alt=""></li>
<li>等待传播</li>
</ul>
<h2>2. 反向代理</h2>
<h3>2.1 申请证书</h3>
<ol>
<li>创建 Acme 账号：<ul>
<li>点击左侧菜单<code>证书</code> -&gt; <code>Acme 账号</code></li>
<li>点击<code>创建</code>，随便输入一个邮箱</li>
</ul>
</li>
<li>创建 DNS 账户<ul>
<li>登录 Cloudflare 控制台</li>
<li>点击右上角的 <code>用户图标</code> -&gt; <code>个人资料</code></li>
<li>点击<code>API 令牌</code> -&gt; <code>创建令牌</code></li>
<li>找到<code>编辑区域 DNS</code> -&gt; <code>使用模板</code></li>
<li><code>区域资源</code> -&gt; <code>特定区域</code>选择目标域名即可</li>
<li>复制保存 Token</li>
</ul>
</li>
<li>1panel 面板添加 DNS<ul>
<li><code>证书</code> -&gt; <code>DNS 账号</code> -&gt; <code>创建</code></li>
<li>填写 Token 即可
<img src="https://s3.2731515.xyz/PicGo/202604031158574JBzJx.webp" alt=""></li>
</ul>
</li>
<li>申请证书<ul>
<li>主域名：目标域名前加 <code>*.</code> 即可，例如 <code>*.example.com</code></li>
</ul>
</li>
</ol>
<h3>2.2 创建反向代理</h3>
<h4>2.2.1 1panel</h4>
<ul>
<li>打开 1panel 面板 -&gt; <code>网站</code> -&gt; <code>创建</code> -&gt; <code>反向代理</code></li>
<li>主域名随意二级域名即可</li>
<li>代理地址 127.0.0.1:端口号</li>
<li><code>网站</code> -&gt; <code>配置</code> -&gt; <code>HTTPS</code> 选择前面的证书</li>
</ul>
<h4>2.2.2 Cloudflare</h4>
<p><code>DNS 记录</code>添加 A 记录，名称填上面的二级域名，IPV4 地址填服务器地址即可</p>
]]></content:encoded>
      <pubDate>Sat, 14 Mar 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>关于输入法和拼音方案的选择</title>
      <link>https://miuo.me/posts/input-method-choice</link>
      <guid isPermaLink="true">https://miuo.me/posts/input-method-choice</guid>
      <description>记录双拼方案选择、小鹤双拼练习方法，以及 RIME 与雾凇拼音的安装配置。</description>
      <content:encoded><![CDATA[<h2>1. 双拼方案</h2>
<p>双拼方案我选择小鹤双拼，第一是泛用性，大部分输入法都进行了内置。第二是便利性，左右手分布均匀，分配合理。</p>
<h3>1.1 双拼键位图</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260402103250iYicvD.webp" alt=""></p>
<h3>1.2 记忆口诀</h3>
<table>
<thead>
<tr>
<th align="left">Qiu</th>
<th align="left">Wei</th>
<th align="left">Ruan</th>
<th align="left">T_ue_ve</th>
<th align="left">Yun</th>
<th align="left">U_shu</th>
<th align="left">I_chi</th>
</tr>
</thead>
<tbody><tr>
<td align="left">秋</td>
<td align="left">闱</td>
<td align="left">软</td>
<td align="left">月</td>
<td align="left">云</td>
<td align="left">梳</td>
<td align="left">翅</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th align="left">Song</th>
<th align="left">_iong</th>
<th align="left">Dai</th>
<th align="left">Fen</th>
<th align="left">Geng</th>
<th align="left">Hang</th>
<th align="left">J_an</th>
</tr>
</thead>
<tbody><tr>
<td align="left">怂</td>
<td align="left">恿</td>
<td align="left">带</td>
<td align="left">粉</td>
<td align="left">更</td>
<td align="left">航</td>
<td align="left">安</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th align="left">Kuai</th>
<th align="left">_ing</th>
<th align="left">Liang</th>
<th align="left">_uang</th>
<th align="left">Zou</th>
<th align="left">Xia</th>
<th align="left">_ua</th>
</tr>
</thead>
<tbody><tr>
<td align="left">快</td>
<td align="left">迎</td>
<td align="left">两</td>
<td align="left">王</td>
<td align="left">揍</td>
<td align="left">夏</td>
<td align="left">蛙</td>
</tr>
</tbody></table>
<table>
<thead>
<tr>
<th align="left">Pie</th>
<th align="left">Cao</th>
<th align="left">V_zhui</th>
<th align="left">_v</th>
<th align="left">Bin</th>
<th align="left">Niao</th>
<th align="left">Mian</th>
</tr>
</thead>
<tbody><tr>
<td align="left">撇</td>
<td align="left">草</td>
<td align="left">追</td>
<td align="left">鱼</td>
<td align="left">滨</td>
<td align="left">鸟</td>
<td align="left">眠</td>
</tr>
</tbody></table>
<h3>1.3 个人练习方案</h3>
<p>网站1记忆键位，网站2进一步熟悉。</p>
<ol>
<li><a href="https://www.keyspell.top/">https://www.keyspell.top/</a></li>
</ol>
<p><img src="https://s3.2731515.xyz/PicGo/20260402224055Ijmq3B.webp" alt=""></p>
<ol start="2">
<li><a href="https://ninglo.github.io/shuangpin/">https://ninglo.github.io/shuangpin/</a></li>
</ol>
<p><img src="https://s3.2731515.xyz/PicGo/20260402223951N5RUwb.webp" alt=""></p>
<hr>
<h2>2. 输入法选择</h2>
<p>基于隐私和个性化选择Windows端我选择<a href="https://rime.im/download/">RIME小狼毫输入法</a>，<a href="https://github.com/iDvel/rime-ice">雾凇拼音词库</a>。</p>
<h3>2.1 RIME-Weasel安装</h3>
<ul>
<li>安装时建议不要修改用户文件夹位置，后续定制输入法容易出错。</li>
<li>不要有中文路径</li>
</ul>
<h3>2.2 雾凇拼音安装</h3>
<p>Git 安装即可</p>
<pre><code class="language-bash">git clone https://github.com/iDvel/rime-ice.git Rime --depth 1

# 更新
cd Rime
git pull
</code></pre>
<p>目前总练习时长一下午，基本熟练，本文全部小鹤双拼手打。</p>
]]></content:encoded>
      <pubDate>Thu, 19 Feb 2026 16:00:00 GMT</pubDate>
    </item>
    <item>
      <title>PicList + Cloudflare R2 + Obsidian + Git 双端同步</title>
      <link>https://miuo.me/posts/obsidian-sync</link>
      <guid isPermaLink="true">https://miuo.me/posts/obsidian-sync</guid>
      <description>使用 PicList 与 Cloudflare R2 搭建图床，并通过 Obsidian Git 实现 Windows 与 Android 双端同步。</description>
      <content:encoded><![CDATA[<h2>01. 准备工作</h2>
<h3>工具</h3>
<ul>
<li><a href="https://obsidian.md/">Obsidian</a></li>
<li><a href="https://piclist.cn/">PicList</a></li>
<li><a href="https://www.cloudflare.com/">Cloudflare R2</a></li>
<li><a href="https://github.com/">GitHub</a></li>
<li><a href="https://code.visualstudio.com/">VS Code</a></li>
</ul>
<h2>02. Obsidian 配置 Git 自动同步</h2>
<h3>1. Windows 端</h3>
<ol>
<li>创建一个 GitHub 私有仓库。</li>
<li>配置 SSH 密钥。</li>
</ol>
<pre><code class="language-bash">ssh-keygen -t ed25519 -C &quot;github邮箱&quot;
cat ~/.ssh/id_ed25519.pub
</code></pre>
<ol start="3">
<li><p>登录 GitHub。</p>
<ul>
<li>点击右上角头像 -&gt; <strong>Settings</strong></li>
<li>在左侧菜单找到 <strong>SSH and GPG keys</strong></li>
<li>点击右上角 <strong>New SSH key</strong></li>
<li>填写 <strong>Title</strong> 和 <strong>Key</strong></li>
<li>点击 <strong>Add SSH key</strong></li>
</ul>
</li>
<li><p>测试是否成功。</p>
</li>
</ol>
<pre><code class="language-bash">ssh -T git@github.com
</code></pre>
<ol start="5">
<li>获取仓库的 SSH 地址。</li>
<li>在 VS Code 中执行克隆。</li>
</ol>
<pre><code class="language-bash">git clone git@github.com:mistn/test_vault.git
</code></pre>
<ol start="7">
<li>创建 .gitignore。</li>
</ol>
<pre><code class="language-text">.obsidian/workspace.json
.obsidian/workspace-mobile.json
</code></pre>
<ol start="8">
<li>推送到 GitHub 仓库。</li>
</ol>
<pre><code class="language-bash">git add .gitignore
git commit -m &quot;add obsidian gitignore&quot;
git push origin main
</code></pre>
<p><img src="https://s3.2731515.xyz/PicGo/20260131182036ipCuhA.webp" alt=""></p>
<p>测试成功。</p>
<ol start="9">
<li><p>安装并配置 Obsidian 自动同步插件。</p>
<ul>
<li>Obsidian 搜索 git</li>
</ul>
</li>
</ol>
<p><img src="https://s3.2731515.xyz/PicGo/20260131182014uxWIlX.webp" alt=""></p>
<ul>
<li>停止编写一分钟后自动同步</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260131181951UujZ8k.webp" alt=""></p>
<ul>
<li>启动时自动拉取</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260131181934QisGbf.webp" alt=""></p>
<h3>2. Android 端</h3>
<ol>
<li>数据线连接手机并选择传输文件。</li>
<li>直接复制 Obsidian 仓库到手机。</li>
<li>手机端 Obsidian 打开文件夹。</li>
<li>Git 配置。</li>
</ol>
<ul>
<li>打开 Git 插件，填写用户名和邮箱。</li>
<li>配置 Personal Access Token。</li>
<li>打开 GitHub。</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260131181906eNqtNU.webp" alt=""></p>
<p>接下来的操作如下：</p>
<ul>
<li>选择 No expiration。</li>
<li>勾选 repo。</li>
<li>填写 token。</li>
</ul>
<h2>03. Cloudflare R2 图床配置</h2>
<h3>1. 创建存储桶（Bucket）</h3>
<ul>
<li>登录 Cloudflare 控制台，在左侧菜单点击 <strong>“存储与数据库” -&gt; “R2”</strong>。</li>
<li>点击 <strong>“创建存储桶”（Create Bucket）</strong>。</li>
</ul>
<h3>2. 获取 API 凭据（密钥）</h3>
<ul>
<li>在 R2 概览页面，点击右上角 <strong>“管理 R2 API 令牌”（Manage API Tokens）</strong>。</li>
<li>点击 <strong>“创建 API 令牌”</strong>，权限选择 <strong>“对象读写”（Object Read &amp; Write）</strong>。</li>
<li>手动保存：<ul>
<li><strong>Access Key ID</strong>（访问密钥 ID）</li>
<li><strong>Secret Access Key</strong>（机密访问密钥）</li>
<li><strong>Endpoint</strong>（终结点 URL）</li>
</ul>
</li>
</ul>
<h3>3. 开启公共访问</h3>
<p>连接域并绑定子域名。</p>
<h2>04. PicList 中配置 R2</h2>
<h3>1. 安装 s3-lls 插件</h3>
<p><img src="https://s3.2731515.xyz/PicGo/202601311818330xsoOR.webp" alt=""></p>
<h3>2. 依次填写</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260131181750uzqSA8.webp" alt=""></p>
<h3>3. 图床设置</h3>
<ul>
<li><p>高级重命名</p>
<pre><code>{Y}{m}{d}{h}{i}{s}{str-6}
</code></pre>
</li>
<li><p>移除 Exif 信息。</p>
</li>
<li><p>转换格式为 webp，压缩质量 85%。</p>
</li>
<li><p>PicList 同步配置到 GitHub 仓库。</p>
</li>
</ul>
<p><img src="https://s3.2731515.xyz/PicGo/20260131180747fXkWsM.webp" alt=""></p>
<h3>4. image auto upload 插件</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260131182309oHU5Hz.webp" alt=""></p>
<p>图片描述改为无。</p>
<h3>5. mousewheel image zoom 插件</h3>
<p><img src="https://s3.2731515.xyz/PicGo/20260131182448XzaUB1.webp" alt=""></p>
<p>可以用鼠标调整图片大小。</p>
]]></content:encoded>
      <pubDate>Fri, 30 Jan 2026 16:00:00 GMT</pubDate>
    </item>
  </channel>
</rss>