<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Moraxyc&apos;s Rhapsody</title><description>折腾小结 · 踩坑经验 · 见闻杂谈</description><link>https://blog.moraxyc.com/</link><language>zh_CN</language><item><title>使用Railway.app部署artalk评论系统</title><link>https://blog.moraxyc.com/posts/25-railway-artalk/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/25-railway-artalk/</guid><description>简述官方文档没有的Serverless部署Artalk</description><pubDate>Thu, 24 Aug 2023 16:35:06 GMT</pubDate><content:encoded>&lt;p&gt;作为DevOps的Oneman选手，我不喜欢运维（&lt;/p&gt;
&lt;p&gt;毕竟博客、评论、统计这种需要保证SLA的东西，服务提供商们在专业领域绝对可以秒杀我，就像我把密码管理器切换到了1Password一样。&lt;/p&gt;
&lt;p&gt;所以，我的博客网页在Cloudflare Pages，统计在Railway.app，配置在Github，api在Cloudflare  workers…&lt;/p&gt;
&lt;p&gt;那么，评论系统Artalk该放在哪儿？之前使用Twikoo时可以轻松部署于vercel，而artalk官方文档并没有提供任何Serverless的部署方式。&lt;/p&gt;
&lt;p&gt;好在artalk提供了Docker镜像，这让我们可以简单改造下写成Dockerfile&lt;/p&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;p&gt;Railway.app的主要部署方式就是Dockerfile，既然只有文本文件和配置的修改，一个小技巧是创建一个&lt;code&gt;GitHub Private repo&lt;/code&gt;并授权给&lt;code&gt;Railway.app Application&lt;/code&gt;，每一个独立配置便分出一个人branch来存放，只需要将railway中&lt;code&gt;service Settings&lt;/code&gt;的&lt;code&gt;Automatic Deployments&lt;/code&gt;更改为对应分支就可以轻松管理Railway.app的各项服务了&lt;/p&gt;
&lt;p&gt;那么接下来，我们便从main中分出artalk分支来配置artalk并新建一个Dockerfile文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git checkout -b artalk
touch Dockerfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将以下内容写入其中&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM artalk/artalk-go

WORKDIR /

COPY ./data /data

ENTRYPOINT [&quot;/entrypoint.sh&quot;]

EXPOSE 23366

CMD [&quot;server&quot;, &quot;-c&quot;, &quot;/data/artalk.yml&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;s&gt;接下来，就需要写入配置文件了，由于截止文章写成，artalk文档并没有提及通过环境变量配置参数，那么直接指定和修改配置文件就是唯一的选择，这也导致一个问题：每次对配置的修改都必须通过配置文件和git提交推送，这意味着无法在Artalk内可视化编辑配置&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;Artalk已经支持通过环境变量来配置了，具体请看下一小节&lt;/p&gt;
&lt;p&gt;文件树如下:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
├── Dockerfile
└── data
    ├── artalk.yml
    └── ip2region.xdb
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此处的&lt;a href=&quot;https://github.com/ArtalkJS/Artalk/raw/master/conf/artalk.example.zh-CN.yml&quot;&gt;&lt;code&gt;artalk.yml&lt;/code&gt;&lt;/a&gt;与&lt;a href=&quot;https://github.com/lionsoul2014/ip2region/raw/master/data/ip2region.xdb&quot;&gt;&lt;code&gt;ip2region.xdb&lt;/code&gt;&lt;/a&gt;分别为配置文件与ip归属地数据库。&lt;/p&gt;
&lt;h2&gt;数据持久化&lt;/h2&gt;
&lt;p&gt;artalk默认使用sqlite持久化数据，但Railway.app虽然有提供挂载的存储点，但功能极其简陋，只能通过服务访问，其他方式皆无效。&lt;/p&gt;
&lt;p&gt;因此Railway.app的全栈性就发挥了出来----项目内创建redis和postgresql并将相关参数填入配置文档即可&lt;/p&gt;
&lt;p&gt;&lt;s&gt;由于没有环境变量配置，此时只能手动复制Railway.app提供的参数填入&lt;code&gt;artalk.yml&lt;/code&gt;了&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;即便如此，也仅建议通过环境变量配置数据库，毕竟配置项太多了，还是直接配置文件舒服些&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;db:
  type: &quot;pgsql&quot;
  file: &quot;./data/artalk.db&quot;
  name: &quot;railway&quot;
  host: &quot;containers-**.railway.app&quot;
  port: **
  user: &quot;postgres&quot;
  password: &quot;******&quot;
  charset: &quot;utf8mb4&quot;
  table_prefix: &quot;&quot;

cache:
  enabled: true
  type: &quot;redis&quot;
  expires: 30
  warm_up: false
  server: &quot;containers-**.railway.app:**&quot;
  redis:
    network: &quot;tcp&quot;
    username: &quot;default&quot;
    password: &quot;******&quot;
    db: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Artalk已经实现通过环境变量配置了，也可以直接在Railway.app环境变量配置处打开&lt;code&gt;RAW editor&lt;/code&gt;粘贴以下内容实现一键配置:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ATK_CACHE_ENABLED=true
ATK_CACHE_SERVER=${{Redis.REDISHOST}}:${{Redis.REDISPORT}}
ATK_CACHE_REDIS_PASSWORD=${{Redis.REDISPASSWORD}}
ATK_CACHE_TYPE=redis
ATK_DB_HOST=${{Postgres.PGHOST}}
ATK_DB_NAME=${{Postgres.PGDATABASE}}
ATK_DB_PASSWORD=${{Postgres.PGPASSWORD}}
ATK_DB_PORT=${{Postgres.PGPORT}}
ATK_DB_TYPE=pgsql
ATK_DB_USER=${{Postgres.PGUSER}}
PORT=23366
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning[坑点!]
如果复制了上面的环境变量配置，那以下内容可跳过&lt;/p&gt;
&lt;p&gt;按理说现在已经可以git提交并推送，让Railway.app来构建了。确实，这能构建成功，甚至运行日志都十分正常，但访问自定义绑定的域名永远是Failed。问题出在哪里？&lt;/p&gt;
&lt;p&gt;实际上，Railway.app号称可以自动检测监听端口并对外开放，但这个就是不成功（&lt;/p&gt;
&lt;p&gt;解决方法也很简单，推送到远端、Railway.app构建完成后，环境变量增加一个PORT并设置为23366即可
:::&lt;/p&gt;
&lt;h2&gt;账户&lt;/h2&gt;
&lt;p&gt;由于Railway.app并没有提供进入容器执行命令的方式，那么直接在配置文件中写入第一个管理员才能成功进入控制面板&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;admin_users:
  - name: &quot;&quot;
    email: &quot;&quot;
    password: &quot;(bcrypt)$2y$10$******&quot;
    badge_name: &quot;博主&quot;
    badge_color: &quot;#0083FF&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;password需要用命令行生成加密采样的版本，以下示例命令适用于Debian/Ubuntu：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt install apache2-utils -y
unset HISTFILE
htpasswd -bnBC 10 &quot;&quot; &quot;your_password&quot; | tr -d &apos;:&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输出字符串前加入&lt;code&gt;(bcrypt)&lt;/code&gt;填入password字段即可&lt;/p&gt;
&lt;p&gt;详情参见&lt;a href=&quot;https://artalk.js.org/guide/backend/multi-site.html&quot;&gt;文档&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;结束&lt;/h2&gt;
&lt;p&gt;至此，一个简单的Railway.app部署artalk的方案便完成了，过程简单但其中有许多可以借鉴于其他Dockerfile Serverless部署项目上。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;该Dockerfile可以作为一个模板改造不支持Serverless部署的项目&lt;/li&gt;
&lt;li&gt;可以通过提前将配置放在repo的方式配置不支持环境变量的项目&lt;/li&gt;
&lt;li&gt;需配置PORT变量来保证Railway.app监听并开放此端口&lt;/li&gt;
&lt;li&gt;当存在多个不复杂项目依赖同一外部服务时，可以考虑一个repo多分支的方式解决&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>千万别注册.cn！</title><link>https://blog.moraxyc.com/posts/20-no-cn-domain/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/20-no-cn-domain/</guid><description>分享下朋友们的悲惨经历哈哈哈哈哈哈</description><pubDate>Sun, 20 Aug 2023 05:01:06 GMT</pubDate><content:encoded>&lt;p&gt;域名注册在几年前可以说是非常火爆，好多人都钟情于特殊和有趣的域名。其中最秀的无疑是&lt;a href=&quot;https://github.com/Showfom&quot;&gt;Showfom&lt;/a&gt;的离谱域名&lt;a href=&quot;https://u.sb&quot;&gt;u.sb&lt;/a&gt;、&lt;a href=&quot;https://m.ac&quot;&gt;m.ac&lt;/a&gt;，这甚至比Elon的x.com还短。无奈本人进场晚好域名全被抢了，也没钱抢（&lt;/p&gt;
&lt;h2&gt;本人经历&lt;/h2&gt;
&lt;p&gt;当初不知域名市场水深火热注册域名时，我其实选的是小姨子(xyz)&lt;s&gt;毕竟便宜&lt;/s&gt;，然后觉得这个是不是B格有点低，就又换了.icu。奈何.icu被列入了&lt;a href=&quot;https://www.spamhaus.org/statistics/tlds/&quot;&gt;spam ltd&lt;/a&gt;列表，在&lt;a href=&quot;https://mail-tester.com&quot;&gt;mail-tester&lt;/a&gt;都拿不到100💯，发邮件更容易被列入垃圾邮件。&lt;/p&gt;
&lt;p&gt;于是标新立异似乎也不是好选择，那就.com吧，大众认可度和普遍性是绝对的第一。&lt;/p&gt;
&lt;h2&gt;朋友趣事&lt;/h2&gt;
&lt;p&gt;然而我的一位朋友就没有我这么复杂的心理历程了，他直接在阿里云上注册了.cn域名…&lt;/p&gt;
&lt;p&gt;这几乎buff叠满，国内注册局、臭名昭著的CNNIC的.cn域名…最开始其实我也没有当一回事，毕竟收回和扣押域名这种事虽然这两个干过但总不能直接发生在身边对吧？&lt;/p&gt;
&lt;p&gt;但习惯了隐私保护的我没有注意到一件事----阿里云默认不开启whois隐私保护功能！&lt;/p&gt;
&lt;p&gt;在他注册域名后一周，我随便翻着我自己域名的whois，看下各自到期日多久，然后顺手搜了下他的域名…于是我震惊的发现阿里云直接把中文真名和电子邮件堂而皇之地呈现在whois服务器上！
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/no-cn-domain/cn-aliyun-whois.JPG&quot; alt=&quot;阿里云上cn域名的whois&quot; /&gt;&lt;/p&gt;
&lt;p&gt;那位朋友在凌晨1点知道这件事一直emo到凌晨6点（毕竟我之前也不知道他真名，实名上网了属于是）&lt;/p&gt;
&lt;h2&gt;阿里云掩耳盗铃&lt;/h2&gt;
&lt;p&gt;过了几天我在一个Q群里看到了&lt;a href=&quot;https://lihaoyu.cn&quot;&gt;Big_cake&lt;/a&gt;的博客未备案就问了下，都实名上网了好像备案也无所谓了…&lt;/p&gt;
&lt;p&gt;然后一个未经过CNNIC毒打的兄弟就天真地中了招，以为阿里云隐藏whois是真的隐藏&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/no-cn-domain/cheat-register-whois.JPG&quot; alt=&quot;掩耳盗铃的注册商&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/no-cn-domain/personal-info.JPG&quot; alt=&quot;真实信息&quot; /&gt;&lt;/p&gt;
&lt;p&gt;然而阿里云的文档是这么写的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;根据ICANN《通用顶级域名注册数据临时政策细则》 和《欧盟《通用数据保护条例》》 合规要求，自2018年5月25日起，阿里云的WHOIS信息公开查询结果中已不再显示域名注册人注册机构的名称，以及域名注册人注册机构、管理联系人和技术联系人的联系信息。鉴于调整措施上线后，&lt;strong&gt;您的域名注册信息已得到默认保护&lt;/strong&gt;，阿里云域名隐私保护服务已经于2018年5月25日起&lt;strong&gt;暂停服务&lt;/strong&gt;。
注意：自2023年1月1日起，.CN/.中国域名注册局提供注册局WHOIS系统隐私保护服务，详情请查看公告，如需开通点此申请。
据ICANN原先政策，WHOIS查询通常需显示域名注册人的姓名和联络信息等个人数据。阿里云为保护域名用户的个人隐私不被公开，减少拉圾邮件和对个人信息的窃取，向客户免费提供域名隐私保护服务并获得了良好效果。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这么一大堆，其中加粗的部分无疑告诉用户：你的信息已经被隐藏啦，没必要再隐藏一次，所以我们把功能取消啦&lt;/p&gt;
&lt;p&gt;&lt;s&gt;虽然前后矛盾驴头不对马嘴&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;确实，在阿里云的whois查询网页，是这样显示信息的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/no-cn-domain/whois-on-aliyun-english.JPG&quot; alt=&quot;英文版&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/no-cn-domain/whois-on-aliyun.JPG&quot; alt=&quot;中文版&quot; /&gt;&lt;/p&gt;
&lt;p&gt;掩耳盗铃、自欺欺人、粉饰太平、指鹿为马、自作聪明、装聋作哑…&lt;/p&gt;
&lt;p&gt;当然，在最新的CNNIC政策中，出了个破财免灾的法子&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;.CN/.中国域名隐私保护服务标准定价39元/域名/年。隐私保护服务年限不得大于域名剩余有效期年限。购买隐私保护服务的日期距离域名到期日期不足一年的按一年收费，且隐私保护服务到期时问同域名相应年份到期时间。例如：域名的到期时间为2023年12月1日，于2023年2月1日开通隐私保护服务1年，则隐私保护的到期时间与域名2023年的到期时间一致，即2023年12月1日&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我有这闲钱还不如买.com&lt;/p&gt;
</content:encoded></item><item><title>我的本地漫画管理方案</title><link>https://blog.moraxyc.com/posts/16-komga-manage-manga/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/16-komga-manage-manga/</guid><description>如何管理本地的漫画？我的方案也许适合你～</description><pubDate>Sat, 15 Apr 2023 18:37:09 GMT</pubDate><content:encoded>&lt;p&gt;&lt;s&gt;您可能是正版的受害者&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;这句话是一个歪理，但在大陆ACG市场却成了一个不得不面对的事实：哪怕开了会员，订阅了漫画，看到的依然是不完整和删改后的内容。&lt;/p&gt;
&lt;p&gt;同时，国内ACG市场也时有不引进/无版权/无熟肉的情况出现。以我的语言水平，显然日语生肉是啃不动的，而翻贴吧或其他论坛熟肉的感觉就像是一碗蛋炒饭没有蛋…&lt;/p&gt;
&lt;p&gt;信奉沉浸式体验的我也同样无法接受盗版漫画网站上那些时不时冒出来的弹窗广告和糟糕的体验，令人窒息的排版。&lt;/p&gt;
&lt;p&gt;看来本地漫画成了最后的归宿，唯一的问题便只有了一个----从哪儿找源？从哪儿下载？&lt;/p&gt;
&lt;h2&gt;下载漫画&lt;/h2&gt;
&lt;p&gt;这个问题十分考验&lt;s&gt;互联网信息索引与筛查分析能力&lt;/s&gt;搜索引擎，一般来说一部漫画加上&lt;strong&gt;zip rar jpg epub&lt;/strong&gt;等字样便可快速筛查出可供下载的漫画文件&lt;/p&gt;
&lt;p&gt;但可悲的是，通常来讲这种资源都是存放在BT/百度云盘上的。BT不必说，国内虽然不审查这个，但速度慢到绝望。至于百度网盘…那是&lt;s&gt;黑洞&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;好在有一些软件实现了对漫画源的爬取存储。我使用的便是&lt;a href=&quot;https://tachiyomi.org/download/&quot;&gt;Tachiyomi&lt;/a&gt;，它支持安装超多插件并爬取下载于本地，保存为cbz格式。这对本地漫画管理而言毫无疑问是非常友好的&lt;/p&gt;
&lt;h2&gt;Komga管理&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Komga 是您的漫画、日本漫画、BD 和杂志的媒体服务器&lt;/p&gt;
&lt;p&gt;如何运行：&lt;/p&gt;
&lt;p&gt;在计算机或 NAS 上安装并运行 Komga。
按内容类型添加库，让 Komga 完成剩下的工作。
使用网络界面或任何兼容的客户端。
享受阅读！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Komga就是一个专门存储漫画的Calibre，且性能和界面超过了Calibre&lt;s&gt;虽然不如Calibre强大&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;建议使用docker-compose搭建&lt;/p&gt;
&lt;h3&gt;docker-compose&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.3&apos;
services:
  komga:
    image: gotson/komga
    container_name: komga
    volumes:
      - type: bind
        source: ./config
        target: /config
      - type: bind
        source: ./data
        target: /data
    ports:
      - 8080:8080
    user: &quot;1000:1000&quot;
    environment:
      - KOMGA_LIBRARIES_SCAN_STARTUP=true
      - TZ=Asia/Shanghai
    restart: unless-stopped
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该docker-compose文件存储结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;└── komga
    ├── docker-compose.yml
    ├── data
    │   └── library
    └── config
        ├── artemis
        ├── database.sqlite
        └── lucene       
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;data&lt;/code&gt;即为数据存储，在里面创建的第一层目录即为书库&lt;/p&gt;
&lt;p&gt;Komga可通过环境变量进行更精细的修改，详见&lt;a href=&quot;https://komga.org/installation/configuration.html&quot;&gt;文档&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;文件格式&lt;/h3&gt;
&lt;p&gt;Komga支持CBZ/CBR、EPUB、PDF格式。对于漫画而言，个人觉得cbz&lt;a href=&quot;%E5%8D%B3zip%E5%8E%8B%E7%BC%A9%E5%8C%85%EF%BC%8C%E5%B0%86%E5%90%8E%E7%BC%80%E6%94%B9%E6%88%90cbz%E8%80%8C%E5%B7%B2&quot;&gt;^1&lt;/a&gt;是最简单、兼容性最高的格式。&lt;/p&gt;
&lt;p&gt;建议的文件结构如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.
└── library
    ├── 我 推 的 孩 子
    │   ├── 第 1话.cbz
    │   └── 第 9话 .cbz
    └── 辉夜大小姐想让我告白
        ├── 01话 .cbz
        └── 02话.cbz
3 directories, 4 files
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;library&lt;/code&gt;表示库名，下一层结构区分不同的漫画，更下一层则存储漫画文件&lt;/p&gt;
&lt;p&gt;如果通过BT/云盘资源下载下来的漫画是一个个文件夹内的图片，那么可以通过shell批量压缩子目录为cbz文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;for dir in */; do zip -r &quot;${dir%/}.cbz&quot; &quot;$dir&quot;; done
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;刮削元数据&lt;/h3&gt;
&lt;p&gt;Komga啥都好，就是不支持在线元数据刮削，只能从文件名/&lt;code&gt;commicinfo.xml&lt;/code&gt;之类的本地文件查找元数据。&lt;/p&gt;
&lt;p&gt;不过Komga本身不支持，社区也很热心的产生了元数据刮削的脚本。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/chu-shen/BangumiKomga&quot;&gt;BangumiKomga&lt;/a&gt;即为一个从&lt;a href=&quot;https://bgm.tv&quot;&gt;Bangumi&lt;/a&gt;获取元数据并填充的Python脚本。&lt;/p&gt;
&lt;p&gt;使用方法详见该脚本&lt;a href=&quot;https://github.com/chu-shen/BangumiKomga/blob/main/README.md&quot;&gt;README&lt;/a&gt;。由于自动识别刮削的成功率很低，强烈建议在&lt;a href=&quot;https://bgm.tv&quot;&gt;Bangumi&lt;/a&gt;中先找到对应漫画后把链接贴到Komga系列作品&lt;strong&gt;链接&lt;/strong&gt;处，标签写为&lt;code&gt;cbl&lt;/code&gt;，配置好后在目录下运行&lt;code&gt;python processMetadata.py&lt;/code&gt;，即可近乎完美的给漫画加上海报和信息了&lt;/p&gt;
&lt;h3&gt;阅读&lt;/h3&gt;
&lt;p&gt;Tachiyomi有官方Komga插件，填入实例地址/用户密码即可丝滑地使用了，那效果简直杠杠的🥰&lt;/p&gt;
&lt;p&gt;Komga同样支持其他OPDS&lt;a href=&quot;%E5%8D%B3%5B%E5%BC%80%E6%94%BE%E5%BC%8F%E5%87%BA%E7%89%88%E5%8F%91%E5%B8%83%E7%B3%BB%E7%BB%9F%5D(https://zh.m.wikipedia.org/zh-cn/%E9%96%8B%E6%94%BE%E5%BC%8F%E5%87%BA%E7%89%88%E7%99%BC%E4%BD%88%E7%B3%BB%E7%B5%B1)&quot;&gt;^2&lt;/a&gt;协议阅读器&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;PS&lt;/strong&gt;:
之前用Calibre搭过同人志漫画库，但Calibre的跨平台性的确差了很多。正好看完推子第一集，想着把漫画刷一遍，又害怕哔哩哔哩漫画有删改，就更新了下漫画管理方案。&lt;/p&gt;
&lt;p&gt;&lt;s&gt;赤坂！你还我星野爱！永失吾爱啊&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;😎👌    👉     😭&lt;/p&gt;
</content:encoded></item><item><title>深夜有感 | 我为什么写博客？</title><link>https://blog.moraxyc.com/posts/11-why-do-i-write-blog/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/11-why-do-i-write-blog/</guid><description>深夜emo~</description><pubDate>Mon, 10 Apr 2023 17:16:09 GMT</pubDate><content:encoded>&lt;p&gt;&lt;s&gt;这篇文章在凌晨1点完成，果然算深夜Emo吧&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;初出茅庐&lt;/h2&gt;
&lt;p&gt;2019年，博客逐渐落寞，但我却毅然决然地踏入了这片海洋，建立自己的“孤岛”。但一座岛，肯定要有根基对吧？于是我租了台搬瓦工vps，买了个域名&lt;s&gt;当时甚至不知道域名是啥作用，只知道可以访问&lt;/s&gt;，选择了最流行的WP作为后端，开始了一段Blogger的生涯&lt;/p&gt;
&lt;p&gt;那个时候，初出茅庐的我感觉自己nb坏了，居然在同龄人还在叱诧峡谷的时候就已经能在网上发表文章了&lt;s&gt;标准的邓克效应&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;于是，那时的我写了很多类似那些低质量网站的水文，啥营养都没有，现在看来也是羞耻无比，&lt;s&gt;想象一下被人大声念你初中的QQ空间&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;膜拜大佬&lt;/h2&gt;
&lt;p&gt;但萌新不可能一辈子，在认识了好多nb大佬的博客后，我发现自己还是太过天真。那些数十年如一日写博客的大佬比比皆是，还有可爱的DIYgod~&lt;/p&gt;
&lt;h2&gt;敏感&lt;/h2&gt;
&lt;p&gt;2020 年的中期，生活中一些事情使我陷入了人生低谷，我清除了所有旧文章。而这也导致了我直到现在都时常感到自卑，对他人的看法十分敏感，一心想着迎合他人，尽可能抑制自我&lt;/p&gt;
&lt;p&gt;2021 年末，我决定注册个新的身份并重新开始写博客&lt;s&gt;现在看来那更像是些低质量教程&lt;/s&gt;，但自那以后，我开始担心自己的文章是否会被人嘲笑，担心自己的表达是否够专业，担心自己的想法是否太过幼稚。这些负面情绪让我失去了写博客的初心&lt;/p&gt;
&lt;p&gt;然而，当我冷静下来反思时，我发现自己犯了一个错误，那就是把写博客当成了一种竞争，而非一种分享和交流的方式。我开始追求别人的认可，而不是享受写作的乐趣&lt;/p&gt;
&lt;h2&gt;迷失&lt;/h2&gt;
&lt;p&gt;不断地更换博客主题、安装各种插件和优化博客的加载速度&lt;/p&gt;
&lt;p&gt;从 WordPress 到 Gridea，再到 Hexo-Fluid、Hexo-Cards，不断更换博客主题，试图找到最漂亮、最吸引人且最高质量的主题，而忽略了博客内容的质量和价值&lt;/p&gt;
&lt;p&gt;这意味着我迷失在博客外在表现的追求中，而忘记了博客的初衷和意义&lt;/p&gt;
&lt;h2&gt;初心&lt;/h2&gt;
&lt;p&gt;回归初心，我要重新认识写博客的意义&lt;/p&gt;
&lt;p&gt;写博客不是为了展示自己有多专业和多nb&lt;s&gt;多菜&lt;/s&gt;，而是为了分享自己的经验和想法，为了与读者建立起一种互动和交流的关系。每个人都有自己独特的视角和生活经历，每篇博客都有它自己的价值。我们不应该把自己和别人比较，而是应该欣赏和尊重每个人的写作风格和表达方式&lt;/p&gt;
&lt;p&gt;如果我们把写博客当成了一种竞争，那么我们就会失去写作的初心和乐趣。相反，如果我们把写博客当成了一种分享和交流的方式，那么我们就可以更加自由地表达自己的想法，和更多的人建立联系，从而获得更多的成长和启发&lt;/p&gt;
&lt;h2&gt;最后&lt;/h2&gt;
&lt;p&gt;所以，我决定回归初心，学着享受写博客的过程，用心去分享，用心去交流，用心去感受，用心去成长&lt;/p&gt;
&lt;p&gt;我想，我应该对所有读者自豪地说一声“感谢您的阅读！”&lt;/p&gt;
</content:encoded></item><item><title>自建轻量邮件服务器？先了解传输原理！</title><link>https://blog.moraxyc.com/posts/mailserver/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/mailserver/</guid><description>自建轻量邮件服务器</description><pubDate>Wed, 29 Mar 2023 18:13:14 GMT</pubDate><content:encoded>&lt;h2&gt;邮件传输原理&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sequenceDiagram
    participant User1;
    participant MUA1 as Mail User Agent 1;
    participant MTA1 as Mail Transfer Agent 1;
    participant DNS;
    participant MTA2 as Mail Transfer Agent 2;
    participant MDA as Mail Delivery Agent;
    participant MRA as Mail Retrieval Agent;
    participant MUA2 as Mail User Agent 2;
    participant User2;

    User1-&amp;gt;&amp;gt;MUA1: 写一封邮件;
    MUA1-&amp;gt;&amp;gt;+MTA1: 通过SMTP(s)发送邮件;
    MTA1-&amp;gt;&amp;gt;+MTA1: 检查发信地址是否合法;
    MTA1-&amp;gt;&amp;gt;+DNS: 查询收信人域名MX记录;
    DNS--&amp;gt;&amp;gt;-MTA1: 响应;
    MTA1-&amp;gt;&amp;gt;+MTA2: 邮件转递;
    MTA2-&amp;gt;&amp;gt;+DNS: 查询发信人域名MX/TXT记录;
    DNS--&amp;gt;&amp;gt;-MTA2: 响应;
    Note over MTA1,MTA2: 验证发信人MX/DKIM/SPF/DMARC/PTR;
    rect RGB(200,200,200);
      MTA2-&amp;gt;&amp;gt;+MDA: 在收信人邮箱中存储邮件;
      MDA--&amp;gt;-MTA2: 确认接收邮件;
    end;
    MTA2--&amp;gt;&amp;gt;-MTA1: 确认邮件已接收;
    MTA1--&amp;gt;&amp;gt;MUA1: 邮件已发送;
    MUA1-&amp;gt;&amp;gt;+MUA1: 存到已发信箱;
    MUA1--&amp;gt;&amp;gt;User1: 发送成功;
    rect RGB(200,200,200);
      MUA2-&amp;gt;&amp;gt;+MRA: 访问邮箱下载邮件;
      MRA-&amp;gt;&amp;gt;+MDA: 访问邮箱以检索邮件内容;
      MDA--&amp;gt;&amp;gt;-MRA: 响应邮件内容;
      MRA--&amp;gt;&amp;gt;-MUA2: 返回邮件;
      User2-)MUA2: 查看邮件;
    end;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;灰色部分表示对方服务器&lt;/li&gt;
&lt;li&gt;仅供参考，有任何错误欢迎评论区讨论！&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;基本定义&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MUA（Mail User Agent）是邮件用户代理，也就是用户用来发送和接收邮件的软件。MUA通过IMAP或POP3协议与MRA通信&lt;/li&gt;
&lt;li&gt;MTA（Mail Transfer Agent）是邮件传输代理，也就是邮件服务器上的软件，负责通过SMTP协议发送和转发邮件。MTA会根据收信人地址中的域名查询对应的邮件服务器，并将邮件投递给它&lt;/li&gt;
&lt;li&gt;MDA（Mail Delivery Agent）是邮件投递代理，也就是负责将MTA接收到的邮件保存到本地磁盘或指定地方的软件。MDA通常会进行垃圾邮件和病毒扫描，并提供邮件过滤和自动回复等功能&lt;/li&gt;
&lt;li&gt;MRA（Mail Receive Agent）是邮件接收代理，负责实现IMAP和POP3协议，与MUA进行交互。MRA可以帮助用户从邮件服务器上下载或查看邮件&lt;/li&gt;
&lt;li&gt;SMTP（Simple Mail Transfer Protocol）是一种用于电子邮件传输的标准协议。它定义了如何在互联网上传输和传递电子邮件。SMTP是一个客户端/服务器协议，它使用TCP作为传输层协议，并使用25端口作为默认端口，ESMTP通过465/587端口&lt;/li&gt;
&lt;li&gt;IMAP（Internet Message Access Protocol）是一种用于电子邮件存储和访问的标准协议。IMAP协议通常使用143/993端口&lt;/li&gt;
&lt;li&gt;POP3（Post Office Protocol version 3）是一种用于电子邮件下载的标准协议，它允许用户通过邮件客户端从邮件服务器上下载邮件到本地计算机。它使用110端口进行传输，与SMTP协议配合使用。POP3协议的重点在于下载，不支持在服务器上管理邮件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常用的MUA有：Outlook、Apple Mail、Mutt、Fairemail&lt;/p&gt;
&lt;p&gt;常用的MTA有：Sendmail、Postfix&lt;/p&gt;
&lt;p&gt;常用的MDA有：procmail、dropmail、Cyrus&lt;/p&gt;
&lt;p&gt;常用的MRA有：dovecot、Fetchmail、Getmail&lt;/p&gt;
&lt;h3&gt;传输过程&lt;/h3&gt;
&lt;p&gt;邮件传输的过程可以分为以下几个步骤：&lt;/p&gt;
&lt;p&gt;本过程将模拟 &quot;小明&quot; &lt;code&gt;&amp;lt;ming@qq.com&amp;gt;&lt;/code&gt;发送至 &quot;小红&quot; &lt;code&gt;&amp;lt;hong@gmail.com&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;1. 发送&lt;/h4&gt;
&lt;p&gt;小明通过MUA编写邮件，并指定&lt;code&gt;hong@gmail.com&lt;/code&gt;，点击发送，MUA使用SMTP(s)将邮件发送到&lt;code&gt;smtp.qq.com&lt;/code&gt;的&lt;code&gt;25/465/587&lt;/code&gt;端口&lt;/p&gt;
&lt;h4&gt;2. 传递&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;smtp.qq.com&lt;/code&gt;检查发信地址是否属于该账号，如果属于，则继续投递。&lt;code&gt;smtp.qq.com&lt;/code&gt;使用DNS查询&lt;code&gt;hong@gmail.com&lt;/code&gt;对应域的MX记录[^1]。查询成功后，将邮件转发给&lt;code&gt;gmail-smtp-in.l.google.com&lt;/code&gt;。&lt;/p&gt;
&lt;h4&gt;3. 接收&lt;/h4&gt;
&lt;p&gt;该过程最复杂，因为邮件发送并无验证身份的机制，于是后续为了防止垃圾/钓鱼/假冒诈骗邮件的传递，接收方MTA会进行各种检查来确保邮件可信，MDA也会在MTA确认收信后进行扫描病毒等处理过程。如果检查未通过，重则直接退信，轻则归入垃圾邮箱。&lt;/p&gt;
&lt;p&gt;在接收邮件时，Gmail会检查DKIM/SPF/DMARC等记录以及PTR记录，以确保邮件的发送者是真实的、可信的，并且该邮件未被篡改。&lt;/p&gt;
&lt;p&gt;:::tip[DNSSEC]
后续检查基本基于DNS系统，因此域名最好支持DNSSEC以防记录被篡改
:::&lt;/p&gt;
&lt;p&gt;具体来说，收信方MTA在接收邮件时，会按照以下流程进行验证：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;DKIM验证：检查邮件中是否包含了签名过的DKIM头部字段。如果有，Gmail会使用公钥对消息进行验证，以确保该邮件是由相应域名的私钥签名的，防止邮件被篡改&lt;/li&gt;
&lt;li&gt;SPF验证：检查邮件的发送服务器是否在发送域名的SPF记录中列出。如果不在，就会认为这封邮件可能是伪造的垃圾/钓鱼邮件&lt;/li&gt;
&lt;li&gt;DMARC验证：检查邮件是否符合发送域名的DMARC策略。DMARC可以指定如何处理没有通过DKIM或SPF验证的邮件。例如，可以要求将这些邮件标记为垃圾邮件或拒绝投递&lt;/li&gt;
&lt;li&gt;PTR验证：检查邮件所在的IP地址是否与发送邮件的域名的PTR记录相匹配。PTR记录通常用于反向DNS查询，可用于验证邮件发送方的身份&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;通过上述验证，收信方MTA可以判断邮件是否来自可信的发信人，并且可以有效地防止垃圾邮件、诈骗&lt;/p&gt;
&lt;h4&gt;4. 存储&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;gmail-smtp-in.l.google.com&lt;/code&gt;确认接收邮件后，MDA进行处理，例如扫描/自动回复等。然后将其存储在&lt;code&gt;hong@gmail.com&lt;/code&gt;的邮箱中&lt;/p&gt;
&lt;h4&gt;5. 查看&lt;/h4&gt;
&lt;p&gt;如果小红用的是支持Push的MUA(例如Gmail客户端)，那么现在应该已经收到了邮件提醒，打开后即可看到小明发过来的邮件&lt;/p&gt;
&lt;p&gt;&lt;s&gt;请原谅我用小明小红，咱就是个起名废&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;自建邮件服务器&lt;/h2&gt;
&lt;p&gt;一般来讲，现在自建邮件服如果不需要图形化界面和其他附加功能，只需要最基本的发送、接受、阻止垃圾邮件，没必要去使用那些过于冗杂的&lt;a href=&quot;https://github.com/awesome-selfhosted/awesome-selfhosted#communication---email---complete-solutions&quot;&gt;邮件服务器完全解决方案&lt;/a&gt;，例如iRedmail&lt;/p&gt;
&lt;p&gt;本部分使用&lt;a href=&quot;https://docker-mailserver.github.io/docker-mailserver/latest&quot;&gt;docker-mailserver&lt;/a&gt;作为例子来搭建邮件服，它包含了&lt;code&gt;postfix&lt;/code&gt;, &lt;code&gt;dovecot&lt;/code&gt;, &lt;code&gt;SpamAssian&lt;/code&gt;, &lt;code&gt;OpenDKIM&lt;/code&gt;, &lt;code&gt;OpenDMARC&lt;/code&gt;, &lt;code&gt;Fail2Ban&lt;/code&gt;等服务，并简单配置为了开箱即用，基本上半小时就可以打造一个功能完备的邮件服务器&lt;/p&gt;
&lt;h3&gt;docker-mailserver&lt;/h3&gt;
&lt;h4&gt;准备服务器&lt;/h4&gt;
&lt;p&gt;需要满足几个条件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ip和服务器域名未被列入黑名单(可通过&lt;a href=&quot;https://mxtoolbox.com/SuperTool.aspx&quot;&gt;MX Super Tool&lt;/a&gt;检查黑名单)&lt;/li&gt;
&lt;li&gt;开放25端口&lt;/li&gt;
&lt;li&gt;可配置rDNS/PTR记录(可选，尽量)&lt;/li&gt;
&lt;li&gt;纯净系统，安装时将hostname主机名填为邮件服务器域名，如&lt;code&gt;mail.example.org&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是用docker-mailserver配置简单的邮件服，使用人数少，那配置无需太高，1c 512m即可&lt;/p&gt;
&lt;p&gt;当然，要安装docker及docker-compose&lt;/p&gt;
&lt;h4&gt;配置&lt;/h4&gt;
&lt;p&gt;如果你的邮件服务器准备于二级域名下，如&lt;code&gt;mail.example.org&lt;/code&gt;指向它，那将&lt;code&gt;hostname&lt;/code&gt;配置为子域名，&lt;code&gt;domainname&lt;/code&gt;配置为apex域&lt;a href=&quot;Apex%E5%9F%9F%E6%98%AF%E6%8C%87%E5%9F%9F%E5%90%8D%E4%B8%AD%E7%9A%84%E6%9C%80%E9%AB%98%E5%B1%82%E7%BA%A7%EF%BC%8C%E4%B8%8D%E5%8C%85%E6%8B%AC%E4%BB%BB%E4%BD%95%E5%AD%90%E5%9F%9F%E5%90%8D%E3%80%82%E4%BE%8B%E5%A6%82%EF%BC%8C%E5%9C%A8%60www.example.org%60%E5%9F%9F%E4%B8%AD%EF%BC%8C%60example.org%60%E6%98%AFapex%E5%9F%9F&quot;&gt;^2&lt;/a&gt;即可。&lt;/p&gt;
&lt;p&gt;:::tip[此处并非填写发信域]
此处仅配置邮件服务器的所在域，例如配置为&lt;code&gt;mail.example.org&lt;/code&gt;，那后面小节中的发信域mx记录就指向它
:::&lt;/p&gt;
&lt;p&gt;如果直接用apex域，那就将&lt;code&gt;hostname&lt;/code&gt;填为&lt;code&gt;example.org&lt;/code&gt;，删掉&lt;code&gt;domainname&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.3&apos;
services:
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    container_name: mailserver
    hostname: mail
    domainname: example.org
    env_file: mailserver.env
    environment:
      - SSL_TYPE=letsencrypt
    ports:
      - &quot;25:25&quot;    # SMTP  (explicit TLS =&amp;gt; STARTTLS)
      - &quot;143:143&quot;  # IMAP4 (explicit TLS =&amp;gt; STARTTLS)
      - &quot;465:465&quot;  # ESMTP (implicit TLS)
      - &quot;587:587&quot;  # ESMTP (explicit TLS =&amp;gt; STARTTLS)
      - &quot;993:993&quot;  # IMAP4 (implicit TLS)
    volumes:
      - ./docker-data/dms/mail-data/:/var/mail/
      - ./docker-data/dms/mail-state/:/var/mail-state/
      - ./docker-data/dms/mail-logs/:/var/log/mail/
      - ./docker-data/dms/config/:/tmp/docker-mailserver/
      - /etc/localtime:/etc/localtime:ro
      - /etc/letsencrypt:/etc/letsencrypt
    restart: always
    stop_grace_period: 1m
    cap_add:
      - NET_ADMIN
    healthcheck:
      test: &quot;ss --listening --tcp | grep -P &apos;LISTEN.+:smtp&apos; || exit 1&quot;
      timeout: 3s
      retries: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;a href=&quot;https://docker-mailserver.github.io/docker-mailserver/latest/config/environment/&quot;&gt;环境变量&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;以下是我自用的环境变量，使用前请修改所有&lt;code&gt;example.org&lt;/code&gt;占位符为你自己准备配置的主发信域名&lt;/p&gt;
&lt;p&gt;还有其它一些选项可配置，请看&lt;a href=&quot;https://docker-mailserver.github.io/docker-mailserver/latest/config/environment/&quot;&gt;文档&lt;/a&gt;了解相关环境变量含义&lt;/p&gt;
&lt;p&gt;强烈建议使用certbot申请证书！上一节的&lt;code&gt;docker-compose.yml&lt;/code&gt;已经配置为兼容certbot与letsencrypt，只需在容器外用certbot申请一个邮件服务器域名的SSL证书即可使用&lt;/p&gt;
&lt;p&gt;更多SSL配置方式请看&lt;a href=&quot;https://docker-mailserver.github.io/docker-mailserver/latest/config/security/ssl&quot;&gt;文档&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OVERRIDE_HOSTNAME=
DMS_DEBUG=0
LOG_LEVEL=info
SUPERVISOR_LOGLEVEL=info
ONE_DIR=1
ACCOUNT_PROVISIONER=
POSTMASTER_ADDRESS=postmaster@example.org
ENABLE_UPDATE_CHECK=1
UPDATE_CHECK_INTERVAL=1d
PERMIT_DOCKER=none
TZ=Asia/Shanghai
NETWORK_INTERFACE=
TLS_LEVEL=
SPOOF_PROTECTION=1
ENABLE_SRS=0
ENABLE_OPENDKIM=1
ENABLE_OPENDMARC=1
ENABLE_POP3=
ENABLE_CLAMAV=0
ENABLE_RSPAMD=1
ENABLE_RSPAMD_REDIS=
ENABLE_AMAVIS=1
AMAVIS_LOGLEVEL=1
ENABLE_DNSBL=1
ENABLE_FAIL2BAN=1
FAIL2BAN_BLOCKTYPE=drop
ENABLE_MANAGESIEVE=
POSTSCREEN_ACTION=enforce
SMTP_ONLY=
SSL_TYPE=
SSL_CERT_PATH=
SSL_KEY_PATH=
SSL_ALT_CERT_PATH=
SSL_ALT_KEY_PATH=
VIRUSMAILS_DELETE_DELAY=
POSTFIX_DAGENT=
POSTFIX_MAILBOX_SIZE_LIMIT=
ENABLE_QUOTAS=1
POSTFIX_MESSAGE_SIZE_LIMIT=
CLAMAV_MESSAGE_SIZE_LIMIT=
PFLOGSUMM_TRIGGER=
PFLOGSUMM_RECIPIENT=
PFLOGSUMM_SENDER=
LOGWATCH_INTERVAL=weekly
LOGWATCH_RECIPIENT=
LOGWATCH_SENDER=
REPORT_RECIPIENT=postmaster@example.org
REPORT_SENDER=
LOGROTATE_INTERVAL=weekly
POSTFIX_INET_PROTOCOLS=all
DOVECOT_INET_PROTOCOLS=all
ENABLE_SPAMASSASSIN=1
SPAMASSASSIN_SPAM_TO_INBOX=1
ENABLE_SPAMASSASSIN_KAM=1
MOVE_SPAM_TO_JUNK=1
SA_TAG=-100000.0
SA_TAG2=5.0
SA_KILL=15.0
SA_SPAM_SUBJECT=***SPAM*****
ENABLE_FETCHMAIL=0
FETCHMAIL_POLL=300
ENABLE_LDAP=
LDAP_START_TLS=
LDAP_SERVER_HOST=
LDAP_SEARCH_BASE=
LDAP_BIND_DN=
LDAP_BIND_PW=
LDAP_QUERY_FILTER_USER=
LDAP_QUERY_FILTER_GROUP=
LDAP_QUERY_FILTER_ALIAS=
LDAP_QUERY_FILTER_DOMAIN=
DOVECOT_TLS=
DOVECOT_USER_FILTER=
DOVECOT_PASS_FILTER=
DOVECOT_MAILBOX_FORMAT=maildir
DOVECOT_AUTH_BIND=
ENABLE_POSTGREY=0
POSTGREY_DELAY=300
POSTGREY_MAX_AGE=35
POSTGREY_TEXT=&quot;Delayed by Postgrey&quot;
POSTGREY_AUTO_WHITELIST_CLIENTS=5
ENABLE_SASLAUTHD=0
SASLAUTHD_MECHANISMS=
SASLAUTHD_MECH_OPTIONS=
SASLAUTHD_LDAP_SERVER=
SASLAUTHD_LDAP_BIND_DN=
SASLAUTHD_LDAP_PASSWORD=
SASLAUTHD_LDAP_SEARCH_BASE=
SASLAUTHD_LDAP_FILTER=
SASLAUTHD_LDAP_START_TLS=
SASLAUTHD_LDAP_TLS_CHECK_PEER=
SASLAUTHD_LDAP_TLS_CACERT_FILE=
SASLAUTHD_LDAP_TLS_CACERT_DIR=
SASLAUTHD_LDAP_PASSWORD_ATTR=
SASLAUTHD_LDAP_AUTH_METHOD=
SASLAUTHD_LDAP_MECH=
SRS_SENDER_CLASSES=envelope_sender
SRS_EXCLUDE_DOMAINS=
SRS_SECRET=
DEFAULT_RELAY_HOST=
RELAY_HOST=
RELAY_PORT=25
RELAY_USER=
RELAY_PASSWORD=
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;启动&amp;amp;查看日志&lt;/h4&gt;
&lt;p&gt;启动&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;查看实时日志&lt;/p&gt;
&lt;p&gt;&lt;code&gt;docker-compose logs -f&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;管理&lt;/h4&gt;
&lt;p&gt;您最好的朋友！Setup.sh！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget https://raw.githubusercontent.com/docker-mailserver/docker-mailserver/master/setup.sh
chmod a+x ./setup.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下载&lt;code&gt;setup.sh&lt;/code&gt;后，可以直接运行以获得帮助信息&lt;/p&gt;
&lt;p&gt;由于&lt;code&gt;docker-mailserver&lt;/code&gt;使用虚拟域，所以任何域名的配置都会在添加相关账号后才会生成&lt;/p&gt;
&lt;p&gt;例如使用&lt;code&gt;./setup.sh email add admin@example.org &quot;&amp;lt;password&amp;gt;&quot;&lt;/code&gt;后，&lt;code&gt;example.org&lt;/code&gt;的配置和存储位置便会生成&lt;/p&gt;
&lt;h4&gt;登录&lt;/h4&gt;
&lt;p&gt;选择任何一个MUA：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;IMAP:
    host: mail.example.org
    port: 993
    encryption: tls
    username: admin@example.org
    password: &amp;lt;password&amp;gt;
SMTP:
    host: mail.example.org
    port: 465
    encryption: tls
    username: admin@example.org
    password: &amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;按照这样填写参数登录即可&lt;/p&gt;
&lt;h3&gt;配置dns记录&lt;/h3&gt;
&lt;p&gt;接下来，请转到你的域名服务提供商。这里假设已经配置好邮件服务器域名为&lt;code&gt;mail.example.org&lt;/code&gt;，且已将A记录指向服务器。发信域名为&lt;code&gt;example.org&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;请确保域名已配置好DNSSEC&lt;/p&gt;
&lt;h4&gt;MX&lt;/h4&gt;
&lt;p&gt;该记录用于声明为域处理邮件的服务器&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;优先级&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MX&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;&lt;code&gt;mail.example.org&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;1小时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;SPF&lt;/h4&gt;
&lt;p&gt;SPF（Sender Policy Framework）用于防止邮件伪造，也就是防止垃圾邮件。可以指定哪些IP地址有权代表该域名发送电子邮件。&lt;/p&gt;
&lt;p&gt;SPF记录语法如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;v=spf1 a mx ip4:192.0.2.0/24 ip6:2001:0db8::/32 include:example.org ~all
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;a：该域名的A记录所指向的IP地址允许代表该域名发信&lt;/li&gt;
&lt;li&gt;mx：该域名的MX记录所指向的IP地址允许代表该域名发信&lt;/li&gt;
&lt;li&gt;ip4/ip6：允许该网段ip发信&lt;/li&gt;
&lt;li&gt;include:example.com：example.com域名的SPF记录中包含的IP地址也可以代表该域名发送电子邮件&lt;/li&gt;
&lt;li&gt;~all：表示除了上述机制之外的所有IP地址都可以尝试代表该域名发送电子邮件，但是会被标记为垃圾邮件。如果将此处改为&lt;code&gt;-all&lt;/code&gt;，那除了前面被允许的地址外，任何地址都不可以代表该域名发信。建议使用&lt;code&gt;-all&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建议配置为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;@&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v=spf1 mx -all&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1小时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;DMARC&lt;/h4&gt;
&lt;p&gt;DMARC（Domain-based Message Authentication, Reporting &amp;amp; Conformance）基于SPF和DKIM，可以让邮件接收方验证发件人的身份，并向域名所有者提供有关发件人身份验证结果的报告&lt;/p&gt;
&lt;p&gt;当邮件接收方收到一封电子邮件时，它会通过SPF和DKIM技术验证发件人的身份。如果发件人的电子邮件地址与SPF记录和DKIM签名匹配，则认为该邮件是合法的；否则就认为该邮件可能是垃圾邮件或欺诈邮件。如果域名所有者启用了DMARC，邮件接收方还会将验证结果报告给域名所有者，以便其进一步分析和处理&lt;/p&gt;
&lt;p&gt;DMARC 记录语法如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;v=DMARC1; p=quarantine; sp=none; rua=mailto:postmaster@example.org; ruf=mailto:postmaster@example.org;
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;p: 用于指定如何处理邮件，有三种取值：none 表示只报告，不采取任何动作，quarantine 表示将邮件放入收件人的垃圾邮件文件夹中，reject 表示直接拒绝邮件。&lt;/li&gt;
&lt;li&gt;sp: 用于指定子域名的处理方式，取值同 p&lt;/li&gt;
&lt;li&gt;rua: 指定接收邮件验证报告的地址，可以是多个邮箱地址，用逗号分隔。&lt;/li&gt;
&lt;li&gt;ruf: 指定接收邮件处理报告地址，其它同上&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;建议配置为：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;_dmarc&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v=DMARC1; p=quarantine; sp=quarantine; rua=mailto:postmaster@example.org; ruf=mailto:postmaster@example.org;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1小时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;DKIM&lt;/h4&gt;
&lt;p&gt;首先，通过&lt;code&gt;./setup.sh config dkim domain &quot;&amp;lt;domain&amp;gt;&quot;&lt;/code&gt;生成发信域名的DKIM公/私钥&lt;/p&gt;
&lt;p&gt;接着，查看&lt;code&gt;docker-data/dms/config/opendkim/keys/&amp;lt;domain&amp;gt;/&amp;lt;selector&amp;gt;.txt&lt;/code&gt;即可找到需要发布到DNS的DKIM公钥，形如&lt;code&gt;&amp;lt;selector&amp;gt;._domainkey IN      TXT     ( &quot;v=DKIM1; h=sha256; k=rsa; &quot;    &quot;p=xxxxxxx&quot;  &quot;xxxxxxx&quot;   &quot;xxxxxxx&quot; )  ; ----- DKIM key mail for example.org&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使用时需去掉引号与空格，将引号内内容发布至dns，示例如下：&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;TTL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;TXT&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;selector&amp;gt;._domainkey&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;v=DKIM1; h=sha256; k=rsa; p=xxxxxxxxxxxxxxxxxxxxx&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1小时&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h4&gt;高级: 多域名使用&lt;/h4&gt;
&lt;p&gt;由于使用虚拟域，&lt;code&gt;docker-mailserver&lt;/code&gt;不存在主域名的说法，任何添加了账号的域名都可被使用来发信，因此请谨慎添加账号，以防发送假冒邮件被退信导致域名/ip进黑名单&lt;/p&gt;
&lt;p&gt;按照上文，已经配置好&lt;code&gt;example.org&lt;/code&gt;，该如何添加第二个&lt;code&gt;test.com&lt;/code&gt;？&lt;/p&gt;
&lt;p&gt;只需要按照从&quot;使用setup.sh添加账号&quot;这个步骤起，将发信域名全换为准备添加的第二个域名，重新走一边流程，就可以正常发信/收信了&lt;/p&gt;
&lt;p&gt;多个域名同理&lt;/p&gt;
&lt;h2&gt;优化&lt;/h2&gt;
&lt;h3&gt;PTR/rDNS&lt;/h3&gt;
&lt;p&gt;PTR 记录提供 IP 地址和域名之间的映射关系&lt;/p&gt;
&lt;p&gt;在邮件传输过程中，邮件服务器会根据 IP 地址来确定邮件发送方的域名。如果邮件服务器收到了一封来自未知 IP 地址的邮件，它会尝试使用 PTR 记录查找该 IP 地址对应的域名。如果查找成功，并且该域名与邮件中的发件人域名匹配，那么该邮件就被认为是合法的&lt;/p&gt;
&lt;p&gt;例如，iCloud Mail某一台mx服务器的ip地址为&lt;code&gt;17.42.251.62&lt;/code&gt;，那么&lt;code&gt;dig -x 17.42.251.62&lt;/code&gt;即可反查到该ip指向的域名&lt;/p&gt;
&lt;h3&gt;附加：解除黑名单/白名单&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.dnswl.org/&quot;&gt;DNSWL&lt;/a&gt;是一个不错的ip地址库，可以将域名与其匹配的ip认证为白名单&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://check.spamhaus.org/&quot;&gt;SpamHaus&lt;/a&gt;也可用于检查是否为黑名单，并提供自助申诉&lt;/p&gt;
&lt;h2&gt;检查&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.mail-tester.com/&quot;&gt;Mail Tester&lt;/a&gt;可以非常方便地看出得分，10分基本上就不可能被放进垃圾邮箱里了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/mailserver/10.jpg&quot; alt=&quot;得瑟一下&quot; /&gt;&lt;/p&gt;
&lt;p&gt;[^1]: 该记录对于大型邮件服务提供商而言，一般会有多个MTA，这只是优先级最高的那个。例如通过&lt;code&gt;dig MX gmail.com&lt;/code&gt;可以看到gmail具有五个MX记录&lt;code&gt;alt4.gmail-smtp-in.l.google.com&lt;/code&gt;,&lt;code&gt;gmail-smtp-in.l.google.com&lt;/code&gt;,&lt;code&gt;alt3.gmail-smtp-in.l.google.com&lt;/code&gt;,&lt;code&gt;alt2.gmail-smtp-in.l.google.com&lt;/code&gt;,&lt;code&gt;alt1.gmail-smtp-in.l.google.com&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Cloudflare Pages上的Hexo博客添加自定义响应头</title><link>https://blog.moraxyc.com/posts/cloudflare_pages_headers/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/cloudflare_pages_headers/</guid><pubDate>Sat, 18 Feb 2023 17:59:30 GMT</pubDate><content:encoded>&lt;p&gt;在上一篇博文 &lt;a href=&quot;/posts/security-headers/&quot;&gt;配置响应头 提高网页安全性 让跑分达到A+！&lt;/a&gt; 中，我简单介绍了一些能够提高安全性的响应头，&amp;lt;!-- more --&amp;gt;但众所周知，静态博客基本上都是&lt;s&gt;白嫖&lt;/s&gt;托管在各大平台上的，例如&lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;、&lt;a href=&quot;https://pages.cloudflare.com/&quot;&gt;Cloudflare Pages&lt;/a&gt;、&lt;a href=&quot;https://cloud.tencent.com/document/product/1154/40217&quot;&gt;腾讯云Serverless&lt;/a&gt;、&lt;a href=&quot;https://vercel.com/&quot;&gt;Vercel&lt;/a&gt;、&lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;、&lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;等。&lt;/p&gt;
&lt;p&gt;在这种托管平台上，Headers响应头配置必须依靠平台本身提供的功能，例如&lt;s&gt;GitHub的没有&lt;/s&gt;Vercel的&lt;a href=&quot;https://vercel.com/docs/concepts/projects/project-configuration#headers&quot;&gt;&lt;code&gt;Vercel.json&lt;/code&gt;&lt;/a&gt;、Netlify的&lt;a href=&quot;https://docs.netlify.com/routing/headers/&quot;&gt;自定义标头&lt;/a&gt;、Cloudflare Pages Headers&lt;a href=&quot;https://developers.cloudflare.com/pages/platform/headers/&quot;&gt;Cloudflare Pages Headers&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;坑点&lt;/h2&gt;
&lt;p&gt;其他平台的自定义标头都是用gui或配置文件来定义的，而Cloudflare Pages与众不同，它要求设置一个&lt;code&gt;_headers&lt;/code&gt;文件位于生成的网页根目录下&lt;/p&gt;
&lt;p&gt;hexo在生成网页时会将source目录下的文件同步复制到生成的网页根目录下，所以将这个文件放在source里就好&lt;/p&gt;
&lt;p&gt;但这个下划线就是个问题了，在Hexo文档中，有这么一句话：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hexo ignores hidden files and files or folders whose names are prefixed with _ (underscore) - except the _posts folder.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Hexo会忽略以下划线开头的文件或文件夹（除了&lt;code&gt;_posts&lt;/code&gt;）&lt;/p&gt;
&lt;p&gt;那么该怎么强行让Hexo在生成时将source目录下的&lt;code&gt;_headers&lt;/code&gt;复制到站点根目录并跳过渲染？&lt;/p&gt;
&lt;h2&gt;解决&lt;/h2&gt;
&lt;p&gt;在&lt;code&gt;skip_render&lt;/code&gt;配置项中填入&lt;code&gt;_headers&lt;/code&gt;后，还需要使用&lt;code&gt;include&lt;/code&gt;将该文件包含在生成时需要复制到根目录的列表里面&lt;/p&gt;
&lt;p&gt;文档内并没有提供这类用法，但这个&lt;a href=&quot;https://github.com/hexojs/hexo/issues/2536&quot;&gt;issue&lt;/a&gt;验证了该方法的可行性&lt;/p&gt;
&lt;p&gt;在&lt;code&gt;_conifg.yml&lt;/code&gt;中按照以下用法填入即可&lt;/p&gt;
&lt;h3&gt;跳过渲染&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;skip_render:
  - &apos;_headers&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;强行包含&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;include:
  - &apos;_headers&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;p&gt;这样就可以保证source目录下的&lt;code&gt;_headers&lt;/code&gt;将会生成于网站根目录下&lt;/p&gt;
&lt;p&gt;那该怎么配置这个文件？&lt;/p&gt;
&lt;p&gt;基本语法如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[url]
  [name]: [value]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/secure/page
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: no-referrer

/static/*
  Access-Control-Allow-Origin: *
  X-Robots-Tag: nosnippet

https://myproject.pages.dev/*
  X-Robots-Tag: noindex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除响应头：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/*.jpg
  ! Content-Security-Policy
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;更多详细内容请查看&lt;a href=&quot;https://developers.cloudflare.com/pages/platform/headers/&quot;&gt;Cloudflare Pages Headers&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>配置响应头 提高网页安全性 让跑分达到A+！</title><link>https://blog.moraxyc.com/posts/security-headers/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/security-headers/</guid><pubDate>Sat, 18 Feb 2023 04:35:48 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;配置安全响应头可以有效地防止客户端被入侵&lt;/p&gt;
&lt;h2&gt;检测网址&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://securityheaders.com/&quot;&gt;Security Headers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://observatory.mozilla.org/&quot;&gt;Mozilla Observatory&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;介绍与配置&lt;/h2&gt;
&lt;h2&gt;HTTP严格传输安全&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Strict-Transport-Security&quot;&gt;(HSTS)&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;http是明文传输，完全没有任何加密，这意味着任何人都可以从传输数据中获取浏览器到服务器间的所有内容。所以https使用的TLS加密十分值得推崇。然而，除非特殊指定https，否则每次用域名访问时，都会首先向服务器发送http请求，再由服务器发送重定向到浏览器，接着浏览器才会升级为https。&lt;/p&gt;
&lt;p&gt;HSTS就是解决这一问题的方法。&lt;/p&gt;
&lt;p&gt;当浏览器接收到https站点发送的&lt;code&gt;Strict-Transport-Security&lt;/code&gt;头，浏览器便会遵守参数规定的时间执行https访问，当浏览器再次访问该站且未过规定时间时，浏览器便不会再发出HTTP请求，而是直接转用https连接，这防止了SSL剥离等针对尚未升级为https连接的攻击。&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该头具有三个参数：&lt;code&gt;max-age=63072000&lt;/code&gt;、&lt;code&gt;includeSubDomains&lt;/code&gt;、&lt;code&gt;preload&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;max-age=&lt;/code&gt;表明保持HTTPS连接的时间，后跟秒数，如&lt;code&gt;max-age=31536000&lt;/code&gt;含义为一年内仅使用https连接&lt;/li&gt;
&lt;li&gt;&lt;code&gt;includeSubDomains&lt;/code&gt;表示该域名下所有子域名皆使用https访问&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HSTS很好，但最原始最开始的那次连接始终是http，如果有个图谋已久的&lt;s&gt;脚本小子&lt;/s&gt;渗透专家始终盯着一举一动，那该怎么办？&lt;/p&gt;
&lt;p&gt;&lt;code&gt;preload&lt;/code&gt;参数便是用于解决这一问题。浏览器会从&lt;a href=&quot;https://www.chromium.org/hsts&quot;&gt;Chrome&lt;/a&gt;或&lt;a href=&quot;https://hg.mozilla.org/mozilla-central/raw-file/tip/security/manager/ssl/nsSTSPreloadList.inc&quot;&gt;Firefox&lt;/a&gt;预加载列表里获取应直接使用https连接的站点。该列表可在&lt;a href=&quot;https://hstspreload.org/&quot;&gt;HSTSpreload&lt;/a&gt;主动提交&lt;/p&gt;
&lt;p&gt;该列表可用&lt;a&gt;chrome://net-internals/#hsts&lt;/a&gt;在本地Chrome上查询和删改&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/X-Frame-Options&quot;&gt;X-Frame-Options&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;:::tip[建议使用CSP参数代替]
&lt;code&gt;Content-Security-Policy&lt;/code&gt; 响应头有一个 &lt;code&gt;frame-ancestors&lt;/code&gt; 参数可以完美替代&lt;code&gt;X-Frame-Options&lt;/code&gt;响应头且具有更多特性
:::&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;X-Frame-Options HTTP 响应头是用来给浏览器指示允许一个页面可否在 &lt;code&gt;&amp;lt;frame&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;、&lt;code&gt;&amp;lt;embed&amp;gt;&lt;/code&gt; 或者 &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt; 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面，从而避免点击劫持攻击。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;X-Frame-Options: SAMEORIGIN
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该头仅有两个参数，&lt;code&gt;SAMEORIGIN&lt;/code&gt;和&lt;code&gt;DENY&lt;/code&gt;。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;SAMEORIGIN&lt;/code&gt;表明该页面只允许同源域名展示frame&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DENY&lt;/code&gt;表明完全不允许任何frame&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;X-Content-Type-Options&lt;/h2&gt;
&lt;p&gt;该头的主要作用是要求客户端严格遵守响应头&lt;code&gt;Content-Type&lt;/code&gt;中规定的文件&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types&quot;&gt;MIME&lt;/a&gt;类型。否则浏览器会使用&lt;a href=&quot;https://mimesniff.spec.whatwg.org/&quot;&gt;&lt;code&gt;MIME-sniffing&lt;/code&gt;&lt;/a&gt;猜测返回文件的内容并执行&lt;/p&gt;
&lt;p&gt;如果该头没有被配置，那么隐藏在图片或其他媒体文件中的&lt;code&gt;javascript&lt;/code&gt;和&lt;code&gt;css&lt;/code&gt;就可能被攻击者利用来渗透系统&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;X-Content-Type-Options: nosniff
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该头仅有&lt;code&gt;nosniff&lt;/code&gt;一个参数来提示客户端&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;nosniff&lt;/code&gt;将阻止请求与MIME类型不符的情况发生。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/x-xss-protection&quot;&gt;X-XSS-Protection&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;:::warning[浏览器兼容性]
目前仅Safari浏览器仍支持
该头可被完全配置的CSP头取代
:::&lt;/p&gt;
&lt;p&gt;该头的作用和其名字一样一目了然，基于浏览器防护XSS攻击，因此不属于任何规范和草案中。&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;X-XSS-Protection: 1; mode=block
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该头有四个参数~引用自Mdn~&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;0&lt;/code&gt; 禁止 XSS 过滤。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;1&lt;/code&gt; 表明启用 XSS 过滤。如果检测到跨站脚本攻击，浏览器将清除页面（删除不安全的部分）。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;1;mode=block&lt;/code&gt; 表明启用 XSS 过滤。如果检测到攻击，浏览器将不会清除页面，而是阻止页面加载。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;1; report=&amp;lt;reporting-URI&amp;gt; &lt;/code&gt;仅chrome 4-77版本支持。该参数表明启用 XSS 过滤。如果检测到跨站脚本攻击，浏览器将清除页面并使用 CSP report-uri 的功能发送违规报告。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy&quot;&gt;Permissions Policy&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;该头可用来控制页面可访问的浏览器功能，这可以让站点先一步为自身划定可能使用权限范围&lt;/p&gt;
&lt;p&gt;e.g.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Permissions-Policy: geolocation=()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;该头具有很多个参数，参数语法为&lt;code&gt;&amp;lt;directive&amp;gt;=&amp;lt;allowlist&amp;gt;&lt;/code&gt;，前半部分表示权限，后半部分表示允许的白名单。&lt;/p&gt;
&lt;p&gt;:::note[权限列表]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/document-domain&quot;&gt;&lt;code&gt;document-domain&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许设置&lt;code&gt;document.domain&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/encrypted-media&quot;&gt;&lt;code&gt;encrypted-media&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用加密媒体扩展API (EME)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/execution-while-not-rendered&quot;&gt;&lt;code&gt;execution-while-not-rendered&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;任务在未呈现时是否应在框架中执行&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/execution-while-out-of-viewport&quot;&gt;&lt;code&gt;execution-while-out-of-viewport&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;任务在可见视口之外时是否应在帧中执行&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/fullscreen&quot;&gt;&lt;code&gt;fullscreen&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Element.requestFullscreen()&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/gamepad&quot;&gt;&lt;code&gt;gamepad&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Gamepad API&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/geolocation&quot;&gt;&lt;code&gt;geolocation&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Geolocation API&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/gyroscope&quot;&gt;&lt;code&gt;gyroscope&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许通过界面收集有关设备方向的信息&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/hid&quot;&gt;&lt;code&gt;hid&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;WebHID API&lt;/code&gt;连接到不常见或奇异的人机界面设备，例如备用键盘或游戏手柄。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/idle-detection&quot;&gt;&lt;code&gt;idle-detection&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用空闲检测 API来检测用户何时与他们的设备交互&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/local-fonts&quot;&gt;&lt;code&gt;local-fonts&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许收集有关用户本地安装字体的数据&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/magnetometer&quot;&gt;&lt;code&gt;magnetometer&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许通过界面收集有关设备方向的信息&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/microphone&quot;&gt;&lt;code&gt;microphone&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用音频输入设备&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/midi&quot;&gt;&lt;code&gt;midi&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用Web MIDI API&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/payment&quot;&gt;&lt;code&gt;payment&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Payment Request API&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/picture-in-picture&quot;&gt;&lt;code&gt;picture-in-picture&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许通过相应的API以画中画模式播放视频。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/publickey-credentials-get&quot;&gt;&lt;code&gt;publickey-credentials-get&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Web Authentication API&lt;/code&gt;来检索已存储的公钥凭据&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/screen-wake-lock&quot;&gt;&lt;code&gt;screen-wake-lock&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用屏幕唤醒锁定 API来指示设备不应关闭或调暗屏幕&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/serial&quot;&gt;&lt;code&gt;serial&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Web Serial API&lt;/code&gt;与串行设备通信，通过串行端口直接连接，或通过 USB 或蓝牙设备模拟串行端口&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/speaker-selection&quot;&gt;&lt;code&gt;speaker-selection&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用音频输出设备 API来列出和选择扬声器&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/USB&quot;&gt;&lt;code&gt;usb&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Web USB API&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/web-share&quot;&gt;&lt;code&gt;web-share&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用&lt;code&gt;Navigator.share()&lt;/code&gt;, Web Share API 将文本、链接、图像和其他内容共享到用户选择的任意目的地，例如移动应用程序&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/xr-spatial-tracking&quot;&gt;&lt;code&gt;xr-spatial-tracking&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用WebXR 设备 API与 WebXR 会话进行交互&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/accelerometer&quot;&gt;&lt;code&gt;accelerometer&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许收集有关设备加速度信息&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ambient-light-sensor&quot;&gt;&lt;code&gt;ambient-light-sensor&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许收集有关设备周围环境中的亮度信息&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/autoplay&quot;&gt;&lt;code&gt;autoplay&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许自动播放通过&lt;code&gt;HTMLMediaElement&lt;/code&gt;请求的媒体。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/battery&quot;&gt;&lt;code&gt;battery&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用电池状态 API&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/camera&quot;&gt;camera&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用视频输入设备&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/display-capture&quot;&gt;display-capture&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;是否允许使用该&lt;code&gt;getDisplayMedia()&lt;/code&gt;方法捕获屏幕内容
:::&lt;/p&gt;
&lt;p&gt;白名单则具有三种值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt;: 允许当前页面及所有呈现在页面中的内容使用该功能&lt;/li&gt;
&lt;li&gt;&lt;code&gt;()&lt;/code&gt;: 不允许使用该功能&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(self &quot;https://example.org&quot;)&lt;/code&gt;: 该种参数允许使用通配符，每个允许站点间以空格
隔开，&lt;code&gt;self&lt;/code&gt;表示本页面&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;内容安全策略（&lt;a href=&quot;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CSP&quot;&gt;CSP&lt;/a&gt;）&lt;/h3&gt;
&lt;p&gt;该头定义了哪些内容允许被该页面使用并执行。&lt;/p&gt;
&lt;p&gt;CSP配置很复杂，详情可以看看阮一峰老师的博客 &lt;a href=&quot;https://www.ruanyifeng.com/blog/2016/09/csp.html&quot;&gt;Content Security Policy 入门教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我可不想重造轮子&lt;s&gt;绝不是因为懒得写&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;配置好CSP头后也可以使用Google提供的&lt;a href=&quot;https://csp-evaluator.withgoogle.com/&quot;&gt;CSP Evaluator&lt;/a&gt;检测一下自己的CSP策略是否强力&lt;/p&gt;
&lt;h2&gt;跑分&lt;/h2&gt;
&lt;p&gt;最上面的两个检测网址均可对响应头进行检测，Securityheaders的检测没有Mozilla家的那么严苛，一般来讲检测如果能达到A+就表明安全性响应头配置得差不多了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cloudflare-pages-headers/1.png&quot; alt=&quot;Security Headers 检测 A+&quot; /&gt;&lt;/p&gt;
</content:encoded></item><item><title>The Fuck？拯救手残党！</title><link>https://blog.moraxyc.com/posts/thefuck/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/thefuck/</guid><description>安利TheFuck</description><pubDate>Tue, 07 Feb 2023 03:03:02 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;:::tip[以原文为主]
本文翻译并总结了原文档，如有冲突，请以原文档为准！
:::&lt;/p&gt;
&lt;p&gt;:::warning[警告]
如无特殊声明，本文所有指令在Debian/Ubuntu系Linux发行版中运行最佳
:::&lt;/p&gt;
&lt;h2&gt;需求与痛点&lt;/h2&gt;
&lt;p&gt;Linux系统的最佳用法自然是CLI，然而CLI的一大痛点就是——没有图形界面！&lt;s&gt;这不是废话嘛&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;没有图形界面，就需要用户一个字符一个字符地去敲命令来。由于没有图形界面这么直观，无论是大神还是新手都会时不时犯下一些拼错字符或打错字的低级错误，但大神和新手不同的是，大神会用命令行快捷键来快速纠错，这篇文章“&lt;a href=&quot;https://gist.github.com/zhulianhua/befb8f61db8c72b4763d&quot;&gt;Linux 命令行编辑快捷键&lt;/a&gt;” 详细地介绍了命令行中一些快捷键来辅助Linuxer们操作命令。&lt;/p&gt;
&lt;p&gt;但，我还是觉得麻烦，输了一长串命令结果要我去慢慢纠错，实在是想骂出声：“Fuck！”&lt;/p&gt;
&lt;p&gt;于是，一个极具戏剧性的命令诞生了：&lt;a href=&quot;https://github.com/nvbn/thefuck&quot;&gt;&lt;em&gt;TheFuck&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;功能&lt;/h2&gt;
&lt;h3&gt;举例&amp;lt;sub&amp;gt;以下内容引用自原开发者&lt;a href=&quot;https://github.com/nvbn&quot;&gt;nvbn&lt;/a&gt;&amp;lt;/sub&amp;gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/thefuck/1.gif&quot; alt=&quot;example动图&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

➜ fuck
sudo apt-get install vim [enter/↑/↓/ctrl+c]
[sudo] password for nvbn:
Reading package lists... Done
...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master


➜ fuck
git push --set-upstream origin master [enter/↑/↓/ctrl+c]
Counting objects: 9, done.
...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ puthon
No command &apos;puthon&apos; found, did you mean:
 Command &apos;python&apos; from package &apos;python-minimal&apos; (main)
 Command &apos;python&apos; from package &apos;python3&apos; (main)
zsh: command not found: puthon

➜ fuck
python [enter/↑/↓/ctrl+c]
Python 3.4.2 (default, Oct  8 2014, 13:08:17)
...
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ git brnch
git: &apos;brnch&apos; is not a git command. See &apos;git --help&apos;.

Did you mean this?
    branch

➜ fuck
git branch [enter/↑/↓/ctrl+c]
* master
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ lein rpl
&apos;rpl&apos; is not a task. See &apos;lein help&apos;.

Did you mean this?
         repl

➜ fuck
lein repl [enter/↑/↓/ctrl+c]
nREPL server started on port 54848 on host 127.0.0.1 - nrepl://127.0.0.1:54848
REPL-y 0.3.1
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你不怕盲目地运行更正的命令，可以禁用 require_confirmation 设置项：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;➜ apt-get install vim
E: Could not open lock file /var/lib/dpkg/lock - open (13: Permission denied)
E: Unable to lock the administration directory (/var/lib/dpkg/), are you root?

➜ fuck
sudo apt-get install vim
[sudo] password for nvbn:
Reading package lists... Done
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;h3&gt;依赖&lt;/h3&gt;
&lt;p&gt;The Fuck依赖Python运行，nvbn给出的依赖项为&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python (3.4+)&lt;/li&gt;
&lt;li&gt;pip&lt;/li&gt;
&lt;li&gt;Python-dev&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;安装依赖与本体&lt;/h3&gt;
&lt;p&gt;通过以下指令安装 (其他发行版Linux&lt;a href=&quot;https://github.com/nvbn/thefuck#installation&quot;&gt;请见原文安装部分&lt;/a&gt;)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install python3-dev python3-pip python3-setuptools
sudo pip3 install thefuck
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;原文处的安装命令在最后一个命令的地方加了&lt;code&gt;--user&lt;/code&gt;参数，这意味着The Fuck被安装在当前登录用户目录的&lt;code&gt;.local/bin&lt;/code&gt;，需要添加环境变量才能运行，此处进行了修改，直接root或sudo下安装该包可跳过该过程。&lt;/p&gt;
&lt;h3&gt;添加别名&lt;/h3&gt;
&lt;p&gt;&lt;s&gt;建议在&lt;code&gt;.bash_profile&lt;/code&gt;, &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.zshrc&lt;/code&gt; 或其他终端启动脚本中添加以下命令:&lt;code&gt;eval $(thefuck --alias)&lt;/code&gt;&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;The Fuck已经支持自动添加，只需要在安装完毕后输入两次&lt;code&gt;fuck&lt;/code&gt;即可。&lt;/p&gt;
&lt;h3&gt;更新&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pip3 install thefuck --upgrade&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;h3&gt;&lt;em&gt;&lt;strong&gt;Fuck!&lt;/strong&gt;&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;命令执行错误后，&lt;s&gt;高呼一句Fuck&lt;/s&gt;输入&lt;code&gt;fuck&lt;/code&gt;，再用上下键控制选项，回车键确认修正即可&lt;/p&gt;
&lt;h3&gt;参数&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;--yeah&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;fuck --yeah&lt;/code&gt;或者&lt;code&gt;fuck -y&lt;/code&gt;跳过确认，直接执行修正后的命令&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;-r&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;code&gt;fuck -r&lt;/code&gt;使TheFuck递归修正并执行命令，直到命令执行成功&lt;/p&gt;
&lt;h3&gt;设置&lt;/h3&gt;
&lt;h4&gt;配置项&lt;/h4&gt;
&lt;p&gt;TheFuck的配置文件默认是&lt;code&gt;~/.config/thefuck/settings.py&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;rules&lt;/code&gt; – 启用的规则列表，默认为 &lt;code&gt;thefuck.const.DEFAULT_RULES&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;exclude_rules&lt;/code&gt; – 禁用规则列表，默认为 &lt;code&gt;[]&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;require_confirmation&lt;/code&gt; – 在运行修正后命令之前是否需要确认，默认为 &lt;code&gt;True&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;wait_command&lt;/code&gt;–获取上一个命令输出的最长时间（以秒为单位）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;no_colors&lt;/code&gt; – 禁用彩色输出&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;priority&lt;/code&gt; – 具有规则优先级的字典，优先级&lt;code&gt;priority&lt;/code&gt;较低的规则将先行匹配&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;debug&lt;/code&gt; – 是否启用调试输出，默认为 &lt;code&gt;False&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;history_limit&lt;/code&gt; – 扫描多少条历史命令，如 &lt;code&gt;2000&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;alter_history&lt;/code&gt; – 是否将修正后命令加入到历史记录，默认为 &lt;code&gt;True&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;wait_slow_command&lt;/code&gt; – 如果它在 &lt;code&gt;slow_commands&lt;/code&gt; 列表中，则获取上一个命令输出的最大时间（以秒为单位）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;slow_commands&lt;/code&gt; –慢命令列表&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;num_close_matches&lt;/code&gt; – 命令修正建议的最大匹配数，默认为 3。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;excluded_search_path_prefixes&lt;/code&gt; – 搜索命令时需要忽略的路径前缀，默认为 &lt;code&gt;[]&lt;/code&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;即时模式(实验性)&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;The Fuck 的默认行为需要时间来重新运行以前的命令。 在即时模式下，The Fuck 通过使用脚本的记录输出接着读取日志来节省时间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;目前，即时模式仅支持带有 bash 或 zsh 的 Python 3。  zsh 的自动更正功能也需要被禁用，以便 thefuck 正常工作。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;要启用即时模式，请将 &lt;code&gt;--enable-experimental-instant-mode&lt;/code&gt; 添加到 &lt;code&gt;.bashrc&lt;/code&gt;、&lt;code&gt;.bash_profile&lt;/code&gt; 、 &lt;code&gt;.zshrc&lt;/code&gt; 等终端启动脚本中的别名参数内。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;举例如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;eval $(thefuck --alias --enable-experimental-instant-mode)
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>博客显示当前Cloudflare CDN节点，让界面更炫酷</title><link>https://blog.moraxyc.com/posts/echo_cloudflare_cdn_node/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/echo_cloudflare_cdn_node/</guid><description>博客显示当前Cloudflare CDN节点</description><pubDate>Sun, 18 Sep 2022 01:40:02 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;
:::tip[更新日志]
2023.08.15
从hexo跳槽到hugo！也许之后会再把这个节点显示重新部署&lt;/p&gt;
&lt;p&gt;2023.03.03
由于博客使用了多平台多线路部署，页脚已更换为CI平台提示
:::&lt;/p&gt;
&lt;p&gt;本文基于huai.pub于2020-03-13 17:55:26发表的文章而成，遵循&lt;a href=&quot;https://creativecommons.org/licenses/by-nc/4.0/deed.zh-Hans&quot;&gt;署名-非商业性使用 4.0 国标 (CC BY-NC 4.0)&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;本博客自建立以来，先后托管于Cloudflare Pages和Vercel。几个月前，Vercel的A记录ip被GFW部分污染，经过&lt;a href=&quot;https://boce.com&quot;&gt;拨测&lt;/a&gt;的全国测速，全国15%的地区污染&lt;a href=&quot;%E6%95%B0%E6%8D%AE%E6%9D%A5%E8%87%AA%E4%BA%8Eboce%EF%BC%8C%E6%9C%AC%E5%8D%9A%E5%AE%A2%E4%B8%8D%E4%BF%9D%E8%AF%81%E6%AD%A3%E7%A1%AE%E6%80%A7&quot;&gt;^1&lt;/a&gt;。&lt;s&gt;居然有那么多人看不到我精心完成的博客&lt;/s&gt;这怎么能忍！&lt;/p&gt;
&lt;p&gt;于是我上周把博客又切换回了Cloudflare Pages，虽然延迟比不上Vercel，全国ping出来平均都有150ms&lt;a href=&quot;%E6%9D%A5%E8%87%AAping.pe&quot;&gt;^2&lt;/a&gt;，但好在Cloudflare拥有很强的可定制性和全球可用性，也就不在意那一点延迟了。&lt;/p&gt;
&lt;p&gt;这时，我又看到了这篇博客：&lt;a href=&quot;https://web.archive.org/web/20200810015401/https://huai.pub/2020/03/13/%E5%9C%A8%E5%BC%80%E5%90%AF%E4%BA%86cloudflare%E7%9A%84%E9%A1%B5%E9%9D%A2%E4%B8%AD%E6%98%BE%E7%A4%BA%E5%BD%93%E5%89%8D%E8%8A%82%E7%82%B9%E4%BF%A1%E6%81%AF/&quot;&gt;在开启了CloudFlare的页面中显示当前节点信息&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;既然已经切换到了Cloudflare，何不整个炫酷的？放在页脚，页面整体渲染后再呈现信息，不影响性能的同时还能告诉各位连接的节点&lt;s&gt;顺便装个逼&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;js脚本&lt;/h2&gt;
&lt;h3&gt;代码&lt;/h3&gt;
&lt;p&gt;我修改了一下原文章中获取脚本的返回，缩减了一点点代码~~，然后增加了n多代码~~&lt;/p&gt;
&lt;p&gt;原脚本用&lt;code&gt;indexOf()&lt;/code&gt;匹配节点，修改版用正则替换了一下，改成了数组内套json的方法&lt;s&gt;绝对不是看原版的括号不爽&lt;/s&gt;，这样更直接，难出错。&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;格式化后的JavaScript脚本，太长了，这里把它先折叠起来&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$(document).ready(
    $.ajax({
        url: &quot;/cdn-cgi/trace&quot;,
        success: function (data, status) {
            let areas = [
                &apos;{&quot;s&quot;:&quot;TNR&quot;,&quot;l&quot;:&quot;Antananarivo, Madagascar&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CPT&quot;,&quot;l&quot;:&quot;Cape Town, South Africa&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CMN&quot;,&quot;l&quot;:&quot;Casablanca, Morocco&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DAR&quot;,&quot;l&quot;:&quot;Dar Es Salaam, Tanzania&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;JIB&quot;,&quot;l&quot;:&quot;Djibouti City, Djibouti&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DUR&quot;,&quot;l&quot;:&quot;Durban, South Africa&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;JNB&quot;,&quot;l&quot;:&quot;Johannesburg, South Africa&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KGL&quot;,&quot;l&quot;:&quot;Kigali, Rwanda&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LOS&quot;,&quot;l&quot;:&quot;Lagos, Nigeria&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LAD&quot;,&quot;l&quot;:&quot;Luanda, Angola&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MPM&quot;,&quot;l&quot;:&quot;Maputo, MZ&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MBA&quot;,&quot;l&quot;:&quot;Mombasa, Kenya&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MRU&quot;,&quot;l&quot;:&quot;Port Louis, Mauritius&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;RUN&quot;,&quot;l&quot;:&quot;Réunion, France&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BLR&quot;,&quot;l&quot;:&quot;Bangalore, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BKK&quot;,&quot;l&quot;:&quot;Bangkok, Thailand&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BWN&quot;,&quot;l&quot;:&quot;Bandar Seri Begawan, Brunei&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CEB&quot;,&quot;l&quot;:&quot;Cebu, Philippines&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CTU&quot;,&quot;l&quot;:&quot;成都, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MAA&quot;,&quot;l&quot;:&quot;Chennai, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CGP&quot;,&quot;l&quot;:&quot;Chittagong, Bangladesh&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CKG&quot;,&quot;l&quot;:&quot;重庆, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CMB&quot;,&quot;l&quot;:&quot;Colombo, Sri Lanka&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DAC&quot;,&quot;l&quot;:&quot;Dhaka, Bangladesh&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SZX&quot;,&quot;l&quot;:&quot;东莞, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;FUO&quot;,&quot;l&quot;:&quot;佛山, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;FOC&quot;,&quot;l&quot;:&quot;福州, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CAN&quot;,&quot;l&quot;:&quot;广州, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HGH&quot;,&quot;l&quot;:&quot;杭州, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HAN&quot;,&quot;l&quot;:&quot;Hanoi, Vietnam&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HNY&quot;,&quot;l&quot;:&quot;衡阳, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SGN&quot;,&quot;l&quot;:&quot;Ho Chi Minh City, Vietnam&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HKG&quot;,&quot;l&quot;:&quot;🇭🇰 香港&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HYD&quot;,&quot;l&quot;:&quot;Hyderabad, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ISB&quot;,&quot;l&quot;:&quot;Islamabad, Pakistan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CGK&quot;,&quot;l&quot;:&quot;Jakarta, Indonesia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TNA&quot;,&quot;l&quot;:&quot;济南, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KHI&quot;,&quot;l&quot;:&quot;Karachi, Pakistan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KTM&quot;,&quot;l&quot;:&quot;Kathmandu, Nepal&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CCU&quot;,&quot;l&quot;:&quot;Kolkata, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KUL&quot;,&quot;l&quot;:&quot;Kuala Lumpur, Malaysia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LHE&quot;,&quot;l&quot;:&quot;Lahore, Pakistan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;NAY&quot;,&quot;l&quot;:&quot;廊坊, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LYA&quot;,&quot;l&quot;:&quot;洛阳, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MFM&quot;,&quot;l&quot;:&quot;🇲🇴 澳门&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MLE&quot;,&quot;l&quot;:&quot;Malé, Maldives&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MNL&quot;,&quot;l&quot;:&quot;Manila, Philippines&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BOM&quot;,&quot;l&quot;:&quot;Mumbai, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;NAG&quot;,&quot;l&quot;:&quot;Nagpur, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;NNG&quot;,&quot;l&quot;:&quot;南宁, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DEL&quot;,&quot;l&quot;:&quot;New Delhi, India&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KIX&quot;,&quot;l&quot;:&quot;Osaka, Japan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PNH&quot;,&quot;l&quot;:&quot;Phnom Penh, Cambodia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TAO&quot;,&quot;l&quot;:&quot;青岛, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ICN&quot;,&quot;l&quot;:&quot;Seoul, South Korea&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SHA&quot;,&quot;l&quot;:&quot;上海, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SHE&quot;,&quot;l&quot;:&quot;沈阳, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SJW&quot;,&quot;l&quot;:&quot;石家庄, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SIN&quot;,&quot;l&quot;:&quot;Singapore, Singapore&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SZV&quot;,&quot;l&quot;:&quot;苏州, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TPE&quot;,&quot;l&quot;:&quot;台北, 🇨🇳 台湾&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PBH&quot;,&quot;l&quot;:&quot;Thimphu, Bhutan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TSN&quot;,&quot;l&quot;:&quot;天津, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;NRT&quot;,&quot;l&quot;:&quot;Tokyo, Japan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ULN&quot;,&quot;l&quot;:&quot;Ulaanbaatar, Mongolia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;VTE&quot;,&quot;l&quot;:&quot;Vientiane, Laos&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;WUH&quot;,&quot;l&quot;:&quot;武汉, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;WUX&quot;,&quot;l&quot;:&quot;无锡, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;XIY&quot;,&quot;l&quot;:&quot;西安, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;EVN&quot;,&quot;l&quot;:&quot;Yerevan, Armenia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CGO&quot;,&quot;l&quot;:&quot;郑州, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CSX&quot;,&quot;l&quot;:&quot;株洲, 🇨🇳 中国大陆&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;AMS&quot;,&quot;l&quot;:&quot;Amsterdam, Netherlands&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ATH&quot;,&quot;l&quot;:&quot;Athens, Greece&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BCN&quot;,&quot;l&quot;:&quot;Barcelona, Spain&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BEG&quot;,&quot;l&quot;:&quot;Belgrade, Serbia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TXL&quot;,&quot;l&quot;:&quot;Berlin, Germany&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BRU&quot;,&quot;l&quot;:&quot;Brussels, Belgium&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;OTP&quot;,&quot;l&quot;:&quot;Bucharest, Romania&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BUD&quot;,&quot;l&quot;:&quot;Budapest, Hungary&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KIV&quot;,&quot;l&quot;:&quot;Chișinău, Moldova&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CPH&quot;,&quot;l&quot;:&quot;Copenhagen, Denmark&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ORK&quot;,&quot;l&quot;:&quot;Cork, Ireland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DUB&quot;,&quot;l&quot;:&quot;Dublin, Ireland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DUS&quot;,&quot;l&quot;:&quot;Düsseldorf, Germany&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;EDI&quot;,&quot;l&quot;:&quot;Edinburgh, United Kingdom&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;FRA&quot;,&quot;l&quot;:&quot;Frankfurt, Germany&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GVA&quot;,&quot;l&quot;:&quot;Geneva, Switzerland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GOT&quot;,&quot;l&quot;:&quot;Gothenburg, Sweden&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HAM&quot;,&quot;l&quot;:&quot;Hamburg, Germany&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HEL&quot;,&quot;l&quot;:&quot;Helsinki, Finland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;IST&quot;,&quot;l&quot;:&quot;Istanbul, Turkey&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KBP&quot;,&quot;l&quot;:&quot;Kyiv, Ukraine&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LIS&quot;,&quot;l&quot;:&quot;Lisbon, Portugal&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LHR&quot;,&quot;l&quot;:&quot;London, United Kingdom&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LUX&quot;,&quot;l&quot;:&quot;Luxembourg City, Luxembourg&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MAD&quot;,&quot;l&quot;:&quot;Madrid, Spain&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MAN&quot;,&quot;l&quot;:&quot;Manchester, United Kingdom&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MRS&quot;,&quot;l&quot;:&quot;Marseille, France&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MXP&quot;,&quot;l&quot;:&quot;Milan, Italy&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DME&quot;,&quot;l&quot;:&quot;Moscow, Russia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MUC&quot;,&quot;l&quot;:&quot;Munich, Germany&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LCA&quot;,&quot;l&quot;:&quot;Nicosia, Cyprus&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;OSL&quot;,&quot;l&quot;:&quot;Oslo, Norway&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CDG&quot;,&quot;l&quot;:&quot;Paris, France&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PRG&quot;,&quot;l&quot;:&quot;Prague, Czech Republic&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KEF&quot;,&quot;l&quot;:&quot;Reykjavík, Iceland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;RIX&quot;,&quot;l&quot;:&quot;Riga, Latvia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;FCO&quot;,&quot;l&quot;:&quot;Rome, Italy&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LED&quot;,&quot;l&quot;:&quot;Saint Petersburg, Russia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SOF&quot;,&quot;l&quot;:&quot;Sofia, Bulgaria&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ARN&quot;,&quot;l&quot;:&quot;Stockholm, Sweden&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TLL&quot;,&quot;l&quot;:&quot;Tallinn, Estonia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SKG&quot;,&quot;l&quot;:&quot;Thessaloniki, Greece&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;VIE&quot;,&quot;l&quot;:&quot;Vienna, Austria&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;VNO&quot;,&quot;l&quot;:&quot;Vilnius, Lithuania&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;WAW&quot;,&quot;l&quot;:&quot;Warsaw, Poland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ZAG&quot;,&quot;l&quot;:&quot;Zagreb, Croatia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ZRH&quot;,&quot;l&quot;:&quot;Zürich, Switzerland&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ARI&quot;,&quot;l&quot;:&quot;Arica, Chile&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ASU&quot;,&quot;l&quot;:&quot;Asunción, Paraguay&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BOG&quot;,&quot;l&quot;:&quot;Bogotá, Colombia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;EZE&quot;,&quot;l&quot;:&quot;Buenos Aires, Argentina&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CWB&quot;,&quot;l&quot;:&quot;Curitiba, Brazil&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;FOR&quot;,&quot;l&quot;:&quot;Fortaleza, Brazil&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GUA&quot;,&quot;l&quot;:&quot;Guatemala City, Guatemala&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LIM&quot;,&quot;l&quot;:&quot;Lima, Peru&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MDE&quot;,&quot;l&quot;:&quot;Medellín, Colombia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PTY&quot;,&quot;l&quot;:&quot;Panama City, Panama&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;POA&quot;,&quot;l&quot;:&quot;Porto Alegre, Brazil&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;UIO&quot;,&quot;l&quot;:&quot;Quito, Ecuador&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GIG&quot;,&quot;l&quot;:&quot;Rio de Janeiro, Brazil&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GRU&quot;,&quot;l&quot;:&quot;São Paulo, Brazil&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SCL&quot;,&quot;l&quot;:&quot;Santiago, Chile&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CUR&quot;,&quot;l&quot;:&quot;Willemstad, Curaçao&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GND&quot;,&quot;l&quot;:&quot;St. George‘s, Grenada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;AMM&quot;,&quot;l&quot;:&quot;Amman, Jordan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BGW&quot;,&quot;l&quot;:&quot;Baghdad, Iraq&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;GYD&quot;,&quot;l&quot;:&quot;Baku, Azerbaijan&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BEY&quot;,&quot;l&quot;:&quot;Beirut, Lebanon&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DOH&quot;,&quot;l&quot;:&quot;Doha, Qatar&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DXB&quot;,&quot;l&quot;:&quot;Dubai, United Arab Emirates&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;KWI&quot;,&quot;l&quot;:&quot;Kuwait City, Kuwait&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BAH&quot;,&quot;l&quot;:&quot;Manama, Bahrain&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MCT&quot;,&quot;l&quot;:&quot;Muscat, Oman&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ZDM&quot;,&quot;l&quot;:&quot;Ramallah&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;RUH&quot;,&quot;l&quot;:&quot;Riyadh, Saudi Arabia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TLV&quot;,&quot;l&quot;:&quot;Tel Aviv, Israel&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;IAD&quot;,&quot;l&quot;:&quot;Ashburn, VA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ATL&quot;,&quot;l&quot;:&quot;Atlanta, GA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BOS&quot;,&quot;l&quot;:&quot;Boston, MA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BUF&quot;,&quot;l&quot;:&quot;Buffalo, NY, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YYC&quot;,&quot;l&quot;:&quot;Calgary, AB, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CLT&quot;,&quot;l&quot;:&quot;Charlotte, NC, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ORD&quot;,&quot;l&quot;:&quot;Chicago, IL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;CMH&quot;,&quot;l&quot;:&quot;Columbus, OH, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DFW&quot;,&quot;l&quot;:&quot;Dallas, TX, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DEN&quot;,&quot;l&quot;:&quot;Denver, CO, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;DTW&quot;,&quot;l&quot;:&quot;Detroit, MI, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;HNL&quot;,&quot;l&quot;:&quot;Honolulu, HI, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;IAH&quot;,&quot;l&quot;:&quot;Houston, TX, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;IND&quot;,&quot;l&quot;:&quot;Indianapolis, IN, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;JAX&quot;,&quot;l&quot;:&quot;Jacksonville, FL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MCI&quot;,&quot;l&quot;:&quot;Kansas City, MO, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LAS&quot;,&quot;l&quot;:&quot;Las Vegas, NV, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;LAX&quot;,&quot;l&quot;:&quot;Los Angeles, CA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MFE&quot;,&quot;l&quot;:&quot;McAllen, TX, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MEM&quot;,&quot;l&quot;:&quot;Memphis, TN, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MEX&quot;,&quot;l&quot;:&quot;Mexico City, Mexico&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MIA&quot;,&quot;l&quot;:&quot;Miami, FL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MSP&quot;,&quot;l&quot;:&quot;Minneapolis, MN, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MGM&quot;,&quot;l&quot;:&quot;Montgomery, AL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YUL&quot;,&quot;l&quot;:&quot;Montréal, QC, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BNA&quot;,&quot;l&quot;:&quot;Nashville, TN, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;EWR&quot;,&quot;l&quot;:&quot;Newark, NJ, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ORF&quot;,&quot;l&quot;:&quot;Norfolk, VA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;OMA&quot;,&quot;l&quot;:&quot;Omaha, NE, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PHL&quot;,&quot;l&quot;:&quot;Philadelphia, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PHX&quot;,&quot;l&quot;:&quot;Phoenix, AZ, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PIT&quot;,&quot;l&quot;:&quot;Pittsburgh, PA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PAP&quot;,&quot;l&quot;:&quot;Port-Au-Prince, Haiti&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PDX&quot;,&quot;l&quot;:&quot;Portland, OR, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;QRO&quot;,&quot;l&quot;:&quot;Queretaro, MX, Mexico&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;RIC&quot;,&quot;l&quot;:&quot;Richmond, Virginia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SMF&quot;,&quot;l&quot;:&quot;Sacramento, CA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SLC&quot;,&quot;l&quot;:&quot;Salt Lake City, UT, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SAN&quot;,&quot;l&quot;:&quot;San Diego, CA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SJC&quot;,&quot;l&quot;:&quot;San Jose, CA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YXE&quot;,&quot;l&quot;:&quot;Saskatoon, SK, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SEA&quot;,&quot;l&quot;:&quot;Seattle, WA, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;STL&quot;,&quot;l&quot;:&quot;St. Louis, MO, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TPA&quot;,&quot;l&quot;:&quot;Tampa, FL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YYZ&quot;,&quot;l&quot;:&quot;Toronto, ON, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YVR&quot;,&quot;l&quot;:&quot;Vancouver, BC, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;TLH&quot;,&quot;l&quot;:&quot;Tallahassee, FL, United States&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;YWG&quot;,&quot;l&quot;:&quot;Winnipeg, MB, Canada&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;ADL&quot;,&quot;l&quot;:&quot;Adelaide, SA, Australia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;AKL&quot;,&quot;l&quot;:&quot;Auckland, New Zealand&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;BNE&quot;,&quot;l&quot;:&quot;Brisbane, QLD, Australia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;MEL&quot;,&quot;l&quot;:&quot;Melbourne, VIC, Australia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;NOU&quot;,&quot;l&quot;:&quot;Noumea, New caledonia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;PER&quot;,&quot;l&quot;:&quot;Perth, WA, Australia&quot;}&apos;,
                &apos;{&quot;s&quot;:&quot;SYD&quot;,&quot;l&quot;:&quot;Sydney, NSW, Australia&quot;}&apos;
            ];
            let area = data.split(&quot;colo=&quot;)[1].split(&quot;\n&quot;)[0];
            for (var i = 0; i &amp;lt; areas.length; i++) {
                const as = JSON.parse(areas[i]);
                if (as.s == area) {
                    document.getElementById(&quot;cdn&quot;).innerHTML = as.l;
                    break;
                };
            }
        }
    }
    )
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;p&gt;修改版将所有的中国节点加上了国旗emoji，替换为了中文，有兴趣的同学也可以自行替换其他节点&lt;/p&gt;
&lt;p&gt;不过Cloudflare大陆节点只有Enterprise Plan用户且已备案才能使用，&lt;s&gt;咱也不是sukka那种巨佬&lt;/s&gt;我不认为能看到大陆节点出现的那一天😢&lt;/p&gt;
&lt;h3&gt;原理&lt;/h3&gt;
&lt;p&gt;Cloudflare为所有客户加上了&lt;code&gt;/cdn-cgi/&lt;/code&gt;端点，任何一个套了Cloudflare的网站访问&lt;code&gt;example.com/cdn-cgi/trace&lt;/code&gt;后都会返回用户现在的信息，如ip地址、CDN节点、是否开启WARP、tls协议版本等。&lt;/p&gt;
&lt;p&gt;那么就可以在前端访问这个端点，再进行解析，将内容写入前段对应id的标签内，就可以呈现出目前的用户与Cloudflare CDN间的关系了。&lt;/p&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;h3&gt;前提&lt;/h3&gt;
&lt;p&gt;由于使用了jQuery来访问&lt;code&gt;cdn-cgi&lt;/code&gt;，所以使用这个脚本需要先引入这个库。已经引用了此库的博客无需再次引用。&lt;/p&gt;
&lt;p&gt;目前大部分博客都用了jQuery库，所以大概率无需改代码。实在没有的可以简单改写下该脚本再使用&lt;/p&gt;
&lt;p&gt;min缩减版：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$(document).ready($.ajax({url: &quot;/cdn-cgi/trace&quot;,success: function(data, status) {let areas=[&apos;{&quot;s&quot;:&quot;TNR&quot;,&quot;l&quot;:&quot;Antananarivo, Madagascar&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CPT&quot;,&quot;l&quot;:&quot;Cape Town, South Africa&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CMN&quot;,&quot;l&quot;:&quot;Casablanca, Morocco&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DAR&quot;,&quot;l&quot;:&quot;Dar Es Salaam, Tanzania&quot;}&apos;,&apos;{&quot;s&quot;:&quot;JIB&quot;,&quot;l&quot;:&quot;Djibouti City, Djibouti&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DUR&quot;,&quot;l&quot;:&quot;Durban, South Africa&quot;}&apos;,&apos;{&quot;s&quot;:&quot;JNB&quot;,&quot;l&quot;:&quot;Johannesburg, South Africa&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KGL&quot;,&quot;l&quot;:&quot;Kigali, Rwanda&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LOS&quot;,&quot;l&quot;:&quot;Lagos, Nigeria&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LAD&quot;,&quot;l&quot;:&quot;Luanda, Angola&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MPM&quot;,&quot;l&quot;:&quot;Maputo, MZ&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MBA&quot;,&quot;l&quot;:&quot;Mombasa, Kenya&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MRU&quot;,&quot;l&quot;:&quot;Port Louis, Mauritius&quot;}&apos;,&apos;{&quot;s&quot;:&quot;RUN&quot;,&quot;l&quot;:&quot;Réunion, France&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BLR&quot;,&quot;l&quot;:&quot;Bangalore, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BKK&quot;,&quot;l&quot;:&quot;Bangkok, Thailand&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BWN&quot;,&quot;l&quot;:&quot;Bandar Seri Begawan, Brunei&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CEB&quot;,&quot;l&quot;:&quot;Cebu, Philippines&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CTU&quot;,&quot;l&quot;:&quot;成都, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MAA&quot;,&quot;l&quot;:&quot;Chennai, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CGP&quot;,&quot;l&quot;:&quot;Chittagong, Bangladesh&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CKG&quot;,&quot;l&quot;:&quot;重庆, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CMB&quot;,&quot;l&quot;:&quot;Colombo, Sri Lanka&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DAC&quot;,&quot;l&quot;:&quot;Dhaka, Bangladesh&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SZX&quot;,&quot;l&quot;:&quot;东莞, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;FUO&quot;,&quot;l&quot;:&quot;佛山, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;FOC&quot;,&quot;l&quot;:&quot;福州, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CAN&quot;,&quot;l&quot;:&quot;广州, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HGH&quot;,&quot;l&quot;:&quot;杭州, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HAN&quot;,&quot;l&quot;:&quot;Hanoi, Vietnam&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HNY&quot;,&quot;l&quot;:&quot;衡阳, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SGN&quot;,&quot;l&quot;:&quot;Ho Chi Minh City, Vietnam&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HKG&quot;,&quot;l&quot;:&quot;🇭🇰 香港&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HYD&quot;,&quot;l&quot;:&quot;Hyderabad, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ISB&quot;,&quot;l&quot;:&quot;Islamabad, Pakistan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CGK&quot;,&quot;l&quot;:&quot;Jakarta, Indonesia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TNA&quot;,&quot;l&quot;:&quot;济南, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KHI&quot;,&quot;l&quot;:&quot;Karachi, Pakistan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KTM&quot;,&quot;l&quot;:&quot;Kathmandu, Nepal&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CCU&quot;,&quot;l&quot;:&quot;Kolkata, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KUL&quot;,&quot;l&quot;:&quot;Kuala Lumpur, Malaysia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LHE&quot;,&quot;l&quot;:&quot;Lahore, Pakistan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;NAY&quot;,&quot;l&quot;:&quot;廊坊, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LYA&quot;,&quot;l&quot;:&quot;洛阳, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MFM&quot;,&quot;l&quot;:&quot;🇲🇴 澳门&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MLE&quot;,&quot;l&quot;:&quot;Malé, Maldives&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MNL&quot;,&quot;l&quot;:&quot;Manila, Philippines&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BOM&quot;,&quot;l&quot;:&quot;Mumbai, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;NAG&quot;,&quot;l&quot;:&quot;Nagpur, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;NNG&quot;,&quot;l&quot;:&quot;南宁, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DEL&quot;,&quot;l&quot;:&quot;New Delhi, India&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KIX&quot;,&quot;l&quot;:&quot;Osaka, Japan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PNH&quot;,&quot;l&quot;:&quot;Phnom Penh, Cambodia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TAO&quot;,&quot;l&quot;:&quot;青岛, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ICN&quot;,&quot;l&quot;:&quot;Seoul, South Korea&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SHA&quot;,&quot;l&quot;:&quot;上海, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SHE&quot;,&quot;l&quot;:&quot;沈阳, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SJW&quot;,&quot;l&quot;:&quot;石家庄, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SIN&quot;,&quot;l&quot;:&quot;Singapore, Singapore&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SZV&quot;,&quot;l&quot;:&quot;苏州, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TPE&quot;,&quot;l&quot;:&quot;台北, 🇨🇳 台湾&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PBH&quot;,&quot;l&quot;:&quot;Thimphu, Bhutan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TSN&quot;,&quot;l&quot;:&quot;天津, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;NRT&quot;,&quot;l&quot;:&quot;Tokyo, Japan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ULN&quot;,&quot;l&quot;:&quot;Ulaanbaatar, Mongolia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;VTE&quot;,&quot;l&quot;:&quot;Vientiane, Laos&quot;}&apos;,&apos;{&quot;s&quot;:&quot;WUH&quot;,&quot;l&quot;:&quot;武汉, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;WUX&quot;,&quot;l&quot;:&quot;无锡, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;XIY&quot;,&quot;l&quot;:&quot;西安, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;EVN&quot;,&quot;l&quot;:&quot;Yerevan, Armenia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CGO&quot;,&quot;l&quot;:&quot;郑州, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CSX&quot;,&quot;l&quot;:&quot;株洲, 🇨🇳 中国大陆&quot;}&apos;,&apos;{&quot;s&quot;:&quot;AMS&quot;,&quot;l&quot;:&quot;Amsterdam, Netherlands&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ATH&quot;,&quot;l&quot;:&quot;Athens, Greece&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BCN&quot;,&quot;l&quot;:&quot;Barcelona, Spain&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BEG&quot;,&quot;l&quot;:&quot;Belgrade, Serbia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TXL&quot;,&quot;l&quot;:&quot;Berlin, Germany&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BRU&quot;,&quot;l&quot;:&quot;Brussels, Belgium&quot;}&apos;,&apos;{&quot;s&quot;:&quot;OTP&quot;,&quot;l&quot;:&quot;Bucharest, Romania&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BUD&quot;,&quot;l&quot;:&quot;Budapest, Hungary&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KIV&quot;,&quot;l&quot;:&quot;Chișinău, Moldova&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CPH&quot;,&quot;l&quot;:&quot;Copenhagen, Denmark&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ORK&quot;,&quot;l&quot;:&quot;Cork, Ireland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DUB&quot;,&quot;l&quot;:&quot;Dublin, Ireland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DUS&quot;,&quot;l&quot;:&quot;Düsseldorf, Germany&quot;}&apos;,&apos;{&quot;s&quot;:&quot;EDI&quot;,&quot;l&quot;:&quot;Edinburgh, United Kingdom&quot;}&apos;,&apos;{&quot;s&quot;:&quot;FRA&quot;,&quot;l&quot;:&quot;Frankfurt, Germany&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GVA&quot;,&quot;l&quot;:&quot;Geneva, Switzerland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GOT&quot;,&quot;l&quot;:&quot;Gothenburg, Sweden&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HAM&quot;,&quot;l&quot;:&quot;Hamburg, Germany&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HEL&quot;,&quot;l&quot;:&quot;Helsinki, Finland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;IST&quot;,&quot;l&quot;:&quot;Istanbul, Turkey&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KBP&quot;,&quot;l&quot;:&quot;Kyiv, Ukraine&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LIS&quot;,&quot;l&quot;:&quot;Lisbon, Portugal&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LHR&quot;,&quot;l&quot;:&quot;London, United Kingdom&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LUX&quot;,&quot;l&quot;:&quot;Luxembourg City, Luxembourg&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MAD&quot;,&quot;l&quot;:&quot;Madrid, Spain&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MAN&quot;,&quot;l&quot;:&quot;Manchester, United Kingdom&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MRS&quot;,&quot;l&quot;:&quot;Marseille, France&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MXP&quot;,&quot;l&quot;:&quot;Milan, Italy&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DME&quot;,&quot;l&quot;:&quot;Moscow, Russia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MUC&quot;,&quot;l&quot;:&quot;Munich, Germany&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LCA&quot;,&quot;l&quot;:&quot;Nicosia, Cyprus&quot;}&apos;,&apos;{&quot;s&quot;:&quot;OSL&quot;,&quot;l&quot;:&quot;Oslo, Norway&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CDG&quot;,&quot;l&quot;:&quot;Paris, France&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PRG&quot;,&quot;l&quot;:&quot;Prague, Czech Republic&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KEF&quot;,&quot;l&quot;:&quot;Reykjavík, Iceland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;RIX&quot;,&quot;l&quot;:&quot;Riga, Latvia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;FCO&quot;,&quot;l&quot;:&quot;Rome, Italy&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LED&quot;,&quot;l&quot;:&quot;Saint Petersburg, Russia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SOF&quot;,&quot;l&quot;:&quot;Sofia, Bulgaria&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ARN&quot;,&quot;l&quot;:&quot;Stockholm, Sweden&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TLL&quot;,&quot;l&quot;:&quot;Tallinn, Estonia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SKG&quot;,&quot;l&quot;:&quot;Thessaloniki, Greece&quot;}&apos;,&apos;{&quot;s&quot;:&quot;VIE&quot;,&quot;l&quot;:&quot;Vienna, Austria&quot;}&apos;,&apos;{&quot;s&quot;:&quot;VNO&quot;,&quot;l&quot;:&quot;Vilnius, Lithuania&quot;}&apos;,&apos;{&quot;s&quot;:&quot;WAW&quot;,&quot;l&quot;:&quot;Warsaw, Poland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ZAG&quot;,&quot;l&quot;:&quot;Zagreb, Croatia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ZRH&quot;,&quot;l&quot;:&quot;Zürich, Switzerland&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ARI&quot;,&quot;l&quot;:&quot;Arica, Chile&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ASU&quot;,&quot;l&quot;:&quot;Asunción, Paraguay&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BOG&quot;,&quot;l&quot;:&quot;Bogotá, Colombia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;EZE&quot;,&quot;l&quot;:&quot;Buenos Aires, Argentina&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CWB&quot;,&quot;l&quot;:&quot;Curitiba, Brazil&quot;}&apos;,&apos;{&quot;s&quot;:&quot;FOR&quot;,&quot;l&quot;:&quot;Fortaleza, Brazil&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GUA&quot;,&quot;l&quot;:&quot;Guatemala City, Guatemala&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LIM&quot;,&quot;l&quot;:&quot;Lima, Peru&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MDE&quot;,&quot;l&quot;:&quot;Medellín, Colombia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PTY&quot;,&quot;l&quot;:&quot;Panama City, Panama&quot;}&apos;,&apos;{&quot;s&quot;:&quot;POA&quot;,&quot;l&quot;:&quot;Porto Alegre, Brazil&quot;}&apos;,&apos;{&quot;s&quot;:&quot;UIO&quot;,&quot;l&quot;:&quot;Quito, Ecuador&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GIG&quot;,&quot;l&quot;:&quot;Rio de Janeiro, Brazil&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GRU&quot;,&quot;l&quot;:&quot;São Paulo, Brazil&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SCL&quot;,&quot;l&quot;:&quot;Santiago, Chile&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CUR&quot;,&quot;l&quot;:&quot;Willemstad, Curaçao&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GND&quot;,&quot;l&quot;:&quot;St. George‘s, Grenada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;AMM&quot;,&quot;l&quot;:&quot;Amman, Jordan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BGW&quot;,&quot;l&quot;:&quot;Baghdad, Iraq&quot;}&apos;,&apos;{&quot;s&quot;:&quot;GYD&quot;,&quot;l&quot;:&quot;Baku, Azerbaijan&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BEY&quot;,&quot;l&quot;:&quot;Beirut, Lebanon&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DOH&quot;,&quot;l&quot;:&quot;Doha, Qatar&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DXB&quot;,&quot;l&quot;:&quot;Dubai, United Arab Emirates&quot;}&apos;,&apos;{&quot;s&quot;:&quot;KWI&quot;,&quot;l&quot;:&quot;Kuwait City, Kuwait&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BAH&quot;,&quot;l&quot;:&quot;Manama, Bahrain&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MCT&quot;,&quot;l&quot;:&quot;Muscat, Oman&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ZDM&quot;,&quot;l&quot;:&quot;Ramallah&quot;}&apos;,&apos;{&quot;s&quot;:&quot;RUH&quot;,&quot;l&quot;:&quot;Riyadh, Saudi Arabia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TLV&quot;,&quot;l&quot;:&quot;Tel Aviv, Israel&quot;}&apos;,&apos;{&quot;s&quot;:&quot;IAD&quot;,&quot;l&quot;:&quot;Ashburn, VA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ATL&quot;,&quot;l&quot;:&quot;Atlanta, GA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BOS&quot;,&quot;l&quot;:&quot;Boston, MA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BUF&quot;,&quot;l&quot;:&quot;Buffalo, NY, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YYC&quot;,&quot;l&quot;:&quot;Calgary, AB, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CLT&quot;,&quot;l&quot;:&quot;Charlotte, NC, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ORD&quot;,&quot;l&quot;:&quot;Chicago, IL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;CMH&quot;,&quot;l&quot;:&quot;Columbus, OH, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DFW&quot;,&quot;l&quot;:&quot;Dallas, TX, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DEN&quot;,&quot;l&quot;:&quot;Denver, CO, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;DTW&quot;,&quot;l&quot;:&quot;Detroit, MI, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;HNL&quot;,&quot;l&quot;:&quot;Honolulu, HI, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;IAH&quot;,&quot;l&quot;:&quot;Houston, TX, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;IND&quot;,&quot;l&quot;:&quot;Indianapolis, IN, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;JAX&quot;,&quot;l&quot;:&quot;Jacksonville, FL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MCI&quot;,&quot;l&quot;:&quot;Kansas City, MO, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LAS&quot;,&quot;l&quot;:&quot;Las Vegas, NV, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;LAX&quot;,&quot;l&quot;:&quot;Los Angeles, CA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MFE&quot;,&quot;l&quot;:&quot;McAllen, TX, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MEM&quot;,&quot;l&quot;:&quot;Memphis, TN, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MEX&quot;,&quot;l&quot;:&quot;Mexico City, Mexico&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MIA&quot;,&quot;l&quot;:&quot;Miami, FL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MSP&quot;,&quot;l&quot;:&quot;Minneapolis, MN, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MGM&quot;,&quot;l&quot;:&quot;Montgomery, AL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YUL&quot;,&quot;l&quot;:&quot;Montréal, QC, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BNA&quot;,&quot;l&quot;:&quot;Nashville, TN, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;EWR&quot;,&quot;l&quot;:&quot;Newark, NJ, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ORF&quot;,&quot;l&quot;:&quot;Norfolk, VA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;OMA&quot;,&quot;l&quot;:&quot;Omaha, NE, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PHL&quot;,&quot;l&quot;:&quot;Philadelphia, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PHX&quot;,&quot;l&quot;:&quot;Phoenix, AZ, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PIT&quot;,&quot;l&quot;:&quot;Pittsburgh, PA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PAP&quot;,&quot;l&quot;:&quot;Port-Au-Prince, Haiti&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PDX&quot;,&quot;l&quot;:&quot;Portland, OR, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;QRO&quot;,&quot;l&quot;:&quot;Queretaro, MX, Mexico&quot;}&apos;,&apos;{&quot;s&quot;:&quot;RIC&quot;,&quot;l&quot;:&quot;Richmond, Virginia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SMF&quot;,&quot;l&quot;:&quot;Sacramento, CA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SLC&quot;,&quot;l&quot;:&quot;Salt Lake City, UT, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SAN&quot;,&quot;l&quot;:&quot;San Diego, CA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SJC&quot;,&quot;l&quot;:&quot;San Jose, CA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YXE&quot;,&quot;l&quot;:&quot;Saskatoon, SK, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SEA&quot;,&quot;l&quot;:&quot;Seattle, WA, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;STL&quot;,&quot;l&quot;:&quot;St. Louis, MO, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TPA&quot;,&quot;l&quot;:&quot;Tampa, FL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YYZ&quot;,&quot;l&quot;:&quot;Toronto, ON, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YVR&quot;,&quot;l&quot;:&quot;Vancouver, BC, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;TLH&quot;,&quot;l&quot;:&quot;Tallahassee, FL, United States&quot;}&apos;,&apos;{&quot;s&quot;:&quot;YWG&quot;,&quot;l&quot;:&quot;Winnipeg, MB, Canada&quot;}&apos;,&apos;{&quot;s&quot;:&quot;ADL&quot;,&quot;l&quot;:&quot;Adelaide, SA, Australia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;AKL&quot;,&quot;l&quot;:&quot;Auckland, New Zealand&quot;}&apos;,&apos;{&quot;s&quot;:&quot;BNE&quot;,&quot;l&quot;:&quot;Brisbane, QLD, Australia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;MEL&quot;,&quot;l&quot;:&quot;Melbourne, VIC, Australia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;NOU&quot;,&quot;l&quot;:&quot;Noumea, New caledonia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;PER&quot;,&quot;l&quot;:&quot;Perth, WA, Australia&quot;}&apos;,&apos;{&quot;s&quot;:&quot;SYD&quot;,&quot;l&quot;:&quot;Sydney, NSW, Australia&quot;}&apos;];let area = data.split(&quot;colo=&quot;)[1].split(&quot;\n&quot;)[0];for (var i = 0; i &amp;lt; areas.length; i++) {const as = JSON.parse(areas[i]);if (as.s == area) {document.getElementById(&quot;cdn&quot;).innerHTML = as.l;break;}}}}));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;放入&lt;code&gt;&amp;lt;script&amp;gt;&amp;lt;/script&amp;gt;&lt;/code&gt;内或者作为文件引用皆可。&lt;/p&gt;
&lt;h3&gt;显示节点信息&lt;/h3&gt;
&lt;p&gt;在想要呈现节点信息的地方添加&lt;code&gt;&amp;lt;span id=&quot;cdn&quot;&amp;gt;&amp;lt;/span&amp;gt;&lt;/code&gt;即可&lt;/p&gt;
&lt;p&gt;效果可见本博客下方⬇️&lt;/p&gt;
</content:encoded></item><item><title>错过 B 站上心爱的直播？试试这个&apos;录播姬&apos;！</title><link>https://blog.moraxyc.com/posts/bililiverecorder_bililiveauto/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/bililiverecorder_bililiveauto/</guid><description>mikufans录播姬~</description><pubDate>Tue, 16 Aug 2022 05:11:02 GMT</pubDate><content:encoded>&lt;p&gt;:::note[更新日志]
2023-02-06 替换systemd持久化运行方式为pm2
:::&lt;/p&gt;
&lt;h2&gt;&lt;s&gt;广告&lt;/s&gt;&lt;/h2&gt;
&lt;p&gt;明明加了特别关注，Bilibili 却从不提醒；明明天天刷 B 站，却总是刷不到正在直播的 TA……&lt;/p&gt;
&lt;p&gt;你，是否有这样的烦恼？你，是否为此感到困惑？&lt;/p&gt;
&lt;p&gt;现在，录播姬来了！让你不再错过任何一场直播！就算一时有事，也能记录下这美好时刻！&lt;/p&gt;
&lt;p&gt;&lt;s&gt;录播姬打钱&lt;/s&gt;&lt;/p&gt;
&lt;h2&gt;前言&lt;/h2&gt;
&lt;p&gt;咳咳，说回正题。&lt;/p&gt;
&lt;p&gt;老是错过哔哩哔哩上的直播，为此我很是苦恼。&lt;/p&gt;
&lt;p&gt;都说遇事不决&lt;s&gt;量子力学&lt;/s&gt;就上 Github。于是，我找到了这款优秀的开源项目：&lt;a href=&quot;https://github.com/BililiveRecorder/BililiveRecorder&quot;&gt;录播姬 | BiliBili Stream Recorder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这个开源项目完整度极高，多平台支持，所以没有服务器的同学也不用担心用不了，只是稍微麻烦点。&lt;/p&gt;
&lt;p&gt;那就简单说说如何使用和配置通知服务吧~&lt;/p&gt;
&lt;h2&gt;安装、配置&amp;amp;使用&amp;lt;sub&amp;gt;（仅简要说明，官方文档更详细）&amp;lt;/sub&amp;gt;&lt;/h2&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://rec.danmuji.org/&quot;&gt;录播姬官方网站&lt;/a&gt; 提供可以自动更新的编译版本。自行根据系统架构选择即可 (&lt;a href=&quot;https://github.com/BililiveRecorder/BililiveRecorder/releases/latest/download/BililiveRecorder-CLI-linux-x64.zip&quot;&gt;Github 上录播姬 Linux amd64 版本安装包&lt;/a&gt;)&lt;/p&gt;
&lt;h3&gt;安装&lt;/h3&gt;
&lt;p&gt;本教程默认下载后的安装包名为&lt;code&gt;BililiveRecorder-CLI-linux-x64.zip&lt;/code&gt;, 安装目录为&lt;code&gt;brec&lt;/code&gt;, 程序目录为&lt;code&gt;brec/work&lt;/code&gt;, 工作目录为&lt;code&gt;brec/file&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使用 Systemd 作为后台运行服务，为保证安全以用户&lt;code&gt;brec&lt;/code&gt;运行&lt;/p&gt;
&lt;p&gt;本教程中运行系统为&lt;code&gt;Debian&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;准备&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;apt update
apt upgrade
apt install zip -y #安装后续所需软件

useradd brec #创建用户 brec

mkdir -p brec/file brec/work
chown -R brec:brec brec #将 brec 目录所有权转移给用户 brec
su brec #切换到用户 brec

cd brec/work
unzip BililiveRecorder-CLI-linux-x64.zip
mv BililiveRecorder.Cli brec
chmod +x brec
./brec --version #检查录播姬是否能正常运行
exit #退出用户 brec
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置 Systemd 运行&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;nano /etc/systemd/system/brec.service #创建 Systemd 服务文件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;brec.service 文件模板如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=BililiveRecorder
After=network.target

[Service]
User=brec
ExecStart=&amp;lt;dir&amp;gt;/brec/work/brec run  --bind &quot;http://*:23567&quot; --http-basic-user &quot;&amp;lt;username&amp;gt;&quot; --http-basic-pass &quot;&amp;lt;password&amp;gt;&quot; &quot;&amp;lt;dir&amp;gt;/brec/file&quot;

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;模板内共有四个占位符，两个重复：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;dir&amp;gt;&lt;/code&gt;表示&lt;code&gt;brec&lt;/code&gt;文件夹所在目录&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;username&amp;gt;&lt;/code&gt;表示开启 http 访问后认证的用户名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;password&amp;gt;&lt;/code&gt;表示开启 http 访问后认证的密码&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;编辑完 systemd 服务文件并保存后，别忘了&lt;code&gt;systemctl daemon-reload&lt;/code&gt;来重载 Systemd&lt;/p&gt;
&lt;p&gt;接下来开启 brec 服务&lt;code&gt;systemctl start brec&lt;/code&gt;, http 服务将会在 23567 端口开放&lt;/p&gt;
&lt;p&gt;如果需要开机启动就
&lt;code&gt;systemctl enable brec&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;担心安全问题或者想开启域名访问，用Caddy反代开启tls即可&lt;/p&gt;
&lt;h3&gt;配置&lt;/h3&gt;
&lt;p&gt;录播姬的配置说明非常简单且详尽，不需要更多的解释和说明&lt;/p&gt;
&lt;h2&gt;自动脚本实现通知、转码、上传&lt;/h2&gt;
&lt;p&gt;虽然我们已经配置好录播姬，也可以很轻松地添加房间号、自动录制了。但作为一个懒人，没有提醒、自动上传分类、弹幕转码怎么行！&lt;/p&gt;
&lt;p&gt;这个板块主要分享一个小脚本，涵盖 Telegram 提醒、弹幕转码、Rclone 自动上传网盘等功能&lt;/p&gt;
&lt;p&gt;代码开源在 Github，本文内容可能不会及时更新，以托管在 GitHub 内的最新版本为准&lt;/p&gt;
&lt;h3&gt;下载&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/Morax-xyc/Bililiveauto
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;基本原理&lt;/h3&gt;
&lt;p&gt;首先需要监听录播姬的 Webhook, 所以选 JavaScript 为语言，Nodejs 为运行时环境&lt;/p&gt;
&lt;p&gt;使用 express web 框架作为接受服务器，代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const dotenv = require(&quot;dotenv&quot;)
dotenv.config()
const express = require(’express‘);
const app = express();
 
app.use(express.json({ extended: false }));
app.post(’/bililive‘, function (req, res) {
    res.sendStatus(200);
})

var server = app.listen(process.env.port, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log(&quot;BiliLiveAuto脚本正在运行, 地址为 http://%s:%s&quot;, host, port);
})
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中引入了dotenv库来读取.env作为配置文件&lt;/p&gt;
&lt;p&gt;接收完录播姬传递的webhook，根据其中&lt;code&gt;EventType&lt;/code&gt;的值来判断录播姬传递的事件类型&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;switch(req.body.EventType) {
        case &quot;FileClosed&quot;:
           &amp;lt;略&amp;gt;
            break;
        case &quot;StreamStarted&quot;:
           &amp;lt;略&amp;gt;
            break;
        case &quot;SessionStarted&quot;:
           &amp;lt;略&amp;gt;
            break;
        case &quot;StreamEnded&quot;:
           &amp;lt;略&amp;gt;
            break;
        default:
            console.log(&quot;Webhook: 判断类型: &quot; + req.body.EventType + &quot; =&amp;gt; 提醒未发送&quot;);
    };
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果接收到开播、下播、录制的webhook，就通过tgnotice.js模块通知；接收到&quot;文件关闭&quot;的webhook，就启动runbash.js模块来运行bash指令转码、上传&lt;/p&gt;
&lt;h3&gt;配置&lt;/h3&gt;
&lt;p&gt;此脚本使用.env文件作为配置文件，模板如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# .env

#run
port=8081
rclonedir=od:/Bililive # rclone中配置的上传地址
danmufc=/home/danmu/DM # danmakufactory编译后的二进制文件
workdir=/home/bililiveauto # 脚本所在文件夹
bilifile=/home/brec/file # 录播姬的工作目录

#Telegram
TG_CHAT_ID=12345678 # Telegram ID
TG_TOKEN=9876543:abcdeffhijklmnopqrstuvwxyz # Telegram Bot Token

#功能开关

#是否上传原始文件？true/false
uploadorigin=false

#是否删除本地文件？true/false
deletelocal=true
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;通知&lt;/h4&gt;
&lt;p&gt;本脚本使用Telegram来通知，只需要向&lt;a href=&quot;https://t.me/userinfobot&quot;&gt;@userinfobot&lt;/a&gt;发送任意消息即可得到Telegram ID; 向&lt;a href=&quot;https://t.me/BotFather&quot;&gt;@BotFather&lt;/a&gt;申请Bot获得Bot Token&lt;/p&gt;
&lt;p&gt;最后将两者填入配置文件即可&lt;/p&gt;
&lt;p&gt;:::tip[最终步骤]
当然要记得私聊一下你的bot
:::&lt;/p&gt;
&lt;h4&gt;弹幕处理&lt;/h4&gt;
&lt;p&gt;弹幕处理使用了一个叫&lt;a href=&quot;https://github.com/hihkm/DanmakuFactory&quot;&gt;DanmakuFactory&lt;/a&gt;的项目&lt;/p&gt;
&lt;p&gt;配置文件中的danmufc就需要自行编译&lt;a href=&quot;https://github.com/hihkm/DanmakuFactory&quot;&gt;DanmakuFactory&lt;/a&gt;后填入编译好的二进制文件地址&lt;/p&gt;
&lt;p&gt;请在编译完成后自行配置并加上&lt;code&gt;--save&lt;/code&gt;参数保存json文件以便使用。也可以使用下面我的配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;resolution&quot;: [1920, 1080],
    &quot;scrolltime&quot;: 12.000000,
    &quot;fixtime&quot;: 5.000000,
    &quot;density&quot;: -1,
    &quot;fontname&quot;: &quot;Microsoft YaHei&quot;,
    &quot;fontsize&quot;: 38,
    &quot;opacity&quot;: 180,
    &quot;outline&quot;: 0,
    &quot;shadow&quot;: 1,
    &quot;displayArea&quot;: 0.300000,
    &quot;scrollArea&quot;: 0.300000,
    &quot;bold&quot;: false,
    &quot;showUsernames&quot;: false,
    &quot;showMsgbox&quot;: false,
    &quot;msgboxSize&quot;: [500, 1080],
    &quot;msgboxPos&quot;: [10, 0],
    &quot;msgboxFontsize&quot;: 35,
    &quot;giftMinPrice&quot;: 0.00,
    &quot;blockmode&quot;: [&quot;Btm&quot;,&quot;Special&quot;,&quot;Repeat&quot;],
    &quot;statmode&quot;: []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;保存在编译好的二进制文件所在目录下的&lt;code&gt;DanmakuFactoryConfig.json&lt;/code&gt;即可&lt;/p&gt;
&lt;p&gt;本配置去除所有特殊弹幕、只在30%的屏幕上显示弹幕、共显示12秒、去除重复弹幕&lt;/p&gt;
&lt;h4&gt;自动转封装&lt;/h4&gt;
&lt;p&gt;本脚本使用FFmpeg来处理视频文件&lt;/p&gt;
&lt;p&gt;录播姬录制下来的文件为flv格式，但编码却是h264，所以可以很方便地转封装为mkv格式&lt;/p&gt;
&lt;h4&gt;自动上传&lt;/h4&gt;
&lt;p&gt;自动上传使用rclone&lt;/p&gt;
&lt;p&gt;安装脚本:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl https://rclone.org/install.sh | sudo bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置及使用建议Google一下，教程太多就不反复造轮子了&lt;/p&gt;
&lt;h3&gt;运行&lt;/h3&gt;
&lt;p&gt;运行本脚本需要先安装nodejs&lt;/p&gt;
&lt;p&gt;建议使用nvm脚本快速安装&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash
nvm install --lts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在此脚本目录运行&lt;code&gt;node server.js&lt;/code&gt;即可&lt;/p&gt;
&lt;h4&gt;pm2持久化运行&lt;/h4&gt;
&lt;p&gt;安装pm2&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install pm2 -g
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行bililiveauto&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pm2 start server.js --name bililiveauto
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置pm2开机自启
root用户全自动，非root用户请执行命令后根据提示复制命令执行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pm2 startup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;储存当前服务列表并加入自启&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pm2 save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此致，你的bililiveauto将自动在后台运行并在重启时自启。可使用&lt;code&gt;pm2 status&lt;/code&gt;查看服务状态，&lt;code&gt;pm2 logs bililiveauto&lt;/code&gt;查看日志，&lt;code&gt;pm2 monit&lt;/code&gt;打开状态监视器。&lt;/p&gt;
&lt;h3&gt;最后一步&lt;/h3&gt;
&lt;p&gt;在录播姬的设置里, 将地址填入&quot;webhook v2&quot;即可, 如&quot;http://127.0.0.1:8081&quot;&lt;/p&gt;
</content:encoded></item><item><title>避免DNS污染！我的DNS解决方案--AdGuard Home</title><link>https://blog.moraxyc.com/posts/dns-project/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/dns-project/</guid><pubDate>Tue, 05 Jul 2022 18:41:05 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;ps: 很久没写博客了，最近又折腾了不少东西，有空了慢慢写出来…&lt;/p&gt;
&lt;h2&gt;前言&amp;amp;科普&lt;/h2&gt;
&lt;h3&gt;DNS污染&lt;/h3&gt;
&lt;p&gt;由于中国大陆较为特殊的网络环境，DNS[^2]一直都是比较麻烦的问题。&lt;/p&gt;
&lt;p&gt;由于DNS污染&lt;a href=&quot;%E4%B8%8D%E7%89%B9%E6%8C%87GFW%E3%80%82%5B%E7%9B%B8%E5%85%B3%E7%A0%94%E7%A9%B6%5D(https://gfwrev.blogspot.com/2009/11/gfwDNS.html)&quot;&gt;^3&lt;/a&gt;，访问网页经常被阻。&lt;/p&gt;
&lt;p&gt;就算通过代理连接DNS，速度也会成为问题。&lt;/p&gt;
&lt;p&gt;当然，肯定会有同学疑惑：&quot;诶？我不用大陆的DNS，我用8.8.8.8不就行了？&quot;但问题在于，现在中国大陆的DNS标准端口53查询都会被ISP抢答，依然存在污染。&lt;/p&gt;
&lt;p&gt;那么，选择一个速度足够快，且没有被污染的DNS就是一个重要的话题。&lt;/p&gt;
&lt;h3&gt;解决方法&lt;/h3&gt;
&lt;p&gt;俗话说，魔高一尺，道高一丈。当然有办法来应对这种dns劫持。两种方法最为常见：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用非标准端口未污染DNS&lt;a href=&quot;%E6%88%AA%E8%87%B3%E5%8F%91%E7%A8%BF%E6%97%A5%EF%BC%8C%E6%9C%89%E4%B8%80%E4%B8%AA%E5%85%AC%E7%9B%8A%E9%A1%B9%E7%9B%AE%22iQDNS%22&quot;&gt;^1&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因为非标准端口，就无法无差别抢答。缺点是…你得找到一个这样的DNS服务器。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用加密DNS&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;例如DoH(DNS over HTTPS)、DoT(DNS over TLS)、DoQ&lt;a href=&quot;AdGuard%E6%98%AF%E7%AC%AC%E4%B8%80%E4%B8%AA%E6%94%AF%E6%8C%81DoQ%E7%9A%84DNS%E8%A7%A3%E6%9E%90%E5%99%A8%E3%80%82%5BAdGuard%E5%8D%9A%E5%AE%A2%5D(https://adguard.com/zh_cn/blog/DNS-over-quic.html)&quot;&gt;^4&lt;/a&gt;(DNS over QUIC)。三种加密DNS分别使用htrps、tls、quic协议。简单对比下，doq是截至目前最好的DNS加密方法。&lt;/p&gt;
&lt;h3&gt;准备&lt;/h3&gt;
&lt;p&gt;这个方案需要用到一下设备或资源，不满足可能无法使用此方案。&lt;s&gt;当然看看也无妨&lt;/s&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[x] 手机电脑路由器…&lt;/li&gt;
&lt;li&gt;[x] 一台低延迟vps/NAS/树莓派/软路由…&lt;/li&gt;
&lt;li&gt;[x] 一枚域名&lt;a href=&quot;%E8%AF%B7%E6%B3%A8%E6%84%8F%EF%BC%8C%E8%8B%A5%E5%9F%9F%E5%90%8D%E6%89%98%E7%AE%A1%E4%BA%8ECloudflare%E5%88%99%E9%A1%BB%E5%85%B3%E9%97%AD%E4%BB%A3%E7%90%86%EF%BC%88%E5%B0%8F%E4%BA%91%E6%9C%B5%EF%BC%89%EF%BC%8C%E4%BB%85%E4%BD%BF%E7%94%A8DNS%E6%9F%A5%E8%AF%A2&quot;&gt;^7&lt;/a&gt;（二级域名更好）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AdGuard将作为后端提供DNS查询。&lt;/p&gt;
&lt;p&gt;终端还得有对应DNS的支持。截至发稿日，原生支持如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iOS: DoT和DoH&lt;/li&gt;
&lt;li&gt;Android 9.0以上: 支持DoT&lt;/li&gt;
&lt;li&gt;Windows11: 支持DoH&lt;/li&gt;
&lt;li&gt;路由器: 看固件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果没有原生支持，也可以通过软件来达到。一般来讲，代理软件都会提供DNS支持。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iOS: Quantumult X、Surge、Stash和Shadowrocket都支持DoH和DoQ。Loon未知。&lt;/li&gt;
&lt;li&gt;安卓: Clash支持DoT和DoH&lt;/li&gt;
&lt;li&gt;其他终端上的软件过多，可谷歌一下，就不赘述了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;部署&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/AdguardTeam/AdGuardHome&quot;&gt;AdGuard Home开源地址&amp;amp;部署文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://adguard.com/zh_cn/blog/in-depth-review-adguard-home.html&quot;&gt;AdGuard Home官方配置教程&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;AdGuard Home的功能很多，甚至还可以过滤广告、强制安全搜索、屏蔽NSFW…&lt;/p&gt;
&lt;h3&gt;部署平台&lt;/h3&gt;
&lt;h4&gt;vps&lt;/h4&gt;
&lt;p&gt;选择一个在香港的三网直连vps，可以有效提高日后体验。&lt;/p&gt;
&lt;p&gt;如果各位有其他适合的厂家可以在评论区留言。&lt;/p&gt;
&lt;h4&gt;树莓派&amp;amp;软路由&lt;/h4&gt;
&lt;p&gt;选择自己的心动设备即可。&lt;s&gt;毕竟玩树莓派和软路由的一般都是大佬&lt;/s&gt;&lt;/p&gt;
&lt;h4&gt;NAS&lt;/h4&gt;
&lt;p&gt;AdGuard Home提供官方 Docker镜像。&lt;/p&gt;
&lt;p&gt;没用过nas实在不知道怎么配置，请见谅～&lt;/p&gt;
&lt;h3&gt;安装AdGuard Home&lt;/h3&gt;
&lt;h4&gt;一键梭哈&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s — -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;一键梭哈，绝不拖泥带水！&lt;/p&gt;
&lt;p&gt;初始管理端口为3000，请在安装完成后及时在ip后面加&lt;code&gt;:3000&lt;/code&gt;进入初始化界面设置管理员账户。&lt;/p&gt;
&lt;h4&gt;Docker&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://hub.docker.com/r/adguard/adguardhome&quot;&gt;Docker文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;官方Docker镜像的docker命令：&lt;/p&gt;
&lt;p&gt;请对照文档自行修改配置！&lt;/p&gt;
&lt;h5&gt;Docker Run&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;docker run —name adguardhome\
    —restart unless-stopped\
    -v /my/own/workdir:/opt/adguardhome/work\
    -v /my/own/confdir:/opt/adguardhome/conf\
    -p 53:53/tcp -p 53:53/udp\
    -p 67:67/udp -p 68:68/udp\
    -p 80:80/tcp -p 443:443/tcp -p 443:443/udp -p 3000:3000/tcp\
    -p 853:853/tcp\
    -p 784:784/udp -p 853:853/udp -p 8853:8853/udp\
    -p 5443:5443/tcp -p 5443:5443/udp\
    -d adguard/adguardhome
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;Docker-compose&lt;/h5&gt;
&lt;pre&gt;&lt;code&gt;version: &apos;3.3&apos;

services:
  adguardhome:
    image: adguard/adguardhome
    container_name: adguardhome
    restart: unless-stopped
    volumes:
      - &apos;/my/own/workdir:/opt/adguardhome/work&apos;
      - &apos;/my/own/confdir:/opt/adguardhome/conf&apos;
    ports:
      - &apos;53:53/tcp&apos;
      - &apos;53:53/udp&apos;
      - &apos;67:67/udp&apos;
      - &apos;68:68/udp&apos;
      - &apos;80:80/tcp&apos;
      - &apos;443:443/tcp&apos;
      - &apos;443:443/udp&apos;
      - &apos;3000:3000/tcp&apos;
      - &apos;853:853/tcp&apos;
      - &apos;784:784/udp&apos;
      - &apos;853:853/udp&apos;
      - &apos;8853:8853/udp&apos;
      - &apos;5443:5443/tcp&apos;
      - &apos;5443:5443/udp&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置&lt;/h3&gt;
&lt;p&gt;由于AdGuard Home全部中文化且UI设计合理，本文只简述部分值得关注的配置。&lt;/p&gt;
&lt;h4&gt;设置- DNS设置-上游DNS服务器&lt;/h4&gt;
&lt;p&gt;由于选择的服务器位于香港🇭🇰，截至发稿日不存在DNS污染，故直接使用公共DNS即可。&lt;/p&gt;
&lt;p&gt;我配置的请求方式为并行请求，于是每种协议都写了至少一个。列表如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;8.8.8.8
8.8.4.4
1.1.1.1
1.0.0.1
quic://DNS.adguard.com
156.154.70.1
tls://1dot1dot1dot1.cloudflare-DNS.com
84.200.69.80
1.2.4.8
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你设置的方式并非&quot;并行请求&quot;，请注意控制列表内上游DNS数量和质量以保证最优的速度。&lt;/p&gt;
&lt;h4&gt;设置- DNS设置- DNS服务配置&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/dnsprotect/1.jpeg&quot; alt=&quot;DNS服务配置&quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;速率限制: 个人使用建议设置为0&lt;/li&gt;
&lt;li&gt;DNSSEC: 建议启用以保证上游DNS的正确&lt;/li&gt;
&lt;li&gt;弃用ipv6: 若日常使用更多为电脑，则建议关闭&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;设置- DNS设置-DNS缓存配置&lt;/h4&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/dnsprotect/2.jpeg&quot; alt=&quot;DNS缓冲配置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;TTL值建议设置为最小600, 最大3600以防止TTL不正常导致的性能问题。&lt;/p&gt;
&lt;p&gt;建议选中乐观缓存。&lt;/p&gt;
&lt;h4&gt;设置- DNS设置-访问控制&lt;/h4&gt;
&lt;p&gt;打开即意味着只能使用DoH、DoT、DoQ连接（毕竟国内个人不存在静态ip）&lt;/p&gt;
&lt;h4&gt;设置- 加密设置&lt;/h4&gt;
&lt;p&gt;按照提示填写即可。&lt;/p&gt;
&lt;p&gt;:::warning[注意]
请更改DoT和DoQ的端口以防被统一屏蔽！
:::&lt;/p&gt;
&lt;p&gt;如果绑定二级域名且托管在Cloudflare上、是为Freenom免费域名，请前往&lt;a href=&quot;https://www.freenom.com&quot;&gt;Freessl&lt;/a&gt;按照提示获取通配符证书。[^6]&lt;/p&gt;
&lt;h4&gt;设置- 客户端设置&lt;/h4&gt;
&lt;p&gt;设置客户端可以有效分离客户端的DNS查询和限制，也可用于前面的访问控制。&lt;/p&gt;
&lt;p&gt;若要让客户端识别功能和DoT、DoQ搭配使用，则绑定的域名必须为二级域名[^5]且将所有三级域名解析到此服务器，例如&lt;code&gt;example.org&lt;/code&gt;和&lt;code&gt;*.example.org&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;家里有孩子的也可以通过这个来有效单独控制成人🔞内容和众多服务禁止。&lt;/p&gt;
&lt;h4&gt;过滤器-DNS拦截/允许列表&lt;/h4&gt;
&lt;p&gt;这个板块即为广告过滤。&lt;/p&gt;
&lt;h5&gt;过滤&lt;/h5&gt;
&lt;p&gt;我使用的清单🧾如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;AdGuard DNS filter
https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt

CHN: anti-AD
https://anti-ad.net/easylist.txt

大圣净化
https://raw.githubusercontent.com/jdlingyu/ad-wars/master/hosts

EasyList China+EasyList
https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt

EasyPrivacy
https://easylist-downloads.adblockplus.org/easyprivacy.txt

Halflife
https://cdn.jsdelivr.net/gh/o0HalfLife0o/list@master/ad.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h5&gt;白名单&lt;/h5&gt;
&lt;p&gt;还有一个白名单板块，我的清单🧾如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Anti-ad白名单
https://raw.githubusercontent.com/privacy-protection-tools/dead-horse/master/anti-ad-white-list.txt

filter_whitelist
https://raw.githubusercontent.com/hl2guide/Filterlist-for-AdGuard/master/filter_whitelist.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;使用&lt;/h2&gt;
&lt;p&gt;原生使用详见AdGuard Home中的设置向导&lt;a href=&quot;%E8%AE%BE%E7%BD%AE%E5%90%91%E5%AF%BC%E4%B8%AD%E6%9C%89%E5%BE%88%E5%A4%9A%E7%A7%8D%E7%BB%88%E7%AB%AF%E3%80%82%E5%9C%A8%E6%9C%80%E5%8F%B3%E4%BE%A7%22DNS%E9%9A%90%E7%A7%81%22%E9%A1%B5%E9%9D%A2%E7%9A%84%E6%9C%80%E4%B8%8B%E9%9D%A2%E5%8F%AF%E6%89%BE%E5%88%B0%E9%80%9A%E8%BF%87%E6%8F%8F%E8%BF%B0%E6%96%87%E4%BB%B6%E5%AE%9E%E7%8E%B0DoT/DoH%E5%8E%9F%E7%94%9F%E6%94%AF%E6%8C%81%E7%9A%84%E6%9D%BF%E5%9D%97%E3%80%82&quot;&gt;^8&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;同时，设置向导中也有众多各终端通过软件实现DNS设置的方法。&lt;/p&gt;
&lt;h3&gt;举个例子🌰&lt;/h3&gt;
&lt;p&gt;这方面的太多了，我就只举个iOS上Quantumult X的例子🌰&lt;/p&gt;
&lt;p&gt;我创建了一个&lt;code&gt;myios&lt;/code&gt;的客户端id，使用的二级域名为&lt;code&gt;example.org&lt;/code&gt;，quic端口为789。那么，我需要在配置文件中使用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[DNS]
prefer-doh3
doh-server=https://example.org/DNS-query/myios
doq-server=quic://myios.example.org:789
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;强烈建议使用DoQ，它比https快太多了！&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;关于DNS，实在有太多可以说。这次文章自我感觉写起来有点杂，因为内容关联太多，很容易导致哪里漏掉了一些，哪里的逻辑有问题这些漏洞。如果发现有任何问题我没有写到或者错误、有补充，请在评论区评论。&lt;/p&gt;
&lt;p&gt;最后，感谢您的阅读！&lt;/p&gt;
&lt;p&gt;提供国内可访问的无污染DNS。&lt;a href=&quot;https://t.me/iQDNS&quot;&gt;tg频道&lt;/a&gt; &lt;a href=&quot;https://iqDNS.xyz/all.html&quot;&gt;网页&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^2]: 什么是DNS？&lt;a href=&quot;https://www.cloudflare.com/zh-cn/learning/DNS/what-is-DNS/&quot;&gt;Cloudflare Blog&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[^5]: 如若&lt;s&gt;扣&lt;/s&gt;不愿付钱购买域名，可以到&lt;a href=&quot;https://www.freenom.com&quot;&gt;Freenom&lt;/a&gt;免费注册&lt;code&gt;.ml .tk .ga .cf .gq&lt;/code&gt;TLD的域名。注册前请一定要谷歌一些教程以防入坑！&lt;/p&gt;
&lt;p&gt;[^6]:  letsencrypt的通配符证书需要DNS验证。但Cloudflare的api拒绝为&lt;code&gt;.ml .tk .ga .cf .gq&lt;/code&gt;TLD的域名验证，只能使用其他通配符证书。&lt;/p&gt;
</content:encoded></item><item><title>网络隐私保护意识的薄弱与改进措施</title><link>https://blog.moraxyc.com/posts/protect-privacy/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/protect-privacy/</guid><pubDate>Sat, 14 May 2022 05:39:28 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;:::note[自卫声明（]
本文最开始为博主为班会准备的稿子，现做了一些修改后在博客发出。本文内容较为浅显且准备时间较短，故文中可能存在一些问题，欢迎批评指正。&lt;/p&gt;
&lt;p&gt;当然，不欢迎杠精！
:::&lt;/p&gt;
&lt;h2&gt;隐私的定义&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;百度百科&quot;上对于隐私的定义：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不愿公开的&lt;a href=&quot;https://baike.baidu.com/item/%E4%BF%A1%E6%81%AF&quot;&gt;信息&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;维基百科&quot;上对于隐私权的定义：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;隐私权，指个人&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E4%BA%BA%E6%A0%BC&quot;&gt;人格&lt;/a&gt;上的利益不受不法僭用或侵害，个人与大众无合法关联的私事，亦不得妄予发布公开，而其私人活动，不得以可能造成一般人的精神痛苦或感觉羞辱之方式非法侵入的权利。是为众多&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%B3%95%E5%BE%8B&quot;&gt;法律&lt;/a&gt;系统所支持的一种&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E4%BA%BA%E6%9D%83&quot;&gt;人身基本权利&lt;/a&gt;。由于它的存在，&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%94%BF%E5%BA%9C&quot;&gt;政府&lt;/a&gt;和&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E9%9D%9E%E6%94%BF%E5%BA%9C%E7%BB%84%E7%BB%87&quot;&gt;民间团体&lt;/a&gt;的某些活动受到一定的限制。&lt;/p&gt;
&lt;p&gt;隐私权是指个人或群体隔离自己或有关自己的信息的权利。在商业世界，人们可能会自愿提供个人详细信息，包括广告信息，以便获得某种利益。公众人物可能受制于公共规则。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;中华人民共和国《民法典》对于隐私权的条例：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;隐私权：自然人享有的对自己的个人隐私进行支配并排除他人非法干涉的&lt;a href=&quot;https://www.zhihu.com/search?q=%E4%BA%BA%E6%A0%BC%E6%9D%83&amp;amp;search_source=Entity&amp;amp;hybrid_search_source=Entity&amp;amp;hybrid_search_extra=%7B%22sourceType%22%3A%22answer%22%2C%22sourceId%22%3A1669941322%7D&quot;&gt;人格权&lt;/a&gt;。任何组织或者个人不得以剌探、侵扰、泄露、公开等方式侵害他人的隐私权。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;现代社会离不开网络，现代人也越来越习惯将隐私信息放在网络上。&lt;/p&gt;
&lt;p&gt;事实上，许多人对隐私信息的定义仍然是模糊的。有人觉得照片是隐私，有人觉得手机号码是隐私，有人觉得凡是个人信息都是隐私。&lt;/p&gt;
&lt;p&gt;不过&quot;隐私&quot;俩字的含义是只要是不想被人知道的信息都是隐私。以下内容都是根据我自己不想泄露的信息而给出的隐患和保护措施。&lt;/p&gt;
&lt;p&gt;如果你不在意这些信息，请选择性忽略相关内容。&lt;/p&gt;
&lt;h1&gt;泄露的途径&lt;/h1&gt;
&lt;h2&gt;直接泄露&lt;/h2&gt;
&lt;p&gt;在网络社会中，直接泄露隐私的危害性比从前更严重。&lt;/p&gt;
&lt;p&gt;说不定只是不小心打出了自己的手机号和名字，于是就被他人记录了下来，然后卖给那些营销推广人员、诈骗犯们。&lt;/p&gt;
&lt;p&gt;于是你接到一大堆知道你名字的骚扰电话。&lt;/p&gt;
&lt;p&gt;这并非危言耸听:现在的服务器储存价格并不贵，机械硬盘几块钱几个T一个月，这对于大公司以及保存你的隐私信息并从中获利来说简直不值一提。&lt;/p&gt;
&lt;p&gt;就像网络爬虫与端口扫描网站一样，它们每天都在网络上收集各种别人的隐私信息以卖给需要的人。
许多黑客动手前一步都是在某端口扫描网站&lt;a href=&quot;%E5%8D%B3%5Bcensys.io%5D(https://censys.io)%E7%B1%BB%E7%BD%91%E7%AB%99&quot;&gt;^1&lt;/a&gt;上搜索网站域名的真实IP以采用各种CC攻击或者其他提权漏洞攻击服务器。&lt;/p&gt;
&lt;p&gt;所以各位中如果有通过CDN加速托管网站的同学一定要时时开启流量代理，不要暴露服务器IP。&lt;s&gt;让CDN承受攻击&lt;/s&gt;&lt;/p&gt;
&lt;h3&gt;主动泄露&lt;/h3&gt;
&lt;h4&gt;粗心大意&lt;/h4&gt;
&lt;p&gt;不经意间泄露自己的信息而忘了考虑泄露的后果&lt;/p&gt;
&lt;h4&gt;不重视&lt;/h4&gt;
&lt;p&gt;没有认识到隐私的重要性。当你认为自己的隐私泄露没有关系时，你并没有考虑到那些不怀好意的人:当歹徒知道你的经济情况与地址时，他可能就盯上你了;诈骗分子想方设法知道你的电话、姓名等信息以取得你的信任;你的照片可能被某个抠脚大汉套用以骗某个纯情男子;你的支付密码可以被用来登录你的账号以偷走资金……&lt;/p&gt;
&lt;h3&gt;被动泄露&lt;/h3&gt;
&lt;p&gt;有时候，即使你想方设法地保护你的隐私信息，但不知怎得，总会被泄露出去。那么这个时候，就要考虑&quot;被泄露&quot;的可能性了。&lt;/p&gt;
&lt;h4&gt;黑客攻击&lt;/h4&gt;
&lt;p&gt;这里我主要讲对于&quot;连接&quot;和&quot;服务器&quot;泄露的风险。关于通过漏洞获取信息的方式太多了，也不可能讲完。这里简单说说比较基础也比较常见的方法。&lt;/p&gt;
&lt;p&gt;虽然现今各种&quot;安全卫士&quot;层出不穷，某360安全卫士更是在国内一家独大。很多人觉得只要安装了这种&quot;安全卫士&quot;就可以在互联网上畅行无阻了。这种观念是错误的。因为安全卫士只是保护了你的电脑不被木马和病毒入侵，却无法确保你的信息不被泄露出去。&lt;/p&gt;
&lt;p&gt;网络通讯可以简单分为三个部分：客户端 连接端 远程端。这过程中，连接端和远程端都有可能泄露你的信息。有些经常上网的同学可能会发现Safari或者Chrome系浏览器有时候会在地址栏那里显示&quot;不安全&quot;的字样。这意味着你和这个服务器的连接处于http协议下，并没有被https保护，途径的一切服务器和ISP都能明文查询你和服务器的访问信息。&lt;/p&gt;
&lt;p&gt;因为https协议是一个比较高深的话题，我在这里就不详细讲了。&lt;/p&gt;
&lt;p&gt;不过即使启用了https协议依旧有两个风险：（MITM中间人攻击）&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;服务端泄露私钥导致连接被解密&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;客户端被安装恶意证书解密。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;第一个风险相当与你和服务端的密码被别人知道了，于是别人就可以通过这个密码访问你到这个服务端的信息，包括密码等一切隐私信息。&lt;/p&gt;
&lt;p&gt;第二个风险意味着你发送向外界的一切信息全部被解密，恶意证书的所有者将知道这个设备对外界的一切访问。只要服务端没有单独的加密协议，那么这些信息都将公开被知晓。所以千万千万千万小心，不要随意安装证书（iOS上称其为描述文件），除非你对这个证书知根知底。&lt;/p&gt;
&lt;h4&gt;恶意读取&lt;/h4&gt;
&lt;p&gt;现今操作系统中，除了严格限制读取权限以及使用沙盒机制外的苹果系列系统，以及对于系统有极端掌控欲的Linux高玩，所有其他系统都面临着文件读取、写入权限管理混乱的问题。即使Google在上个月（2022.2）发布了安卓将引入沙盒机制的消息，大家对此依旧充满担忧：Google从不作恶已经成为笑话，权限管理做的不如几款第三方软件，会不会被国内OS加入还是一个问号，这真的会给安卓系用户带来福音嘛？&lt;/p&gt;
&lt;h4&gt;他人泄露&lt;/h4&gt;
&lt;p&gt;&quot;他人&quot;不只指人，还包括那些服务提供商。就像网站泄露注册信息，学校泄露家长电话，CDN泄露IP等情况太多了。&lt;/p&gt;
&lt;p&gt;一个很简单的例子：我们至今不知道某度网盘会不会泄露数据。明明只是一份简单的视频文件，却被替换成只有十几秒的视频。&lt;a href=&quot;%22%E6%9F%90%E5%BA%A6%22%E5%B9%B6%E4%B8%8D%E7%89%B9%E6%8C%87%E7%99%BE%E5%BA%A6%EF%BC%8C%E7%89%B9%E6%AD%A4%E8%AF%B4%E6%98%8E&quot;&gt;^2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这种情况都会发生，我们还有什么理由相信某度网盘&lt;a href=&quot;%22%E6%9F%90%E5%BA%A6%22%E5%B9%B6%E4%B8%8D%E7%89%B9%E6%8C%87%E7%99%BE%E5%BA%A6%EF%BC%8C%E7%89%B9%E6%AD%A4%E8%AF%B4%E6%98%8E&quot;&gt;^2&lt;/a&gt;会加密我们的数据？&lt;/p&gt;
&lt;p&gt;这些服务商泄露数据也不是一天两天的事儿了。真正能顶住压力的商家终究是少数。除了从一开始就主打端对端加密的MEGA网盘外，连最硬气、力扛FBI坚决不解锁iPhone的Apple都在iCloud端对端加密服务这方面低下了头颅，FBI坚决不会允许拥有如此庞大用户群体的iCloud云盘被完全加密，现阶段没有丝毫解密的可能性的服务被提供。这使得Apple只能在部分安全敏感信息上采用绝对加密，例如健康数据、iCloud钥匙串和iPhone相关信息。&lt;/p&gt;
&lt;h2&gt;间接泄露&lt;/h2&gt;
&lt;p&gt;尽管有些人很重视隐私保护，但总是发现自己的隐私被他人知道。许多人总是不经意间泄露隐私出去。明明只是发了个挡住眼睛的自拍，却能够被知道位置在哪儿。&lt;/p&gt;
&lt;p&gt;这是个很简单的事情，凭借搜图工具，亦或者其他照片上较为明显的标志，都能很轻松的找到这个照片的关联信息，从而使你的隐私泄露。&lt;/p&gt;
&lt;p&gt;关注方面、兴趣爱好、性格等隐私也是各大公司重点关注的方面。下面我讲两个较为常见的间接泄露隐私的渠道。&lt;/p&gt;
&lt;h3&gt;综合侧写&lt;/h3&gt;
&lt;p&gt;事实上，在2021.11.1没有执行《中华人民共和国个人信息保护法》前，各大公司对于数据收集简直是可以以&quot;猖狂&quot;二字来形容。&lt;/p&gt;
&lt;p&gt;举个例子，某音作为全球下载量最高的软件，它无疑是具有极高的人气的。而是它如此迷人的原因，正在于它对用户信息大分析与定向推送。&lt;/p&gt;
&lt;p&gt;它的推荐算法是个黑盒，但运行机制大致如下:审核人员对视频打上初步分类，在第一档推荐池内进行初步标签，接着通过用户行为筛选出优良视频，然后推送至第二档及之后的推荐池不断优化视频tag，最后面向整个某音拥有视频相关tag的用户。&lt;/p&gt;
&lt;p&gt;体现在用户上，就是用户们觉得某音视频推荐的极其符合胃口，特别吸引人。&lt;/p&gt;
&lt;p&gt;当然，真正的算法没那么简单，某音绝对具有一个优秀的机制来保证流量。&lt;/p&gt;
&lt;p&gt;在这个过程中，某音收集了以下数据:用户姓名、头像、手机号码、视频观看时长、点赞对象、关注等信息。&lt;/p&gt;
&lt;p&gt;而这些信息通过对你每次观看的数据再次优化，最终生成一份用户侧写，囊括你的喜好、兴趣、性格等隐私信息。&lt;/p&gt;
&lt;p&gt;而这些信息，又会被某音共享给其他公司，例如某宝。&lt;/p&gt;
&lt;p&gt;于是，当你在某音上盯着一款手机的参数看了很久后，某宝就会不断给你弹出手机的优惠，听起来就细思极恐对吧？这些技术还有个名字:大数据分析。&lt;/p&gt;
&lt;p&gt;其实这些东西给那些大公司也没什么问题，毕竟人家需要提供优质的服务嘛。&lt;/p&gt;
&lt;p&gt;可是，这些信息并没办法被完全妥善的保管，一旦被有心人得到，可能被针对性的会有无论是诈骗还是针对，甚至对人身安全产生威胁的行为发生。&lt;/p&gt;
&lt;p&gt;近年来，这种提供&quot;个性化服务&quot;的行为越来越普遍，它也从一种优质的服务变味了。因为你提供的所有信息都来自于你过往的数据。这也就意味着，你没有办法跳出舒适圈获取新的内容，这便是&quot;信息茧房&quot;，也可以说是&quot;回音室效应&quot;。&lt;/p&gt;
&lt;p&gt;这次的演讲是关于隐私的，就不细讲了。感兴趣的同学可以在网络上搜搜，自己看看。&lt;/p&gt;
&lt;h3&gt;跟踪信息&lt;/h3&gt;
&lt;p&gt;在上一个部分中说到了某音和某宝共享信息。事实上这并不是特例，各大公司为了实现利益最大化，都进行了数据共享。&lt;/p&gt;
&lt;p&gt;但利益牵扯永远是复杂的，所以这种信息共享在最后变成由平台负责。&lt;/p&gt;
&lt;p&gt;这种平台一般叫做&quot;xx分析&quot;、&quot;xx analytics&quot;。&lt;/p&gt;
&lt;p&gt;国内，提供这种跟踪服务的公司叫&quot;百度分析&quot;，而国外叫&quot;Google Analyics&quot;。&lt;/p&gt;
&lt;p&gt;了解Apple的同学可能知道iOS 15推出了&quot;拒绝跟踪&quot;的功能。&lt;/p&gt;
&lt;p&gt;国内百度不怎么敢和Apple较量，且百度盈利并不怎么靠这种跟踪，所以没怎么在意。&lt;/p&gt;
&lt;p&gt;但谷歌的90%多的盈利都靠广告。所以iOS这项服务推出后，许多人猜测两家公司会打起来。&lt;/p&gt;
&lt;p&gt;结果谷歌反而是最支持苹果的。因为国外谷歌搜索几乎把握所有流量，完全不需要靠这个分析，而是直接通过搜索记录分析，于是戏剧性的一幕发生了:&quot;Apple禁止跟踪&quot;被全球最大跟踪器Google分析支持。&lt;/p&gt;
&lt;p&gt;除了这些自动跟踪，有些无良公司还嵌入了便于主动跟踪的代码。这个技术很常见，例如绝大多数打印机都具有这个技术，方便追踪文档泄密者与伪造钞票者。豆瓣之前就被曝光在网页使用追踪代码，滴滴在应用中嵌入对比度代码。&lt;a href=&quot;%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%5Bwebarchive%5D(https://web.archive.org)%E5%9B%9E%E6%BA%AF%E8%B1%86%E7%93%A3%E5%B0%8F%E7%BB%84%E7%9A%84%E9%A1%B5%E9%9D%A2%E6%89%BE%E5%88%B0&quot;&gt;^3&lt;/a&gt;这只是一些比较明显，可以被轻松察觉的。那些不容易察觉的跟踪代码通常被使用于应用之中：通过网页字体、屏幕大小、间距、时间、ip等多重信息生成跟踪代码。这些信息看似很常见，但事实上，几百万人中都不会出现完全一模一样的跟踪代码。&lt;/p&gt;
&lt;h1&gt;保护措施&lt;/h1&gt;
&lt;p&gt;看了那么多的隐患，是不是感觉自身已经被扒光，什么隐私都不剩了？别慌，密码学家与算法工程师、白帽黑客、SRC&lt;a href=&quot;%E5%8D%B3%E6%BC%8F%E6%B4%9E%E5%BA%94%E6%80%A5%E5%93%8D%E5%BA%94%E5%B9%B3%E5%8F%B0%EF%BC%8C%E5%9B%BD%E5%86%85%E7%9F%A5%E5%90%8D%E7%9A%84%E6%9C%89%E8%A1%A5%E5%A4%A9%E3%80%81%E8%85%BE%E8%AE%AF%E3%80%81360%E7%AD%89&quot;&gt;^4&lt;/a&gt;每天也在想着怎么保护你的隐私。下面我们看看哪些保护措施可以实施。&lt;/p&gt;
&lt;h2&gt;增强隐私保护意识&lt;/h2&gt;
&lt;h3&gt;警惕套取信息&lt;/h3&gt;
&lt;p&gt;钓鱼网站和诈骗网站便是为&quot;套取信息&quot;而服务。所以遇到那些不明链接千万别傻乎乎点进去。因为对于网站所有者而言，只要你点进去，它就赢了。网站可以根据你的访问得知你的访问IP、语言、设备、Cookie、追踪信息…千万别看到个链接就去随便点！同学们可以进入看看&lt;a href=&quot;https://whoer.net/zh&quot;&gt;whoer.net&lt;/a&gt;仅仅根据DNS查询信息就可以知道什么。&lt;/p&gt;
&lt;p&gt;当然，除了这种套取信息外，也要警惕那些&quot;卖茶小姐姐&quot;，&quot;纯情小哥哥&quot;们的骚扰，诈骗犯们可是&quot;专业&quot;的。说不定这些人背后都是抠脚大汉呢。&lt;/p&gt;
&lt;h3&gt;不使用有隐私泄露风险的软件&lt;/h3&gt;
&lt;p&gt;有隐私泄露风险的软件太多了，例如&lt;s&gt;微信（bushi&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;2021年6月，工信部对天涯社区、大麦、途牛旅游、VIP陪练、脉脉等90款侵害用户权益的App进行了下架处理。&lt;/p&gt;
&lt;p&gt;所以使用软件是一定要注意使用被信任的软件。如果开源就更好了，因为开源意味着全网程序员都在审查，防止app存在隐患。我推荐几个安全保护Max的软件：Telegram，Tor，MEGA，Cryptomator…它们都使用了End-To-End端对端加密技术，并基本开源。&lt;/p&gt;
&lt;p&gt;有些人觉得Telegram不安全，这个不用和我杠，因为Telegram只有开启&quot;加密聊天&quot;才是完全体，这种状态下的Telegram除非是实现了量子霸权的量子计算机才能短时间内破解.有人算过，用2015年全球能源去喂养Antminer R4矿机来穷举破解AES-256加密需要6.3619305×10&amp;lt;sup&amp;gt;53&amp;lt;/sup&amp;gt; s。&lt;a href=&quot;%E6%95%B0%E6%8D%AE%E7%94%B1%E5%86%99%E6%9C%AC%E6%96%87%E6%97%B6%E5%9C%A8V2EX%E6%90%9C%E7%B4%A2%E5%88%B0%E7%9A%84%E6%95%B0%E6%8D%AE%EF%BC%8C%E5%A6%82%E6%9C%89%E9%94%99%E8%AF%AF%E6%AC%A2%E8%BF%8E%E6%89%B9%E8%AF%84%E6%8C%87%E6%AD%A3%E3%80%82&quot;&gt;^5&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;密码等高风险信息妥善保管&lt;/h3&gt;
&lt;p&gt;密码这种风险过高的隐私信息一定要妥善保管。一般来讲，我们现在创建的密码都太多了，一般人根本记不住，而保存在那些文本应用里又担心泄露风险，那么你可以使用密码管理器。&lt;/p&gt;
&lt;p&gt;我推荐几个比较安全的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;KeePass（开源）&lt;/li&gt;
&lt;li&gt;BitWarden（开源，可自行部署）&lt;/li&gt;
&lt;li&gt;1Password（闭源，付费）&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;2FA双重验证&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SMS验证码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;TOTP验证码&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安全密钥&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Recovery Code&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SMS验证码就是普通手机短信验证码。&lt;/p&gt;
&lt;p&gt;TOTP验证码就是微软Authenticator、Steam手机令牌、Apple双重验证使用的技术。Apple Keychain和1Password、Bitwarden现已支持TOTP验证码。&lt;/p&gt;
&lt;p&gt;安全密钥即为Face ID、Windows Hello、Touch ID等FODI验证方法。&lt;/p&gt;
&lt;p&gt;Recovery Code就是恢复密钥，创建TOTP验证码时自动生成，唯一恢复TOTP的方法。&lt;/p&gt;
&lt;h3&gt;减少信任对象&lt;/h3&gt;
&lt;p&gt;有人说&quot;只要我没有可以花钱的对象，贫穷就不会找上我&quot;(笑&lt;/p&gt;
&lt;p&gt;这其中透露的&quot;奥卡姆剃刀原理&quot;，也叫&quot;简单性原则&quot;十分清晰。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;如无必要，勿增实体&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;尽可能减少信任的对象，由信任对象进行管理是一个不错的措施。比如你信任微信，那么就尽可能减少其他即时聊天软件的使用。比如你信任Apple keychain，那么就不要信任其他密码管理软件。这样可以有效减少泄密源，以免出现全局崩盘的局面。&lt;/p&gt;
&lt;h2&gt;技术层面阻断&lt;/h2&gt;
&lt;h3&gt;拒绝追踪器&lt;/h3&gt;
&lt;p&gt;各大浏览器都有自己的&quot;拒绝追踪器&quot;的方法，一般在设置里有。如果没有，可以安装Duckducgo的隐私拓展，阻断追踪器。&lt;/p&gt;
&lt;p&gt;Apple设备中，未成年人自动禁止所有追踪及启用强隐私保护服务且不可更改。你也可以在设置里自行启用。&lt;/p&gt;
&lt;h3&gt;定期清除cookie&lt;/h3&gt;
&lt;p&gt;可以简单将其理解为清除浏览数据。Cookie数据是网站保存在电脑本地的数据，一般用于判断登陆情况。如果不定期清除，遇到了XSS跨域脚本攻击，那么你的登录密钥有可能被窃取。不过这个登录Cookie通常是会自动销毁的，B站是30天。&lt;/p&gt;
&lt;h3&gt;文件加密&lt;/h3&gt;
&lt;p&gt;对文件进行加密是不错的保护选项。&lt;/p&gt;
&lt;p&gt;Veracrypt和Cryptomator都是开源文件加密软件的极佳选项。两者各有优劣。Cryptomator是分布式网盘同步加密软件，Veracrypt更多适用于本地。更多信息可自行搜索使用&lt;/p&gt;
&lt;h3&gt;高级措施&lt;/h3&gt;
&lt;h4&gt;使用VPN服务或代理&lt;/h4&gt;
&lt;p&gt;emm，VPN这个在国内不是很好使，因为流量特征过于明显，容易被GFW不分青红皂白地阻断。&lt;/p&gt;
&lt;h4&gt;使用DoH&lt;/h4&gt;
&lt;p&gt;DoH全名是&quot;DNS over HTTPS&quot;，意味着你的DNS查询收到https协议保护。&lt;/p&gt;
&lt;p&gt;普通的DNS查询并未受到保护，那么就有可能出现DNS劫持的情况，他人也可以通过DNS服务器知道你访问了什么网站，使用了什么服务。只要不被代理转发，那么ISP可以很轻松地get到所有公开信息。&lt;/p&gt;
&lt;p&gt;国内较好的DoH有阿里DoH、腾讯DoH、DNSpod。当然因为国内特殊网络环境，它们均从源头上收到污染。如果想要不受污染的，那么推荐IQDNS。&lt;/p&gt;
&lt;p&gt;Apple设备可以通过安装描述文件来快速更改DNS。地址：&lt;a href=&quot;https://ios.passcloud.xyz&quot;&gt;IQDNS&lt;/a&gt;，&lt;a href=&quot;https://github.com/paulmillr/encrypted-dns/tree/master/signed&quot;&gt;Github DoH Config项目&lt;/a&gt;（可自行下载安装）&lt;/p&gt;
&lt;h4&gt;WARP等动态ip及动态线路&lt;/h4&gt;
&lt;p&gt;使用全球良心CDN——Cloudflare提供的WARP服务来动态更换IP及获得全球网络服务访问与全隐私保护。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.morax-xyc.com/post/839e7851/&quot;&gt;本站有相关教程&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Tor暗网浏览器&lt;/h4&gt;
&lt;p&gt;下载安装Tor浏览器进行浏览。Tor可以访问暗网，所以在所有浏览器中，它的安全系数最高。&lt;/p&gt;
&lt;h4&gt;Gpg端对端加密认证&lt;/h4&gt;
&lt;p&gt;GPG端对端加密需要一个根证书以搭建你自己的信任网络。GPG可以和Git联合起来进行加密Commit提交，能够实现文件签名、信任、加密操作。&lt;/p&gt;
&lt;p&gt;不过相对而言，门槛较高，建议同学们以后在考虑这种加密方式。&lt;/p&gt;
&lt;p&gt;（不过它的安全系数是最高的）&lt;/p&gt;
&lt;h1&gt;小结&lt;/h1&gt;
&lt;p&gt;现今社会，隐私可谓是公民最重要的东西之一。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;一个人对我们了解得越多，就越能控制我们&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果个人数据落到坏人手中，则可能会给我们带来巨大的伤害，财产、人身或精神各方面。&lt;/p&gt;
&lt;p&gt;个人数据可能会被用来影响我们的决定，塑造我们的行为，甚至作为一种工具来控制我们。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;对于他人隐私的不尊重，在某种意义上，意思是:&quot;我关心我的利益，但我不关心你的。&quot;&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;自由的标志之一是拥有自主和对我们生活的控制，而如果这么多关于我们的重要决定是在我们没有意识或参与的情况下秘密做出的，我们就无法拥有&lt;strong&gt;生而为人&lt;/strong&gt;的自主权。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;保护隐私&lt;/strong&gt;不仅意味着保护人格的健全与自主权，更意味着一种尊严、一种精神。&lt;/p&gt;
&lt;p&gt;希望同学们能重视对隐私的保护，保护自己的信息，保护自己的人格！&lt;/p&gt;
</content:encoded></item><item><title>使用Vercel反代Leancloud国际版api以避免屏蔽</title><link>https://blog.moraxyc.com/posts/vercel-proxy-leancloud-api/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/vercel-proxy-leancloud-api/</guid><pubDate>Thu, 12 May 2022 16:39:28 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;
:::tip[叛变]
已经叛变到twikoo的统计后端了，Leancloud这种号称对开发者友好的平台已经变味了
:::&lt;/p&gt;
&lt;h2&gt;情况描述&lt;/h2&gt;
&lt;p&gt;我用的Hexo主题为Fluid，它内置了用leancloud实现的UV统计功能。作为一位完全不想备案，想方设法逃避的博主，我当然不会选择leancloud国内版，国际版才是最优选！&lt;/p&gt;
&lt;p&gt;然而，由于手机和电脑分流规则皆是“漏网之鱼”指向了代理，我也没有专门为我的网站设立规则，我一直没发现一个问题：通过大陆ip访问博客时，leancloud的api会拒绝连接！&lt;a href=&quot;%E5%AE%98%E6%96%B9%E6%B2%A1%E6%9C%89%E4%BB%BB%E4%BD%95%E5%85%B3%E4%BA%8E%E6%AD%A4%E7%8E%B0%E8%B1%A1%E7%9A%84%E4%BF%A1%E6%81%AF%EF%BC%8C%E6%97%A0%E6%B3%95%E5%88%A4%E6%96%AD%E6%98%AF%E5%90%A6%E6%89%80%E6%9C%89%E5%9B%BD%E9%99%85%E7%89%88api%E9%83%BD%E6%9C%89%E6%AD%A4%E9%97%AE%E9%A2%98%E3%80%82&quot;&gt;^1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我分配到的leancloud api地址是&lt;a href=&quot;https://ewtbugjp.api.lncldglobal.com&quot;&gt;ewtbugjp.api.lncldglobal.com&lt;/a&gt;，大陆直连时服务器会拒绝连接，其他地方访问才会出现404的返回。&lt;/p&gt;
&lt;p&gt;不知道这是什么情况，我Google了好一会儿也没找到原因，没有任何人报告出现此问题。唉，无论是否是特例，我都得修好这个bug！&lt;/p&gt;
&lt;p&gt;:::caution[责任自负]
此方法涉及到源代码修改，如果你用的是Serverless托管部署方案[^2]，主题安装方式必须为releases包安装，而非npm install方式安装。
使用过程中请遵守Vercel TOS，违反TOS的一切后果由用户承担
:::&lt;/p&gt;
&lt;h2&gt;解决方法&lt;/h2&gt;
&lt;h3&gt;思路&lt;/h3&gt;
&lt;p&gt;既然直连不行，还有种方法叫“反代&lt;a href=&quot;%E5%8D%B3%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%EF%BC%8C%E4%B8%8E%E4%B8%80%E8%88%AC%E6%84%8F%E4%B9%89%E4%B8%8A%E4%BB%A3%E7%90%86%E4%B8%8D%E5%90%8C%EF%BC%8C%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86%E8%B4%9F%E8%B4%A3%E4%BB%A3%E7%90%86%E9%9C%80%E8%A6%81%E8%AF%B7%E6%B1%82%E7%9A%84%E8%B5%84%E6%BA%90%E5%86%8D%E8%BF%94%E5%9B%9E%E7%BB%99%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8C%E4%BA%8E%E6%98%AF%E8%A2%AB%E8%AF%B7%E6%B1%82%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%8F%AA%E8%83%BD%E5%BE%97%E5%88%B0%E5%8F%8D%E4%BB%A3%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84IP%E5%8F%8A%E5%8F%8D%E4%BB%A3%E5%86%85%E5%AE%B9%E3%80%82&quot;&gt;^3&lt;/a&gt;”。通过一个不在大陆的服务器去反代这个api，是否就能躲开leancloud国际版对于大陆ip的屏蔽？&lt;/p&gt;
&lt;p&gt;可是我的整套个人网站都是Serverless的，不存在后端去代理啊？🤔&lt;/p&gt;
&lt;p&gt;事实上，serverless服务也可以作为反代服务器！有很多种办法达成目的。考虑到我现在主博客采用的Vercel部署，且延迟优秀、速度快，自然就想到了用Vercel来反代。&lt;/p&gt;
&lt;p&gt;当然，Cloudflarr Worker也可以达到类似效果。教程可以在Google上面搜一下，估计一大堆。&lt;/p&gt;
&lt;h3&gt;一. Vercel反代&lt;/h3&gt;
&lt;p&gt;首先，你得有一个Vercel的帐号。
&lt;s&gt;这不是废话嘛&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;其次，你得有一个终端环境。推荐bash或zsh。&lt;/p&gt;
&lt;h4&gt;1. 安装Vercel CLI&lt;/h4&gt;
&lt;p&gt;通过Debian系的&lt;code&gt;sudo apt install npm&lt;/code&gt;或CentOS系的&lt;code&gt;sudo yum install npm&lt;/code&gt;安装npm包管理器。&lt;/p&gt;
&lt;p&gt;安装完成后，使用&lt;code&gt;npm i -g vercel&lt;/code&gt;以安装Vercel CLI。&lt;/p&gt;
&lt;h4&gt;2. 登陆Vercel CLI&lt;/h4&gt;
&lt;p&gt;&lt;code&gt;vercel login&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;这个过程中有很多种登录方式，这里就不细说了，看着英文指导来就可以。&lt;/p&gt;
&lt;h4&gt;3. 创建反代文件&lt;/h4&gt;
&lt;p&gt;新建一个文件夹当作部署的根目录，在文件夹下随便创建一个json文件。我的是&lt;code&gt;ewtbugjp.api.lncldglobal.com.json&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在json文件内写入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;version&quot;: 2,
  &quot;routes&quot;: [
      {&quot;src&quot;: &quot;/(.*)&quot;,&quot;dest&quot;: &quot;https://ewtbugjp.api.lncldglobal.com/$1&quot;}
  ]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面的&lt;code&gt;https://ewtbugjp.api.lncldglobal.com&lt;/code&gt;是我的api地址。可以在leancloud项目后台找到替换上去，或者通过appid获取：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;https://app-router.leancloud.cn/2/route?appId=&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;将appid添加到上述地址后面访问，即可看到json格式的返回，其中最后一个&lt;code&gt;api_server&lt;/code&gt;的值即为你的api服务器域名。&lt;/p&gt;
&lt;h4&gt;4. 部署&lt;/h4&gt;
&lt;p&gt;准备好反代文件后，就可以部署了。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;vercel -A ewtbugjp.api.lncldglobal.com.json --prod&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;上面命令中的json文件名记得改为你记得的。&lt;/p&gt;
&lt;h4&gt;5. 获取部署域名&lt;/h4&gt;
&lt;p&gt;访问&lt;a href=&quot;https://vercel.com&quot;&gt;vercel&lt;/a&gt;，找到你刚刚部署的项目后，可以选择在设置中通过A记录或CNAME添加域名，也可以直接用vercel提供的域名。&lt;/p&gt;
&lt;p&gt;记录下这个域名，我们开始替换&lt;code&gt;leancloud.js&lt;/code&gt;内的地址。&lt;/p&gt;
&lt;h3&gt;二. 替换leancloud地址&lt;/h3&gt;
&lt;p&gt;以Fluid主题内的&lt;code&gt;leancloud.js&lt;/code&gt;为例。&lt;/p&gt;
&lt;h4&gt;1. 找到leancloud.js&lt;/h4&gt;
&lt;p&gt;使用npm包安装、在vps或云服务器上运行的Hexo中，leancloud.js文件是&lt;code&gt;node_modules/hexo-theme-fluid/source/js/leancloud.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;使用releases安装在themes文件夹，则leancloud.js是&lt;code&gt;themes/fluid/source/js/leancloud.js&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;2. 修改server_url&lt;/h4&gt;
&lt;p&gt;脚本内大约180多行处，有一处代码如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; var apiServer = serverUrl || `https://${appId.slice(0, 8).toLowerCase()}.api.lncldglobal.com`;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;将其改为：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  var apiServer = serverUrl || `https://leancloud.proxy.com`;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当然，此处的&lt;code&gt;https://leancloud.proxy.com&lt;/code&gt;应该修改为你自己的反代网址。&lt;/p&gt;
&lt;p&gt;推送部署后，你的api应该就能全球访问了。此行为不会影响“浏览人数”的数据。&lt;/p&gt;
&lt;p&gt;[^2]: 即Cloudflare Pages、Github Actions &amp;amp; Pages、Vercel、Heroku等&lt;/p&gt;
</content:encoded></item><item><title>Cloudflare R2 快速开始使用指南教程 | 中文翻译</title><link>https://blog.moraxyc.com/posts/cloudflare-r2/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/cloudflare-r2/</guid><description>感谢支持</description><pubDate>Wed, 11 May 2022 15:34:14 GMT</pubDate><content:encoded>&lt;p&gt;:::tip[提示]
&lt;a href=&quot;https://developers.cloudflare.com/r2/get-started/&quot;&gt;&lt;strong&gt;原文地址&lt;/strong&gt;&lt;/a&gt;
本文内容已尽可能与原格式相同，如有遗漏，请多海涵。
本文于&lt;a href=&quot;https://github.com/cloudflare/cloudflare-docs/blob/37f49d99e0c5f701f26324c173f9079a32430ff9/content/r2/get-started.md&quot;&gt;&lt;strong&gt;此Commit&lt;/strong&gt;&lt;/a&gt;下翻译
:::&lt;/p&gt;
&lt;h2&gt;R2入门指南&lt;/h2&gt;
&lt;p&gt;Cloudflare R2存储允许开发人员存储大量非结构化数据，而无需支付与典型云存储服务相关的昂贵出口带宽费用。&lt;/p&gt;
&lt;p&gt;本指南将指导您设置Wrangler部署第一个R2存储桶。&lt;/p&gt;
&lt;h3&gt;购买R2&lt;/h3&gt;
&lt;p&gt;在创建第一个存储桶之前，您必须在Cloudflare仪表板中购买R2。&lt;/p&gt;
&lt;p&gt;购买R2：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;登录&lt;a href=&quot;https://dash.cloudflare.com/login&quot;&gt;Cloudflare仪表板&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;在&lt;strong&gt;帐户主页中&lt;/strong&gt;，选择&lt;strong&gt;R2&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;选择&lt;strong&gt;购买R2计划&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;选择&lt;strong&gt;继续查看付款详情&lt;/strong&gt;以查看您的付款。&lt;/li&gt;
&lt;li&gt;选择&lt;strong&gt;返回 R2&lt;/strong&gt;以前往 R2 面板。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;1. 安装Wrangler&lt;/h3&gt;
&lt;p&gt;要创建您的R2存储桶，请安装Wrangler，即Workers CLI。&lt;/p&gt;
&lt;p&gt;安装&lt;a href=&quot;https://github.com/cloudflare/wrangler&quot;&gt;&lt;code&gt;wrangler&lt;/code&gt;&lt;/a&gt;，确保您已安装&lt;a href=&quot;https://www.npmjs.com/get-npm&quot;&gt;&lt;code&gt;npm&lt;/code&gt;&lt;/a&gt;。使用像&lt;a href=&quot;https://volta.sh/&quot;&gt;Volta&lt;/a&gt;这样的Node版本管理器或&lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;nvm&lt;/a&gt;以避免权限问题或轻松更改Node.js版本，然后运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install -D wrangler
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或用Yarn安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn add wrangler
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有关更多信息，请参阅Wrangler&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/get-started/&quot;&gt;安装/更新&lt;/a&gt;页面（英文页面&lt;a href=&quot;%E8%AF%91%E8%80%85%E6%B3%A8%EF%BC%9A%22%EF%BC%88%E8%8B%B1%E6%96%87%E9%A1%B5%E9%9D%A2%EF%BC%89%E2%80%9D%E8%A1%A8%E7%A4%BA%E4%BD%8D%E4%BA%8E%E6%8B%AC%E5%8F%B7%E5%89%8D%E6%96%B9%E7%9A%84%E8%B6%85%E9%93%BE%E6%8E%A5%E8%B7%B3%E8%BD%AC%E5%9C%B0%E5%9D%80%E5%B9%B6%E6%9C%AA%E8%A2%AB%E6%B1%89%E5%8C%96%EF%BC%8C%E5%B1%9E%E4%BA%8ECloudflare%E7%9A%84%E5%8E%9F%E8%8B%B1%E6%96%87%E5%86%85%E5%AE%B9&quot;&gt;^1&lt;/a&gt;）。&lt;/p&gt;
&lt;h3&gt;2. 认证Wrangler&lt;/h3&gt;
&lt;p&gt;安装完成后，&lt;code&gt;wrangler&lt;/code&gt;将需要访问Cloudflare OAuth令牌来代表您管理Worker资源。&lt;/p&gt;
&lt;p&gt;运行&lt;code&gt;wrangler login&lt;/code&gt;以自动化处理令牌。&lt;/p&gt;
&lt;p&gt;Wrangler将尝试自动打开您的网页浏览器，以完成Cloudflare帐户的登录过程。如果您在完成此步骤时遇到问题，或者您无法访问浏览器GUI，您可以将&lt;code&gt;wrangler login&lt;/code&gt;终端生成的URL复制并粘贴到浏览器中并登录。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler login
Allow Wrangler to open a page in your browser? [y/n]
y
💁  Opened a link in your default browser: https://dash.cloudflare.com/oauth2/...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开浏览器，登录您的帐户，然后选择&lt;strong&gt;Allow&lt;/strong&gt;。这将向Wrangler发送OAuth令牌，以便它可以将您的脚本部署到Cloudflare。&lt;/p&gt;
&lt;p&gt;:::note[版本要求]
R2需要Wrangler&lt;code&gt;1.19.8&lt;/code&gt;或更高版本。要检查您的Wrangler版本，请运行&lt;code&gt;wrangler --version&lt;/code&gt;。
:::&lt;/p&gt;
&lt;h3&gt;&amp;lt;span id=&quot;step3&quot;&amp;gt;3. 创建您的存储桶&amp;lt;/span&amp;gt;&lt;/h3&gt;
&lt;p&gt;通过运行以下操作创建存储桶：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler r2 bucket create &amp;lt;YOUR_BUCKET_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要检查您的存储桶是否已创建，请运行：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler r2 bucket list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行&lt;code&gt;list&lt;/code&gt;命令后，您将看到所有存储桶名称，包括您刚刚创建的存储桶名称。&lt;/p&gt;
&lt;h3&gt;4. 将您的R2存储桶绑定在Worker上&lt;/h3&gt;
&lt;p&gt;你需要存储桶绑定在worker上使用。&lt;/p&gt;
&lt;p&gt;:::note[绑定（Bindings）]
binding&lt;a href=&quot;%E8%AF%91%E8%80%85%E6%B3%A8%EF%BC%9A%E8%BF%99%E4%B8%AA%E6%8F%90%E7%A4%BA%E6%A1%86%E7%9A%84%E5%8E%9F%E6%96%87%E4%B8%BA%EF%BC%9A&quot;&gt;^2&lt;/a&gt;是您的worker与KV命名空间、耐用对象或R2存储桶等外部资源交互的方式。binding是Workers运行时向您的代码提供的运行时变量。您可以在&lt;code&gt;wrangler.toml&lt;/code&gt;文件中声明一个变量名，该变量名将在运行时绑定到这些资源，并通过此变量与它们交互。每个binding的变量名称和行为都由您在部署Worker时决定。请参阅&lt;a href=&quot;https://github.com/workers/platform/environment-variables&quot;&gt;环境变量&lt;/a&gt;（英文页面）的文档以了解更多信息。&lt;/p&gt;
&lt;p&gt;Binding在Worker项目目录的&lt;code&gt;wrangler.toml&lt;/code&gt;文件中定义。
:::&lt;/p&gt;
&lt;p&gt;使用官方提供的模板创建Worker。Wrangler模板是git存储库，旨在作为构建新的Cloudflare Workers项目的起点。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler init &amp;lt;YOUR_WORKER_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;接下来，在项目目录中找到新生成的&lt;code&gt;wrangler.toml&lt;/code&gt;文件，并使用Cloudflare帐户ID更新&lt;code&gt;account_id&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;通过登录Cloudflare仪表板&amp;gt;&lt;strong&gt;概述&lt;/strong&gt;&amp;gt;向下移动到&lt;strong&gt;API&lt;/strong&gt;&amp;gt;找到您的帐户ID，然后选择&lt;strong&gt;单击复制&lt;/strong&gt;以复制&lt;strong&gt;您的帐户ID&lt;/strong&gt;。或者运行&lt;code&gt;wrangler whoami&lt;/code&gt;命令来复制您的帐户ID。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;name = ”&amp;lt;YOUR_WORKER_NAME&amp;gt;&quot;
type = ”javascript&quot;
compatibility_date = ”2022-04-18&quot;

account_id = ”YOUR_ACCOUNT_ID&quot; # ← Replace with your Account ID.
workers_dev = true
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果您需要使用较旧的兼容日期，则需要启用&lt;code&gt;r2_public_beta_bindings&lt;/code&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/platform/compatibility-dates/&quot;&gt;标志&lt;/a&gt;（英文页面）。&lt;/p&gt;
&lt;p&gt;为此，请更新您的&lt;code&gt;wrangler.toml&lt;/code&gt;文件以包含以下内容：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# An example date older than ”2022-04-18&quot;
compatibility_date = ”2022-02-10&quot;
compatibility_flags = [”r2_public_beta_bindings&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要将R2存储桶绑定到您的Worker，请将以下内容添加到您的&lt;code&gt;wrangler.toml&lt;/code&gt;文件中。将&lt;code&gt;binding&lt;/code&gt;属性更新为有效的JavaScript变量标识符，并将&lt;code&gt;bucket_name&lt;/code&gt;为您在&lt;a href=&quot;#step3&quot;&gt;步骤3&lt;/a&gt;中用于创建存储桶的&lt;code&gt;&amp;lt;YOUR_BUCKET_NAME&amp;gt;&lt;/code&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[[r2_buckets]]
binding = &apos;MY_BUCKET&apos; # &amp;lt;~ valid JavaScript variable name
bucket_name = &apos;&amp;lt;YOUR_BUCKET_NAME&amp;gt;&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/cli-wrangler/configuration/&quot;&gt;Wrangler配置文档&lt;/a&gt; （英文页面）中找到有关如何配置Worker的更多详细信息。&lt;/p&gt;
&lt;h3&gt;5. 通过worker访问您的R2存储桶&lt;/h3&gt;
&lt;p&gt;在您的Worker代码中，您的存储桶现在可以在&lt;code&gt;MY_BUCKET&lt;/code&gt;变量下使用，您可以开始与它交互。&lt;/p&gt;
&lt;p&gt;R2存储桶能够读取、列表、写入和删除对象。您可以使用Service Worker语法在下面看到所有操作的示例。将以下片段添加到项目的&lt;code&gt;index.js&lt;/code&gt;文件中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;addEventListener(&quot;fetch”, (event) =&amp;gt; {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const url = new URL(request.url);
  const key = url.pathname.slice(1);

  switch (request.method) {
    case &quot;PUT”:
      await MY_BUCKET.put(key, request.body);
      return new Response(`Put ${key} successfully!`);
    case &quot;GET”:
      const object = await MY_BUCKET.get(key);

      if (!object) {
        return new Response(&quot;Object Not Found”, { status: 404 });
      }

      return new Response(object.body);
    case &quot;DELETE”:
      await MY_BUCKET.delete(key);
      return new Response(&quot;Deleted!”, { status: 200 });

    default:
      return new Response(&quot;Route Not Found.”, { status: 404 });
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;6. 存储桶访问和隐私&lt;/h3&gt;
&lt;p&gt;将上述代码添加到您的Worker中后，每个传入的请求都能够与您的存储桶进行交互。这意味着您的存储桶被公开暴露，其内容可以被公开且无需任何许可地访问和修改。&lt;/p&gt;
&lt;p&gt;您现在必须定义授权逻辑，以确定谁可以对您的存储桶执行哪些操作。这种逻辑存在于您的Worker代码中，因为确定用户权限是应用程序的工作。以下是与访问和授权实践相关的资源的简单列表：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/examples/basic-auth/&quot;&gt;基本身份验证&lt;/a&gt;：展示如何使用HTTP基本模式限制访问。（英文页面）&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/examples/auth-with-headers/&quot;&gt;使用自定义标头&lt;/a&gt;：允许或拒绝基于标题中已知的预共享密钥的请求。（英文页面）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;继续使用新创建的桶和Worker，您需要保护所有对于存储桶的操作。&lt;/p&gt;
&lt;p&gt;对于&lt;code&gt;PUT&lt;/code&gt;和&lt;code&gt;DELETE&lt;/code&gt;请求，您将使用一个新的&lt;code&gt;AUTH_KEY_SECRET&lt;/code&gt;环境变量，稍后您将该变量定义为Wrangler secret。&lt;/p&gt;
&lt;p&gt;对于&lt;code&gt;GET&lt;/code&gt;请求，您将确保只能请求特定文件。所有这些自定义逻辑都发生在&lt;code&gt;authorizeRequest&lt;/code&gt;函数中，&lt;code&gt;hasValidHeader&lt;/code&gt;函数处理自定义标头逻辑。如果所有验证都通过了，则允许该操作。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const ALLOW_LIST = [&apos;cat-pic.webp&apos;];
// Check requests for a pre-shared secret
const hasValidHeader = request =&amp;gt; {
  return request.headers.get(&apos;X-Custom-Auth-Key&apos;) === AUTH_KEY_SECRET;
};

function authorizeRequest(request, key) {
  switch (request.method) {
    case &apos;PUT&apos;:
    case &apos;DELETE&apos;:
      return hasValidHeader(request);
    case &apos;GET&apos;:
      return ALLOW_LIST.includes(key);
    default:
      return false;
  }
}

async function handleRequest(request) {
  const url = new URL(request.url);
  const key = url.pathname.slice(1);

  if (!authorizeRequest(request, key)) {
    return new Response(&apos;Forbidden&apos;, { status: 403 });
  }
  // ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;要做到这一点，您需要通过Wrangler创建一个Secret：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler secret put AUTH_KEY_SECRET
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此命令将提示您在终端中输入Secret：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler secret put AUTH_KEY_SECRET
Enter the secret text you&apos;d like assigned to the variable AUTH_KEY_SECRET on the script named &amp;lt;YOUR_WORKER_NAME&amp;gt;:
*********
🌀  Creating the secret for script name &amp;lt;YOUR_WORKER_NAME&amp;gt;
✨  Success! Uploaded secret AUTH_KEY_SECRET.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;此Secret现在作为Worker中的全局变量&lt;code&gt;AUTH_KEY_SECRET&lt;/code&gt;可用。&lt;/p&gt;
&lt;h3&gt;7. 部署你的存储桶&lt;/h3&gt;
&lt;p&gt;一切准备就绪，设置完Worker和存储桶Bucket后，运行&lt;code&gt;wrangler publish&lt;/code&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/wrangler/cli-wrangler/commands/#publish&quot;&gt;命令&lt;/a&gt;（英文页面）以部署到Cloudflare的全球网络：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wrangler publish
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;您可以使用已经部署的Worker 路由验证您的授权逻辑是否通过以下命令工作：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Attempt to write an object without providing the &quot;X-Custom-Auth-Key&quot; header
curl https://your-worker.dev/cat-pic.webp -X PUT —header —data &apos;test&apos;
#=&amp;gt; Forbidden
# Expected because header was missing

# Attempt to write an object with the wrong ”X-Custom-Auth-Key&quot; header value
curl https://your-worker.dev/cat-pic.webp -X PUT —header ”X-Custom-Auth-Key: hotdog&quot; —data &apos;test&apos;
#=&amp;gt; Forbidden
# Expected because header value did not match the AUTH_KEY_SECRET value

# Attempt to write an object with the correct ”X-Custom-Auth-Key&quot; header value
# Note: Assume that ”*********&quot; is the value of your AUTH_KEY_SECRET Wrangler secret
curl https://your-worker.dev/cat-pic.webp -X PUT —header ”X-Custom-Auth-Key: *********&quot; —data &apos;test&apos;
#=&amp;gt; Put cat-pic1.webp successfully!

# Attempt to read object called ”foo&quot;
curl https://your-worker.dev/foo
#=&amp;gt; Forbidden
# Expected because ”foo&quot; is not in the ALLOW_LIST

# Attempt to read an object called ”cat-pic.webp&quot;
curl https://your-worker.dev/cat-pic.webp
#=&amp;gt; test
# Note: This is the value that was successfully PUT above
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过完成本指南，您已成功安装Wrangler，并将R2存储桶部署到Cloudflare。&lt;/p&gt;
&lt;h3&gt;相关资源（英文页面）&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/tutorials/&quot;&gt;Worker教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.cloudflare.com/workers/examples/&quot;&gt;Worker示例&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&quot;A binding is a how your Worker interacts with external resources such as KV Namespaces , Durable Objects , or R2 Buckets . A binding is a runtime variable that the Workers runtime provides to your code. You can declare a variable name in your wrangler.toml file that will be bound to these resources at runtime, and interact with them through this variable. Every binding&apos;s variable name and behavior is determined by you when deploying the Worker. Refer to the Environment VariablesOpen external link documentation for more information.
A binding is defined in the wrangler.toml file of your Worker project&apos;s directory.” 水平有限，若翻译有误，欢迎批评指正&lt;/p&gt;
</content:encoded></item><item><title>iOS和iPad设备上Git卡在Resolving delta的解决办法</title><link>https://blog.moraxyc.com/posts/git-ish-error/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/git-ish-error/</guid><pubDate>Sat, 23 Apr 2022 00:41:50 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;h2&gt;问题描述&lt;/h2&gt;
&lt;p&gt;因为程序并发与iOS内存管理之间的冲突，Git使用多线程处理将会卡在&lt;code&gt;Resolving deltas&lt;/code&gt;部分。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/git-ish-error/1.jpeg&quot; alt=&quot;Resolving Delta&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;解决方法&lt;/h2&gt;
&lt;p&gt;解决方法很简单，让ish上的Git运行于单线程即可解决问题。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config pack.threads &quot;1&quot;&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果想全局使用单线程Git，可以加上global参数。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git config --global pack.threads &quot;1&quot;&lt;/code&gt;&lt;/p&gt;
</content:encoded></item><item><title>Gpg 提交中的一个坑</title><link>https://blog.moraxyc.com/posts/gpg-error/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/gpg-error/</guid><pubDate>Tue, 01 Mar 2022 16:23:51 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;h2&gt;经过描述&lt;/h2&gt;
&lt;p&gt;当github配置好gpg加密后，提交commit就需要输入密码了。不过提交后，总会弹出一个提示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ERROR:数据签名失败 
Fatal:写提交对象失败 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就很诡异。&lt;/p&gt;
&lt;h2&gt;解决方案&lt;/h2&gt;
&lt;p&gt;Google一番后，找到了解决方法：&lt;/p&gt;
&lt;h3&gt;定义变量&lt;/h3&gt;
&lt;p&gt;定义GPG_TTY变量为$(tty)。&lt;/p&gt;
&lt;h3&gt;具体命令&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;
cat &amp;gt; /etc/profile.d/gpg.sh &amp;lt;&amp;lt; EOF 
export GPG_TTY=$(tty) 
EOF 

&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;效果&lt;/h2&gt;
&lt;p&gt;这样，每当你登录时，这个变量都会自动加载，不会再出现这种error的情况。&lt;/p&gt;
</content:encoded></item><item><title>让Telegram提醒你诸多事务</title><link>https://blog.moraxyc.com/posts/tg-notice/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/tg-notice/</guid><pubDate>Tue, 01 Mar 2022 09:27:37 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;:::caution[弃坑]
感觉重复造轮子了，&lt;s&gt;Gayhub&lt;/s&gt;上好多类似项目
:::&lt;/p&gt;
&lt;p&gt;也许是因为记忆力实在是不太好，而且我的设备很杂，统一推送提醒不太好弄，于是我有了一个写一个通知脚本的打算。&lt;/p&gt;
&lt;p&gt;单方面的通知很简单就可以实现，也不需要回调，凭借api轻松实现。&lt;/p&gt;
&lt;p&gt;后来我发现了个&quot;Pushdeer&quot;项目，简直惊为天人，有空探索下玩法。&lt;/p&gt;
&lt;h2&gt;思路&lt;/h2&gt;
&lt;h3&gt;客户端&lt;/h3&gt;
&lt;p&gt;Telegram作为我个人认为最优秀的即使信息软件且兼容性极高，所以选择它作为这个项目的承载客户端。&lt;/p&gt;
&lt;h3&gt;功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;[x] SSH Login Notice&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] Manage  一键管理脚本，图形化配置，无需手动操作，体验一键梭哈的感觉&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 定时自定义内容提醒&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 网站守护 - 定时检测网站可访问性，若失联则立刻提醒&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;[x] 进程守护 - 定时检测服务器进程运行状态，若发生error立刻提醒&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;发展&lt;/h3&gt;
&lt;p&gt;有一个关于这个的想法：&lt;/p&gt;
&lt;p&gt;因为所有功能都和服务器有关，不如直接做一个telegram bot用来管理所有vps，毕竟现在的telegram功能又多又好，简直全能。当然，由于从来没学过telegram bot的完整开发，可能得学习好一阵了。&lt;/p&gt;
&lt;h2&gt;安装&amp;amp;使用&lt;/h2&gt;
&lt;p&gt;详见&lt;a href=&quot;https://github.com/morax-xyc/telegram-notice&quot;&gt;Github Telegram Notice项目&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>让Github乖乖接受+86 SMS 2FA短信验证</title><link>https://blog.moraxyc.com/posts/github-86/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/github-86/</guid><pubDate>Sat, 26 Feb 2022 14:23:48 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;作为世界上最大的开源托管&lt;s&gt;同性交友&lt;/s&gt;网站，GitHub居然在双因素验证的地方没有+86的位置，令人震怒。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/github-86/1.jpeg&quot; alt=&quot;GitHub没有+86的位置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;但魔高一尺道高一丈，GitHub既然不主动给我们+86，那我们就强迫它接受！&lt;/p&gt;
&lt;h2&gt;第一步 打开&quot;开发人员工具&quot;&lt;/h2&gt;
&lt;p&gt;打开开发人员工具后找到&quot;Country Code&quot;部分，如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/github-86/2.jpeg&quot; alt=&quot;开发人员工具&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第二步 修改为+86&lt;/h2&gt;
&lt;p&gt;将&lt;code&gt;value&lt;/code&gt;部分中的&lt;code&gt;+1&lt;/code&gt;改为&lt;code&gt;+86&lt;/code&gt;，如果乐意还可以顺便把&lt;code&gt;United States +1&lt;/code&gt;改成&lt;code&gt;China Mainland +86&lt;/code&gt;也可以。&lt;s&gt;震惊！老美被中国吞并！&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/github-86/3.jpeg&quot; alt=&quot;强制让GitHub显示出+86&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;第三步 输入手机号并验证&lt;/h2&gt;
&lt;p&gt;接下来的步骤相信小学二年级的同学都会了，就不再赘述。上图！
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/github-86/4.jpeg&quot; alt=&quot;验证中&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/github-86/5.jpeg&quot; alt=&quot;验证成功&quot; /&gt;&lt;/p&gt;
&lt;p&gt;是不是很简单？&lt;/p&gt;
</content:encoded></item><item><title>Cloudflare WARP | 已屏蔽中国大陆访问</title><link>https://blog.moraxyc.com/posts/cloudflare-warp/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/cloudflare-warp/</guid><pubDate>Fri, 04 Feb 2022 03:44:50 GMT</pubDate><content:encoded>&lt;p&gt;玩vps的朋友应该听过Cloudflare WARP&lt;a href=&quot;%5B1.1.1.1%5D(https://1.1.1.1)&quot;&gt;^1&lt;/a&gt;，他有个作用就是解锁流媒体，因为它可以提供原生IP供vps使用，原理见下方注释[^2]。而今天，我们就来讲讲在iOS设备上WARP +给科学上网带来的体验。
&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;:::warning[警告]
Cloudflare作为目前看来最良心的cdn网络服务商，建议大家少薅羊毛，jsdelivr前车之鉴啊！&lt;/p&gt;
&lt;p&gt;第二节的team/zero-trust方案是官方认可的，并不算漏洞，但还是谨慎使用，说不准什么时候cf就关掉了…&lt;/p&gt;
&lt;p&gt;非常不建议大家用脚本刷！
:::&lt;/p&gt;
&lt;p&gt;:::note[更新日志]
2022.8.7，Cloudflare宣布升级warp：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;全面隐藏用户IP，这使得warp效果将接近于iCloud Private Relay&lt;/li&gt;
&lt;li&gt;扩容warp网络至100多个国家的270多个城市&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.cloudflare.com/geoexit-improving-warp-user-experience-larger-network/&quot;&gt;Source&lt;/a&gt;
:::&lt;/p&gt;
&lt;p&gt;:::tip[🍟的Surge转换脚本]
薯条🍟写了个脚本，能够将warp(包括team版)转换为Surge可用的格式&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/VirgilClyne/Cloudflare/wiki/%E2%98%81-1.1.1.1-by-Cloudflare-with-WARP&quot;&gt;脚本地址&lt;/a&gt;
:::&lt;/p&gt;
&lt;h2&gt;1.前提&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[ ] 外区Apple ID&lt;/li&gt;
&lt;li&gt;[ ] 一个可以用的科学上网方案（临时使用）&lt;/li&gt;
&lt;li&gt;[ ] Cloudflare账号&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2.Cloudflare WARP&lt;/h2&gt;
&lt;h3&gt;2.1安装&lt;/h3&gt;
&lt;p&gt;首先要在App Store登录外区Apple ID[^3]，接着访问&lt;a href=&quot;https://itunes.apple.com/us/app/1-1-1-1-faster-internet/id1423538627&quot;&gt;安装链接&lt;/a&gt;进行安装。&lt;/p&gt;
&lt;h3&gt;2.2配置&lt;/h3&gt;
&lt;p&gt;接着，先开着你自己的上网工具，然后打开Cloudflare WARP（也就是1.1.1.1 [^4]）开始配置。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/dx4zk2lr18mbe9e.jpeg&quot; alt=&quot;什么是WARP？&quot; /&gt;
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/1xufv4qun8ebabi.jpeg&quot; alt=&quot;隐私条款&quot; /&gt;&lt;/p&gt;
&lt;p&gt;它会有许多条款，直接同意即可&lt;s&gt;谁&amp;lt;sup&amp;gt;tm&amp;lt;/sup&amp;gt;没事儿看条款啊&lt;/s&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/gf6ei7sw4a1ziyf.jpeg&quot; alt=&quot;连接&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个时候就需要注册设备，也就是为什么要开着科学上网的原因（注册设备阶段需要连接1.1.1.1，但长城应该是把它封掉了)。&lt;/p&gt;
&lt;h3&gt;2.3连接&lt;/h3&gt;
&lt;p&gt;注册完后可以打开连接，再打开Cloudflare的&lt;a href=&quot;https://www.cloudflare.com/zh-cn/ssl/encrypted-sni&quot;&gt;检测工具&lt;/a&gt;看看是不是连上了1.1.1.1的DoH，连上了就可以。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/yuvnsqca2iobjzf.jpeg&quot; alt=&quot;iOS上的1.1.1.1 WARP&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此时，你的WARP连接的是共享带宽，速度慢得一批，当然看看网页还是没啥问题的。如果想要更优质的服务，有两条路。一条是充钱；而另一条，则是白嫖Cloudflare for Teams [^5]。&lt;/p&gt;
&lt;p&gt;(如果有条件还是花钱支持一下吧，毕竟也就将近5$/月，Cloudflare的羊毛都薅的我不好意思了😅。订阅了WARP+后可以在设置中帐户页面复制密钥在电脑上使用以共享订阅)&lt;/p&gt;
&lt;h2&gt;3.Cloudflare Zero Trust&lt;/h2&gt;
&lt;h3&gt;3.1注册组织&lt;/h3&gt;
&lt;p&gt;首先&lt;a href=&quot;https://dash.cloudflare.com&quot;&gt;登录&lt;/a&gt;你的cloudflare账号，进入控制台。打开&lt;a href=&quot;https://dash.teams.cloudflare.com/&quot;&gt;team界面&lt;/a&gt;，输入你想注册的组织名（后续可改），然后选择计划。有支付方式的可以绑定一个后选择free计划，没有的也可以直接不管，重新进入&lt;a href=&quot;https://dash.teams.cloudflare.com/&quot;&gt;Cloudflare Zero Trust&lt;/a&gt;。&lt;/p&gt;
&lt;h3&gt;3.2连接服务&lt;/h3&gt;
&lt;p&gt;在左侧的My Team中选择Device，增加第一个设备&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/elv6uxgxyey34wa.jpeg&quot; alt=&quot;增加Device&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击&quot;Connect a device&quot;后，&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/tfdbhmzfmpynh2x.jpeg&quot; alt=&quot;开始增加设备&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击创建注册策略（Create an enrollment policy）后，输入你想要登录邮箱的后缀，例如&quot;@gmail.com&quot;。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/grmjlm2zng3etu9.jpeg&quot; alt=&quot;填入被允许的邮箱后缀&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接着会要求安装一个描述文件以增加对https连接的支持。（事实上我没搞懂这一步有什么用，因为即使我没安装描述文件并信任也可以正常使用）。&lt;/p&gt;
&lt;h3&gt;3.3连接Teams&lt;/h3&gt;
&lt;p&gt;右上角点开更多&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/ysf7umglzctan2p.jpeg&quot; alt=&quot;设置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;点击账户&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/xilbnqgdysirknw.jpeg&quot; alt=&quot;帐户&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个界面中的&quot;按键&quot;上的密钥可以连接电脑和手机以共享流量或WARP+订阅。当然对我们白嫖党是没用滴😎。点击&quot;使用Cloudflare for Teams登录&quot;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/sxh9dgbqqpopagv.jpeg&quot; alt=&quot;Cloudflare for Teams&quot; /&gt;&lt;/p&gt;
&lt;p&gt;隐私条款&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/irzw1exqundbys4.jpeg&quot; alt=&quot;隐私条款&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通过1.1.1.1登录&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/gt1wijmpnv3rdms.jpeg&quot; alt=&quot;登录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;登录界面
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/gt1wijmpnv3rdms.jpeg&quot; alt=&quot;登录界面&quot; /&gt;
登录成功后就可以成功进入Team版无限流量啦！享受生活！
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cf-warp/xtkpey2uw3fxamz.jpeg&quot; alt=&quot;连接成功！&quot; /&gt;&lt;/p&gt;
&lt;p&gt;[^2]: WARP 是 Cloud­flare 提供的一项基于 Wire­Guard 的网络流量安全及加速服务，能够让你通过连接到 Cloud­flare 的边缘节点实现隐私保护及链路优化。其连接入口为双栈 (IPv4/​IPv6)，因此单栈服务器可以连接到 WARP 来获取额外的网络连通性支持。
比如可以让仅具有 IPv6 的服务器直接访问 IPv4 网络，不再局限于 DNS64 的束缚，能自定义任意 DNS 解析服务器，对于科学上网会有很大的帮助；也能让仅具有 IPv4 的服务器获得 IPv6 网络的访问能力，可以作为 IPv6 Only VPS 的 SSH 跳板。
[^3]: &lt;a href=&quot;https://zhuanlan.zhihu.com/p/452378078&quot;&gt;知乎专栏-外区Apple ID注册方式，2022版&lt;/a&gt;
[^4]: &lt;a href=&quot;https://blog.cloudflare.com/zh-cn/1111-warp-better-vpn-zh-cn/&quot;&gt;Cloudflare公布1.1.1.1&lt;/a&gt;
[^5]: &lt;a href=&quot;https://blog.cloudflare.com/zh-cn/warp-for-desktop-zh-cn/&quot;&gt;WARP for Desktop 和 Cloudflare for Teams&lt;/a&gt;&lt;/p&gt;
</content:encoded></item><item><title>Cryptomator 开源应用保护你的隐私！</title><link>https://blog.moraxyc.com/posts/cryptomator/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/cryptomator/</guid><pubDate>Mon, 24 Jan 2022 22:05:42 GMT</pubDate><content:encoded>&lt;p&gt;众所周知，著名公司某度与谷某绝不会窥探用户隐私，绝不对文件进行审查。某度甚至表示绝不会替换用户文件为其他视频。
&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;（本段为虚构情节，如有雷同纯属巧合🙃）&lt;/p&gt;
&lt;p&gt;我们在生活中经常会用到网盘。但除了那些端对端加密的高档货（例如Mega），每一个网盘都会对文件进行审查。这无疑是损坏了用户的隐私权益。&lt;/p&gt;
&lt;p&gt;这时，就要请上主角- Cryptomator！&lt;/p&gt;
&lt;h2&gt;介绍&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/gwdt3hhlat2zmag.jpeg&quot; alt=&quot;Cryptomator Logo&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是一个开源软件，在Github上的&lt;a href=&quot;https://github.com/cryptomator/cryptomator&quot;&gt;Cryptomator库&lt;/a&gt;开源，所以可以对其安全性放心。&lt;/p&gt;
&lt;p&gt;开发者使用了强大的加密与混淆方法，对目录、名称及内容都进行了加密。单从外部来看是没有任何办法找到真实内容。&lt;/p&gt;
&lt;p&gt;开发者在立项时就决定这个应用适用于网盘同步加密，所以产生了这种特殊的分割式加密，使得不像Veracrypt那样，一旦内容更换就需要全部重新下载。&lt;/p&gt;
&lt;h2&gt;用法&lt;/h2&gt;
&lt;p&gt;在&lt;a href=&quot;https://cryptomator.org/downloads/&quot;&gt;Cryptomator下载界面&lt;/a&gt;下载安装适合自己系统的程序版本。&lt;/p&gt;
&lt;p&gt;:::note[iOS收费]
顺带一提，这个软件是全平台的，仅有iOS收费，就当是捐款支持了
:::&lt;/p&gt;
&lt;h3&gt;第一步：创建保险库&lt;/h3&gt;
&lt;h4&gt;电脑客户端&lt;/h4&gt;
&lt;p&gt;在PC、Mac或Linux客户端中，网盘必须挂载才能在使用cryptomator。因为博主只有Windows电脑&lt;s&gt;绝不是因为买不起&lt;/s&gt;，所以就以Windows版演示。&lt;/p&gt;
&lt;h5&gt;软件界面&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/wqrcnfs2ry9pdxf.jpeg&quot; alt=&quot;Windows版&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;首选项&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/jucbfgile7gqw2c.jpeg&quot; alt=&quot;常规&quot; /&gt;
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/qnnexk6pzch7gxv.jpeg&quot; alt=&quot;虚拟磁盘&quot; /&gt;
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/lyepdzv5h3xgmaw.jpeg&quot; alt=&quot;支持我们&quot; /&gt;&lt;/p&gt;
&lt;h5&gt;添加保险库&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/oq7r2hzybbuqvnv.jpeg&quot; alt=&quot;点击添加保险库&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::tip[选择]
这一步中，如果你已经创建过网盘保险库，那就直接选择即可
:::&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/v1kqghpi9d8xayn.jpeg&quot; alt=&quot;选择创建/现有&quot; /&gt;&lt;/p&gt;
&lt;h6&gt;填写名称&lt;/h6&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/zoalyixozfwwapb.jpeg&quot; alt=&quot;输入名称&quot; /&gt;&lt;/p&gt;
&lt;h6&gt;选择路径&lt;/h6&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/q8zwkgojofxht2r.jpeg&quot; alt=&quot;选择你想要的路径&quot; /&gt;
:::tip[注意]
这里的选择仅仅只是保险库目录存在的父目录，真正的路径将会由程序自动创建为父目录下你填写的保险库名称的文件夹。
:::&lt;/p&gt;
&lt;h6&gt;输入密码&lt;/h6&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/btydqwfctaorkya.jpeg&quot; alt=&quot;密码&quot; /&gt;&lt;/p&gt;
&lt;p&gt;:::caution[强烈建议]
强烈建议选择创建恢复密钥。因为如果你的密码忘了，真的真的真的只能通过这个恢复了
:::&lt;/p&gt;
&lt;h5&gt;创建成功&lt;/h5&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/1zn2phls8ryegfa.jpeg&quot; alt=&quot;成功&quot; /&gt;&lt;/p&gt;
&lt;p&gt;你可以在主界面选择解锁了！&lt;/p&gt;
&lt;h4&gt;手机客户端&lt;/h4&gt;
&lt;p&gt;手机客户端支持链接常见的网盘&lt;s&gt;除某度网盘、阿某云盘外&lt;/s&gt;，也支持webdav。&lt;/p&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;iOS客户端&amp;lt;sub&amp;gt;点此展开&amp;lt;/sub&amp;gt;&amp;lt;/summary&amp;gt;&lt;/p&gt;
&lt;p&gt;iOS上的Cryptomator比较特殊，截至2021.12.19日前，App Store上的版本为1.x。而开发者正在开发2.x版本。可以通过&lt;a href=&quot;https://testflight.apple.com/join/WMtYSrzD&quot;&gt;Testflight&lt;/a&gt;提前尝试。&lt;/p&gt;
&lt;p&gt;1.x因为使用自身的文件管理方式，无法绕开iOS的文件沙盒，导致使用iCloud同步的果粉们功能受限，且管理很不方便。所以强烈建议等一会儿后使用第二个版本，直接内置于Apple 文件应用，cryptomator程序仅有加解密功能。（多个加密盘会在文件里显示多个盘，下带名称）
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/bev6osd4liqfzmg.jpeg&quot; alt=&quot;iOS Cryptomator 2.x 程序本序&quot; /&gt;
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/6y3xkvijfq2bzsq.jpeg&quot; alt=&quot;iOS Cryptomator 2.x 文管程序&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有人担心买了第一版是不是还得买第二版？&lt;s&gt;没错就是我&lt;/s&gt;完全没必要
&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/k7l2y51nmejwdv9.jpeg&quot; alt=&quot;Reply&quot; /&gt;
开发者回应，购买了第一版的将会免费获得第二版的使用权。参与testflight测试的用户可以在测试期间免费使用。
&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;h3&gt;第二步：上传后在另一个设备添加保险库&lt;/h3&gt;
&lt;p&gt;这一步很简单，以iOS Cryptomqtor 2.x举例，挂载对应的网盘，打开现有保险库，输入密码解锁即可。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/cryptomator/vgtjn81xwyjl7a6.jpeg&quot; alt=&quot;添加保险库 iOS&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;小结&lt;/h3&gt;
&lt;p&gt;接下来，享受无法被窥视的轻松生活吧！😎&lt;/p&gt;
&lt;p&gt;:::note[注意事项]&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;任何一个文件都别丢！因为Cryptomator是无序加密的，谁也不知道这个对应哪一个文件！&lt;/li&gt;
&lt;li&gt;iCloud PC版挺抽风，不建议用windows的朋友使用iCloud同步。&lt;s&gt;Onedrive都比它好&lt;/s&gt;&lt;/li&gt;
&lt;li&gt;Cryptomator已经算加密软件中性能比较好的了&lt;s&gt;当然比不上Veracrypt&lt;/s&gt;，但还是要注意别传太大或过多的文件。
:::&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Google Search Console 让你的网站充满人气!</title><link>https://blog.moraxyc.com/posts/google-search-console/</link><guid isPermaLink="true">https://blog.moraxyc.com/posts/google-search-console/</guid><pubDate>Mon, 24 Jan 2022 18:01:17 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;!-- more --&amp;gt;&lt;/p&gt;
&lt;p&gt;建站之后，你是否发现一个访问也没有？你是否时常感到空虚?现在，我们拥有了站长们都必须拥有的权利：让别人知道我们！&lt;/p&gt;
&lt;h2&gt;搜索 Google，判断网站是否被收录&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;site:&amp;lt;your-url&amp;gt; #直接在Google上这样搜索，&amp;lt;your-url&amp;gt;填写你自己的站点&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;大多数情况会是这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/1.jpeg&quot; alt=&quot;搜索失败了&quot; /&gt;
别担心，这种情况下，我们就需要主动向 Google 填报网站，让 Google 的 spider 爬到我们的文章。&lt;/p&gt;
&lt;h2&gt;申请索引&lt;/h2&gt;
&lt;p&gt;打开&lt;a href=&quot;https://search.google.com/search-console/&quot;&gt;Google Search Console&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/2.jpeg&quot; alt=&quot;选择资源类型&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里有两种认证所有权的对象：网域认证和网页认证，建议使用第二个，比较简单。所以在这里我只以此为例。&lt;/p&gt;
&lt;p&gt;输入需要认证的 url 后，会有五种方法可供认证：&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;HTML 文件：通过在网址根目录添加一个随机生成的.html 文件验证。优点：不需要改动原有代码。&lt;/li&gt;
&lt;li&gt;HTML 标记：通过向首页添加元标记，将元标记复制到第一个&amp;lt;head&amp;gt;中验证。缺点：需要改动原有 index.html&lt;/li&gt;
&lt;li&gt;Google Analytics：注册 Google Analytics 账号后将 analytics.js 或 gtag.js 代码段添加到&amp;lt;head&amp;gt;中。&lt;/li&gt;
&lt;li&gt;Google Tag Manager：同样如此&lt;/li&gt;
&lt;li&gt;DNS 设置：将 TXT 记录复制到 DNS 配置中。缺点：麻烦，响应慢（最长 1 天），有的服务商很难找到 DNS 配置入口。&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;第一种方式最简单也最直接。&lt;/p&gt;
&lt;p&gt;Google 会提供一份 html 文件，只需把文件上传至网站根目录即可。&lt;/p&gt;
&lt;p&gt;验证完成后会这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/3.jpeg&quot; alt=&quot;验证成功啦！&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;建立 sitemap 提高爬虫速度&lt;/h2&gt;
&lt;p&gt;打开&lt;a href=&quot;http://XML-Sitemaps.com&quot;&gt;XML-sitemaps&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/4.jpeg&quot; alt=&quot;进入&quot; /&gt;&lt;/p&gt;
&lt;p&gt;填入自己的网站 URL，然后开始爬取&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/5.jpeg&quot; alt=&quot;爬取成功&quot; /&gt;&lt;/p&gt;
&lt;p&gt;接着进入 detail，然后下载&lt;code&gt;sitemap.xml&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://thumbnail.moraxyc.com/blog/gsc/6.jpeg&quot; alt=&quot;Detail&quot; /&gt;&lt;/p&gt;
&lt;p&gt;把这个文件上传到网站根目录下（如果你用的是宝塔面板，你可以直接将下载链接复制过去远程下载，更方便）&lt;/p&gt;
&lt;p&gt;转到&lt;a href=&quot;https://search.google.com/search-console/&quot;&gt;Google Search Console&lt;/a&gt;，在菜单中找到站点地图，填入&lt;code&gt;/sitemap.xml&lt;/code&gt;即可。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;以上就是让 Google 加入自己网站的教程，是不是很简单？&lt;/p&gt;
&lt;p&gt;当然，有了索引却没文章是一个很丢脸的事情哦，望各位像我一样&lt;s&gt;不要脸&lt;/s&gt;，不当鸽子 🐦！&lt;/p&gt;
</content:encoded></item></channel></rss>