<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>惜别的秘密基地</title>
  
  
  <link href="https://sekibetu.com/atom.xml" rel="self"/>
  <link href="https://pubsubhubbub.appspot.com/" rel="hub"/>
  <link href="https://sekibetu.com/"/>
  <updated>2025-09-16T15:34:20.000Z</updated>
  <id>https://sekibetu.com/</id>
  
  <author>
    <name>SekiBetu</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>对Linux社区封禁俄罗斯开发者且linus本人支持这一行为的评价</title>
    <link href="https://sekibetu.com/linus01.html"/>
    <id>https://sekibetu.com/linus01.html</id>
    <published>2024-10-24T13:54:15.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>这件事确实引发了广泛的争议，值得我们深入思考。Linus Torvalds作为开源界的领军人物，他的行为无疑会在全球范围内产生影响。他决定封禁俄罗斯开发者的账号，表面上看，似乎是对俄罗斯在乌克兰问题上采取的立场和行动作出回应，表达了某种政治立场。然而，这一做法却引起了开源社区的强烈反弹，主要是因为开源社区一向强调全球合作、技术无国界的精神。</p><p>我们必须承认，乌克兰战争是一个非常复杂的国际事件，它牵动着全球舆论，很多国家和个人对此都有立场和情感。然而，将政治因素引入技术领域，特别是开源这种基于全球协作的项目中，难免会导致更多的分歧和对立。封禁俄罗斯开发者不仅可能影响开源项目的质量和进展，还可能破坏开源社区的包容性，甚至削弱这一技术领域长期以来形成的多边合作机制。</p><p>从现实出发，制裁和封禁措施本身或许能够带来短期的压力，但从长远来看，技术的进步和创新依赖于跨国界的协作与共享。开源世界的成功正是因为它超越了政治、种族和国界，为全世界的开发者提供了一个平等的舞台。将某个国家的开发者排除在外，不仅是在打击个体的贡献，更是对全球技术生态的破坏。</p><p>因此，我认为Linus的这一决定虽然在当前的国际形势下可以理解，但从维护全球开源生态的长远利益来看，恐怕并不是最佳的选择。技术合作需要保持相对的独立性，不能被政治因素过多干扰，否则最终可能伤害的是整个行业的健康发展。希望开源社区能够冷静思考，找到一种既能够表达立场又不损害合作精神的解决方案。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;这件事确实引发了广泛的争议，值得我们深入思考。Linus Torvalds作为开源界的领军人物，他的行为无疑会在全球范围内产生影响。他决定封禁俄罗斯开发者的账号，表面上看，似乎是对俄罗斯在乌克兰问题上采取的立场和行动作出回应，表达了某种政治立场。然而，这一做法却引起了开源社</summary>
      
    
    
    
    
    <category term="Linux" scheme="https://sekibetu.com/tags/Linux/"/>
    
  </entry>
  
  <entry>
    <title>三分钟，让Follow认证我的Hexo博客订阅源</title>
    <link href="https://sekibetu.com/followis.html"/>
    <id>https://sekibetu.com/followis.html</id>
    <published>2024-10-14T12:04:50.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>书接上回：<br><a href="https://sekibetu.com/rss01.html">https://sekibetu.com/rss01.html</a></p><p>通过Follow认证十分简单，首先在Follow上获得需要认证的暗号</p><p><img src="followis/1.png" alt=""></p><p><img src="followis/2.png" alt=""></p><p>此处我选择最简单的修改插件模版的方式，我使用的是atom模版，所以修改atom.xml</p><p><img src="followis/3.png" alt=""></p><p>随便找个地方把暗号插入即可</p><p><img src="followis/4.png" alt=""></p><p>完成后再次部署，查看网站的RSS订阅是否已经存在这个暗号了</p><p><img src="followis/5.png" alt=""></p><p>完成后按下Follow里的认证，无内鬼，暗号正确，就通过了</p><p><img src="followis/6.png" alt=""></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;书接上回：&lt;br&gt;
&lt;a href=&quot;https://sekibetu.com/rss01.html&quot;&gt;https://sekibetu.com/rss01.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;通过Follow认证十分简单，首先在Follow上获得需要认证的暗号&lt;/p&gt;
&lt;p&gt;</summary>
      
    
    
    
    
    <category term="Hexo" scheme="https://sekibetu.com/tags/Hexo/"/>
    
    <category term="RSS" scheme="https://sekibetu.com/tags/RSS/"/>
    
  </entry>
  
  <entry>
    <title>给 Hexo 博客加上 PubSubHubbub 协议实现 RSS 实时推送</title>
    <link href="https://sekibetu.com/rss01.html"/>
    <id>https://sekibetu.com/rss01.html</id>
    <published>2022-06-29T21:55:05.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="第一步">第一步</h2><ul><li>安装 <a href="https://github.com/hexojs/hexo-generator-feed">hexo-generator-feed</a> 插件</li></ul><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install hexo-generator-feed</span><br></pre></td></tr></table></figure><h2 id="第二步">第二步</h2><ul><li>在 Hexo 博客配置文件 <code>_config.yml</code> 中配置上述插件的 <code>hub</code> 项为 <a href="https://pubsubhubbub.appspot.com">Google PubSubHubbub Hub</a></li></ul><figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">feed:</span></span><br><span class="line">  <span class="attr">hub:</span> <span class="string">https://pubsubhubbub.appspot.com</span></span><br></pre></td></tr></table></figure><h2 id="第三步">第三步</h2><ul><li>在部署 Hexo 静态博客的相关站点设置 Webhook, 此处以 GitHub 为例, 在站点仓库新建一个 Webhook</li></ul><p><img src="rss01/01.png" alt=""></p><ul><li><code>Payload URL</code> 的填写格式为</li></ul><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">https://pubsubhubbub.appspot.com/publish?hub.mode=publish&amp;hub.url=站点RSS链接</span><br><span class="line"></span><br><span class="line"># 以本站为例</span><br><span class="line">https://pubsubhubbub.appspot.com/publish?hub.mode=publish&amp;hub.url=https://sekibetu.com/atom.xml</span><br></pre></td></tr></table></figure><ul><li><code>Content type</code> 选择 <code>application/x-www-form-urlencoded</code></li></ul><p><img src="rss01/02.png" alt=""></p><ul><li>在 GitHub 中还可以设置各种触发 Webhook 的方式，因为 Hexo 博客是静态网页，我们可以选择 <code>Page builds</code> , 这样每次站点更新后就会触发 Webhook</li></ul><p><img src="rss01/03.png" alt=""></p><h2 id="第四步">第四步</h2><ul><li>做完上一步之后就大功告成了, 可以在 <a href="https://www.inoreader.com/">Inoreader</a> 等支持 <a href="https://github.com/pubsubhubbub/">PubSubHubbub</a> 协议的 RSS 订阅软件中查看自己的站点是不是已经实时推送了</li></ul><p><img src="rss01/04.png" alt=""></p><ul><li>经过测试，本文在站点更新后也是实时推送了</li></ul><p><img src="rss01/05.png" alt=""></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;第一步&quot;&gt;第一步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;安装 &lt;a href=&quot;https://github.com/hexojs/hexo-generator-feed&quot;&gt;hexo-generator-feed&lt;/a&gt; 插件&lt;/li&gt;
&lt;/ul&gt;
&lt;figure clas</summary>
      
    
    
    
    
    <category term="RSS" scheme="https://sekibetu.com/tags/RSS/"/>
    
  </entry>
  
  <entry>
    <title>抓取安卓端FGO游戏数据并导入素材规划软件Chaldea教程(需解锁BootLoader)</title>
    <link href="https://sekibetu.com/sniff01.html"/>
    <id>https://sekibetu.com/sniff01.html</id>
    <published>2022-06-08T11:58:22.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>更新 Android 12 系统之后，证书不让安装为 root 证书了，SSL Pinning 也来了，老办法抓不到数据了，于是经过一番摸索，写下了本文，本文理论上适用于所有 APP，不仅仅是 FGO</p><h2 id="第一步">第一步</h2><ul><li><p>参照以下文章安装 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a></p></li><li><p><a href="https://sekibetu.com/magisk01.html">https://sekibetu.com/magisk01.html</a></p></li></ul><h2 id="第二步">第二步</h2><ul><li><p>参照以下文章的第二步，在 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 中刷入对应 Zygisk 版本的 <a href="https://github.com/LSPosed/LSPosed/releases/latest">LSPosed</a> 框架</p></li><li><p><a href="https://sekibetu.com/tiktok01.html">https://sekibetu.com/tiktok01.html</a></p></li></ul><h2 id="第三步">第三步</h2><ul><li><p>下载 <a href="https://github.com/SekiBetu/MagiskTrustUserCerts/releases/latest">MagiskTrustUserCerts</a> 并在 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 中刷入</p></li><li><p>重启手机</p></li></ul><h2 id="第四步">第四步</h2><ul><li>安装 <a href="https://github.com/SekiBetu/JustTrustMe/releases/latest">JustTrustMe</a> 模块(用来绕过 SSL Pinning)，并在 <a href="https://github.com/LSPosed/LSPosed/releases/latest">LSPosed</a> 中启用，模块作用域指定为 FGO</li></ul><p><img src="sniff01/1.png" alt=""></p><p><img src="sniff01/2.png" alt=""></p><h2 id="第五步">第五步</h2><ul><li><p>下载安装 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 或 <a href="https://mitmproxy.org/">mitmproxy</a></p></li><li><p>启动 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 或 <a href="https://mitmproxy.org/">mitmproxy</a> 并进行一些基础设置，以下是 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 的基础设置， <a href="https://mitmproxy.org/">mitmproxy</a> 并不需要特别设置即可使用，我是通过 <code>python</code> 的 <code>pip install mitmproxy</code> 安装的，所以直接在命令行输入 <code>mitmweb</code> 启动</p></li></ul><p><img src="sniff01/3.png" alt=""></p><p><img src="sniff01/4.png" alt=""></p><ul><li>通过 <code>ipconfig</code> 程序找到你的本地局域网 IPv4 地址</li></ul><p><img src="sniff01/5.png" alt=""></p><ul><li>将其填入手机 WLAN 中的代理设置并保存，端口号为 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 或 <a href="https://mitmproxy.org/">mitmproxy</a> 的代理端口，默认为 <code>8888</code> 和 <code>8080</code></li></ul><p><img src="sniff01/6.png" alt=""></p><p><img src="sniff01/7.png" alt=""></p><ul><li>使用手机浏览器访问上述 IP 与端口并点击 <code>FiddlerRoot certificate</code> 下载 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 的证书</li></ul><p><img src="sniff01/8.png" alt=""></p><p><img src="sniff01/9.png" alt=""></p><ul><li>或访问 <a href="mitm.it">mitm.it</a> 下载 <a href="https://mitmproxy.org/">mitmproxy</a> 的证书</li></ul><p><img src="sniff01/10.png" alt=""></p><p><img src="sniff01/11.png" alt=""></p><ul><li><p>从系统设置中安装下载好的证书，以小米的 MIUI 系统为例，在 <code>设置</code> — <code>密码与安全</code> — <code>系统安全</code> — <code>加密与凭证</code> — <code>安装证书</code> — <code>CA证书</code></p></li><li><p>安装完证书重启手机，第三步中的证书提权模块 <a href="https://github.com/SekiBetu/MagiskTrustUserCerts/releases/latest">MagiskTrustUserCerts</a> 会在重启的过程中将安装完的用户证书复制到 root 证书目录以提权</p></li></ul><h2 id="第六步">第六步</h2><ul><li>登录 FGO 使 <a href="https://www.telerik.com/download/fiddler">Fiddler Classic</a> 或 <a href="https://mitmproxy.org/">mitmproxy</a> 抓到用户的数据</li></ul><p><img src="sniff01/12.png" alt=""></p><ul><li>国服一般会在 <code>line3-s2-bili-fate.bilibiligame.net/rongame_beta/rgfate/60_1001/ac.php</code> 这样的路径抓到一个大小较大的包，保存抓到的数据的 Response Body</li></ul><p><img src="sniff01/13.png" alt=""></p><p><img src="sniff01/14.png" alt=""></p><ul><li>将数据导入 <a href="https://github.com/chaldea-center/chaldea/releases/latest">Chaldea</a> 就可以愉快地规划素材刷取了</li></ul><p><img src="sniff01/15.png" alt=""></p><p><img src="sniff01/16.png" alt=""></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;更新 Android 12 系统之后，证书不让安装为 root 证书了，SSL Pinning 也来了，老办法抓不到数据了，于是经过一番摸索，写下了本文，本文理论上适用于所有 APP，不仅仅是 FGO&lt;/p&gt;
&lt;h2 id=&quot;第一步&quot;&gt;第一步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
</summary>
      
    
    
    
    
    <category term="Fiddler" scheme="https://sekibetu.com/tags/Fiddler/"/>
    
    <category term="Android" scheme="https://sekibetu.com/tags/Android/"/>
    
    <category term="HTTPS" scheme="https://sekibetu.com/tags/HTTPS/"/>
    
    <category term="FGO" scheme="https://sekibetu.com/tags/FGO/"/>
    
    <category term="mitmproxy" scheme="https://sekibetu.com/tags/mitmproxy/"/>
    
  </entry>
  
  <entry>
    <title>SSH客户端简单对比</title>
    <link href="https://sekibetu.com/ssh01.html"/>
    <id>https://sekibetu.com/ssh01.html</id>
    <published>2022-06-07T14:37:06.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>不采用横向对比，以缺点为主，优点仅为备注作用</p><ul><li><p><a href="https://www.openssh.com/">OpenSSH</a></p><ul><li>优点：开源，跨平台，各大系统默认集成，不需要安装</li><li>缺点：使用过程全靠手打命令行参数，SFTP 的使用繁琐</li><li>个人推荐度：⭐</li></ul></li><li><p><a href="https://www.putty.org/">PuTTY</a> + <a href="https://winscp.net/eng/index.php">WinSCP</a></p><ul><li>优点：开源</li><li>缺点：界面丑，使用时 <a href="https://winscp.net/eng/index.php">WinSCP</a> 不能同步当前 <a href="https://www.putty.org/">PuTTY</a> 所在目录</li><li>个人推荐度：⭐⭐</li></ul></li><li><p><a href="https://termius.com/">Termius</a></p><ul><li>优点：跨平台，有手机端</li><li>缺点：商业闭源，SFTP 功能需付费</li><li>个人推荐度：⭐⭐</li></ul></li><li><p><a href="https://code.visualstudio.com/">Visual Studio Code</a></p><ul><li>优点：跨平台，易于编辑代码</li><li>缺点：终端界面过小，浏览服务器目录的方式逆天，需要频繁重新输入 passphrase</li><li>个人推荐度：⭐</li></ul></li><li><p><a href="https://www.netsarang.com/en/xshell/">Xshell</a></p><ul><li>优点：功能齐全，支持 SFTP</li><li>缺点：商业闭源</li><li>个人推荐度：⭐⭐⭐</li></ul></li><li><p><a href="https://github.com/kingToolbox/WindTerm">WindTerm</a></p><ul><li>优点：跨平台，功能齐全，支持 SFTP，内存使用较少，使用流畅</li><li>缺点：逐渐开源</li><li>个人推荐度：⭐⭐⭐⭐</li></ul></li><li><p><a href="https://github.com/electerm/electerm">Electerm</a></p><ul><li>优点：开源，跨平台，功能齐全，支持 SFTP，可查看服务器运行信息</li><li>缺点：内存使用较多，界面 UI 较为卡顿，不能使用本地编辑器打开文件，长时间使用会断开连接</li><li>个人推荐度：⭐⭐⭐</li></ul></li><li><p><a href="https://github.com/Eugeny/tabby">Tabby</a></p><ul><li>优点：开源，跨平台，功能齐全，支持 SFTP，使用还算流畅</li><li>缺点：内存使用较多，SFTP 目录同步需要 <a href="https://github.com/Eugeny/tabby/wiki/Shell-working-directory-reporting">配置</a></li><li>个人推荐度：⭐⭐⭐⭐</li></ul></li></ul><p>个人总结：</p><ul><li><p>使用 SSH 协议连接服务器是一个较为敏感的操作，应避免使用闭源软件，但 <a href="https://github.com/kingToolbox/WindTerm">WindTerm</a> 的使用体验极佳，是个特例，如果在未来完全开源，我将会优先选择它</p></li><li><p><a href="https://github.com/Eugeny/tabby">Tabby</a> 与 <a href="https://github.com/electerm/electerm">Electerm</a> 因占用大量内存而成为了难兄难弟，如果在服务器上安装一个 <a href="https://github.com/aristocratos/btop">btop</a> ，则 <a href="https://github.com/Eugeny/tabby">Tabby</a> 优于 <a href="https://github.com/electerm/electerm">Electerm</a> ，我目前也正在使用 <a href="https://github.com/Eugeny/tabby">Tabby</a></p></li><li><p><a href="https://www.putty.org/">PuTTY</a> 与 <a href="https://winscp.net/eng/index.php">WinSCP</a> 的组合是我的 Plan B</p></li><li><p><a href="https://www.openssh.com/">OpenSSH</a> 很纯真，很朴素</p></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;不采用横向对比，以缺点为主，优点仅为备注作用&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://www.openssh.com/&quot;&gt;OpenSSH&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;优点：开源，跨平台，各大系统默认集成，不需要安装&lt;/li&gt;
&lt;li&gt;缺点：</summary>
      
    
    
    
    
    <category term="ssh" scheme="https://sekibetu.com/tags/ssh/"/>
    
  </entry>
  
  <entry>
    <title>国际版抖音TikTok改区观看方法(需解锁BootLoader)</title>
    <link href="https://sekibetu.com/tiktok01.html"/>
    <id>https://sekibetu.com/tiktok01.html</id>
    <published>2022-06-03T14:42:31.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="第一步">第一步</h2><ul><li>参照以下文章安装 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a></li><li><a href="https://sekibetu.com/magisk01.html">https://sekibetu.com/magisk01.html</a></li></ul><h2 id="第二步">第二步</h2><ul><li>在 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 设置中启用 Zygisk (关于什么是 Zygisk 请看 <a href="https://topjohnwu.medium.com/state-of-magisk-2021-fe29fdaee458">这篇文章</a> 和 <a href="https://t.me/LSPosed/140">这个公告</a> )</li></ul><p><img src="tiktok01/1.png" alt=""></p><ul><li>下载对应 Zygisk 的 <a href="https://github.com/LSPosed/LSPosed/releases/latest">LSPosed</a> 版本并在 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 中刷入，然后重启手机</li></ul><p><img src="tiktok01/2.png" alt=""></p><p><img src="tiktok01/3.png" alt=""></p><p><img src="tiktok01/4.png" alt=""></p><h2 id="第三步">第三步</h2><ul><li>安装 <a href="https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill">TikTok</a></li></ul><p><img src="tiktok01/5.png" alt=""></p><h2 id="第四步">第四步</h2><ul><li><p>安装可以修改手机 SIM 卡信息的相关模块( <a href="https://github.com/NekoGirlSAIKOU/AppEnv-Kotlin/releases/latest">应用变量</a>、<a href="https://github.com/Xposed-Modules-Repo/com.variable.apkhook/releases/latest">应用伪装</a>、<a href="https://github.com/Tornaco/Thanox/releases/latest">Thanox</a> 等)，本文以 <a href="https://github.com/Xposed-Modules-Repo/com.variable.apkhook">源计划</a> 模块做演示</p></li><li><p>在 <a href="https://github.com/LSPosed/LSPosed/releases/latest">LSPosed</a> 中激活上述模块并指定模块作用域为 <a href="https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill">TikTok</a></p></li></ul><p><img src="tiktok01/6.png" alt=""></p><p><img src="tiktok01/7.png" alt=""></p><h2 id="第五步">第五步</h2><ul><li>在 <a href="https://github.com/Xposed-Modules-Repo/com.variable.apkhook">源计划</a> 模块 APP 中搜索 <a href="https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill">TikTok</a> 并进入详细设置界面</li></ul><p><img src="tiktok01/8.png" alt=""></p><ul><li>修改 <code>SIM信息</code> 中的 <code>SIM厂商</code> 、 <code>SIM国际</code> 和 <code>SIM名称</code> (不同模块有不同的叫法)，将 SIM 卡伪装成非大陆 SIM 卡即可</li></ul><p><img src="tiktok01/9.png" alt=""></p><h2 id="第六步">第六步</h2><ul><li><p>修改手机的地区，以 MIUI 系统为例，进入 <code>设置</code> —— <code>更多设置</code> —— <code>地区</code> ，设置成中国以外的国家或者地区</p></li><li><p>修改手机的时区，进入 <code>设置</code> —— <code>更多设置</code> —— <code>日期和时间</code> ，关闭 <code>自动设置时区</code> ，进入 <code>选择时区</code> 选择一个非大陆的时区即可，推荐选择马来西亚、台湾、香港等和大陆同一个时区的国家或者地区，这样不会影响手机的时间</p></li></ul><h2 id="第七步">第七步</h2><ul><li><p>保证你的网络环境能够访问 <a href="https://www.tiktok.com/">TikTok 官网</a></p></li><li><p>打开 <a href="https://play.google.com/store/apps/details?id=com.ss.android.ugc.trill">TikTok</a> 开始看视频吧，账号登录、点赞、收藏、关注、评论都可正常使用</p></li></ul><p><img src="tiktok01/10.png" alt=""></p><p><img src="tiktok01/11.png" alt=""></p><p><img src="tiktok01/12.png" alt=""></p>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;第一步&quot;&gt;第一步&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;参照以下文章安装 &lt;a href=&quot;https://github.com/topjohnwu/Magisk/releases/latest&quot;&gt;Magisk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://s</summary>
      
    
    
    
    
    <category term="Android" scheme="https://sekibetu.com/tags/Android/"/>
    
    <category term="TikTok" scheme="https://sekibetu.com/tags/TikTok/"/>
    
    <category term="Xposed" scheme="https://sekibetu.com/tags/Xposed/"/>
    
  </entry>
  
  <entry>
    <title>十分钟学会Magisk的安装</title>
    <link href="https://sekibetu.com/magisk01.html"/>
    <id>https://sekibetu.com/magisk01.html</id>
    <published>2022-06-03T11:58:39.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>本文 PDF 版：<a href="magisk01/magisk01.pdf">magisk01.pdf</a></p><p>Magisk 官方教程指路：<a href="https://topjohnwu.github.io/Magisk/install.html">https://topjohnwu.github.io/Magisk/install.html</a></p><p>本文仅为官方教程中最通用的一种方法的个人实践过程(Ramdisk、vbmeta 验证和三星手机的问题还请自行查阅上述官方教程)</p><h2 id="食材准备：">食材准备：</h2><ul><li><p>手机一部，本文以 红米 K30Pro (MIUI 13 Android 12) 做演示</p></li><li><p>电脑一台，本文以 Windows 11 系统 做演示</p></li><li><p>USB 线一根</p></li></ul><h2 id="厨具准备：">厨具准备：</h2><ul><li><p><a href="https://developer.android.com/studio/releases/platform-tools">Android SDK Platform-Tools</a></p></li><li><p><a href="https://developer.android.com/studio/run/win-usb">Google USB</a></p></li><li><p><a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a></p></li></ul><h2 id="烹饪步骤：">烹饪步骤：</h2><ul><li><p>通过小米官方的 <a href="https://www.miui.com/unlock/download.html">解锁工具</a> 解锁手机的 BootLoader (不同的厂商有不同的解锁方式，也有一些厂商不支持解锁 BootLoader)</p></li><li><p>把下载好的 <a href="https://developer.android.com/studio/releases/platform-tools">Android SDK Platform-Tools</a> 压缩包解压到一个文件夹中</p></li></ul><p><img src="magisk01/1.png" alt=""></p><ul><li>【可选步骤】将上述文件夹的路径加入到系统环境变量以使 <code>adb</code> 、<code>fastboot</code>等程序能够在任意位置调用(如果不进行此处步骤，则下述步骤中的 <code>cmd</code> 和 <code>powershell 7</code> 请在上述 <a href="https://developer.android.com/studio/releases/platform-tools">Android SDK Platform-Tools</a> 解压后的文件夹目录中运行，并替换 <code>adb</code> 和 <code>fastboot</code> 指令为 <code>.\adb.exe</code> 和 <code>.\fastboot.exe</code> 执行)</li></ul><p><img src="magisk01/2.png" alt=""></p><ul><li><p>通过手机品牌官网下载或者以抓包的方式获取手机的系统安装包并解压获得 <code>boot.img</code> 文件</p></li><li><p>在手机上安装 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a></p></li><li><p>将上述步骤获取到的 <code>boot.img</code> 文件传输到手机中，并用 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 对其进行修补</p></li></ul><p><img src="magisk01/3.png" alt=""></p><p><img src="magisk01/4.png" alt=""></p><p><img src="magisk01/5.png" alt=""></p><p><img src="magisk01/6.png" alt=""></p><ul><li><p>将修补后的 <code>magisk_patched-25000_XXXXX.img</code> 文件传输回电脑</p></li><li><p>将手机通过 USB 连上电脑并启用手机的 USB 调试模式，然后设置为文件传输模式(各品牌手机不同，小米手机可以通过 <code>我的设备 </code> —— <code>全部参数</code> —— 多次点击 <code>MIUI版本</code> 开启开发者模式，在 <code>更多设置</code> —— <code>开发者选项</code> 中启用 <code>USB调试</code> 选项)</p></li><li><p>【可选步骤，适用于 USB 连接有问题的人】下载 <a href="https://developer.android.com/studio/run/win-usb">Google USB</a> 驱动压缩包并解压到一个文件夹后安装</p></li></ul><p><img src="magisk01/7.png" alt=""></p><p><img src="magisk01/8.png" alt=""></p><p><img src="magisk01/9.png" alt=""></p><p><img src="magisk01/10.png" alt=""></p><ul><li><p>在电脑上打开 <code>cmd</code> 或者 <code>powershell 7</code> ，输入 <code>adb devices</code> 回车执行查看是否能检测到手机，如果没有检测到则返回上一步安装 <a href="https://developer.android.com/studio/run/win-usb">Google USB</a> 驱动</p></li><li><p>继续输入 <code>adb reboot bootloader</code> 回车执行使手机进入 fastboot 模式(也可以在手机关机状态下，同时按住 <code>电源</code> 和 <code>音量+</code> 键几秒后进入)</p></li></ul><p><img src="magisk01/11.png" alt=""></p><ul><li><p>继续输入 <code>fastboot flash boot 路径\magisk_patched-25000_XXXXX.img</code> 回车执行刷入通过 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 修补后的上述文件</p></li><li><p>继续输入 <code>fastboot reboot</code> 或者长按电源键关机后重启手机，至此，<a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 的安装就完成了</p></li></ul><p><img src="magisk01/12.png" alt=""></p><h2 id="关于系统升级">关于系统升级</h2><ul><li>看了以上的安装过程可以得知的一点是，<a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 是通过修改 <code>boot.img</code> 生效的，所以在升级系统的时候，只要让升级包里的 <code>boot.img</code> 被 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 修补一遍，再升级系统，就可以让 <a href="https://github.com/topjohnwu/Magisk/releases/latest">Magisk</a> 在升级系统后不失效</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;本文 PDF 版：&lt;a href=&quot;magisk01/magisk01.pdf&quot;&gt;magisk01.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Magisk 官方教程指路：&lt;a href=&quot;https://topjohnwu.github.io/Magisk/install.html&quot;&gt;</summary>
      
    
    
    
    
    <category term="Magisk" scheme="https://sekibetu.com/tags/Magisk/"/>
    
    <category term="Android" scheme="https://sekibetu.com/tags/Android/"/>
    
  </entry>
  
  <entry>
    <title>v2ray中DNS运作流程</title>
    <link href="https://sekibetu.com/v2ray01.html"/>
    <id>https://sekibetu.com/v2ray01.html</id>
    <published>2020-12-23T17:19:05.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>本文为摘选，仅作为备忘录使用</p><p>以以下路由配置为例</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br></pre></td><td class="code"><pre><span class="line"><span class="punctuation">&#123;</span></span><br><span class="line">  <span class="attr">&quot;dns&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;servers&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;8.8.8.8&quot;</span><span class="punctuation">,</span> <span class="string">&quot;localhost&quot;</span><span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;outbounds&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;protocol&quot;</span><span class="punctuation">:</span> <span class="string">&quot;vmess&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;vnext&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">          <span class="punctuation">&#123;</span></span><br><span class="line">            <span class="attr">&quot;users&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">              <span class="punctuation">&#123;</span></span><br><span class="line">                <span class="attr">&quot;id&quot;</span><span class="punctuation">:</span> <span class="string">&quot;xxx-x-x-x-xx-x-x-x-x&quot;</span></span><br><span class="line">              <span class="punctuation">&#125;</span></span><br><span class="line">            <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;address&quot;</span><span class="punctuation">:</span> <span class="string">&quot;1.2.3.4&quot;</span><span class="punctuation">,</span></span><br><span class="line">            <span class="attr">&quot;port&quot;</span><span class="punctuation">:</span> <span class="number">10086</span></span><br><span class="line">          <span class="punctuation">&#125;</span></span><br><span class="line">        <span class="punctuation">]</span></span><br><span class="line">      <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;streamSettings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;network&quot;</span><span class="punctuation">:</span> <span class="string">&quot;tcp&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;proxy&quot;</span></span><br><span class="line">    <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;tag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;protocol&quot;</span><span class="punctuation">:</span> <span class="string">&quot;freedom&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span><span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;inbounds&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">    <span class="punctuation">&#123;</span></span><br><span class="line">      <span class="attr">&quot;domainOverride&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;http&quot;</span><span class="punctuation">,</span> <span class="string">&quot;tls&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;port&quot;</span><span class="punctuation">:</span> <span class="number">1086</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;listen&quot;</span><span class="punctuation">:</span> <span class="string">&quot;127.0.0.1&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;protocol&quot;</span><span class="punctuation">:</span> <span class="string">&quot;socks&quot;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="attr">&quot;settings&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;auth&quot;</span><span class="punctuation">:</span> <span class="string">&quot;noauth&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;udp&quot;</span><span class="punctuation">:</span> <span class="literal"><span class="keyword">true</span></span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;ip&quot;</span><span class="punctuation">:</span> <span class="string">&quot;127.0.0.1&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">&#125;</span></span><br><span class="line">  <span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">  <span class="attr">&quot;routing&quot;</span><span class="punctuation">:</span> <span class="punctuation">&#123;</span></span><br><span class="line">    <span class="attr">&quot;domainStrategy&quot;</span><span class="punctuation">:</span> <span class="string">&quot;IPIfNonMatch&quot;</span><span class="punctuation">,</span></span><br><span class="line">    <span class="attr">&quot;rules&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;field&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;ip&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;8.8.8.8&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;outboundTag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;proxy&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span><span class="punctuation">,</span></span><br><span class="line">      <span class="punctuation">&#123;</span></span><br><span class="line">        <span class="attr">&quot;type&quot;</span><span class="punctuation">:</span> <span class="string">&quot;field&quot;</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;domain&quot;</span><span class="punctuation">:</span> <span class="punctuation">[</span><span class="string">&quot;geosite:cn&quot;</span><span class="punctuation">]</span><span class="punctuation">,</span></span><br><span class="line">        <span class="attr">&quot;outboundTag&quot;</span><span class="punctuation">:</span> <span class="string">&quot;direct&quot;</span></span><br><span class="line">      <span class="punctuation">&#125;</span></span><br><span class="line">    <span class="punctuation">]</span></span><br><span class="line">  <span class="punctuation">&#125;</span></span><br><span class="line"><span class="punctuation">&#125;</span></span><br></pre></td></tr></table></figure><p>内置 DNS 用 8.8.8.8 做首选服务器，localhost 作备用，路由中首先来一条规则让 8.8.8.8 的流量一定走 proxy，匹配了 geosite:cn 中的域名的请求走 direct，如果没匹配任何规则，则走主 outbound，也即 outbounds 中的第一个，也即 proxy。</p><p>同样设置系统代理至 V2Ray 的 SOCKS inbound 127.0.0.1:1086，再来考虑浏览器做请求的过程，经过上面几个例子，可以看到很多步骤其实是一样的，所以后续例子中会简化一些：</p><blockquote><p>S4</p><ol><li>假设浏览器请求 <a href="https://www.bilibili.com">https://www.bilibili.com</a></li><li>浏览器发 SOCKS 请求到 V2Ray</li><li>请求来到 V2Ray 的 inbound，再到路由过程</li><li>很明显 <a href="http://www.bilibili.com">www.bilibili.com</a> 这个域名包括在 geosite:cn 中，走 direct</li><li>Freedom outbound (direct) 对 <a href="http://www.bilibili.com">www.bilibili.com</a> 发起 TCP 连接</li><li>Freedom outbound 解析域名，因为这次没有用 UseIP，用的是系统 DNS</li><li>直接发 DNS 请求到 114.114.114.114</li><li>得到结果后可以跟 Bilibili 服务器建立连接，准备代理浏览器发过来的 HTTPS 流量</li></ol><p>S5</p><ol><li>再假设浏览器请求 <a href="https://www.google.com">https://www.google.com</a></li><li>浏览器发 SOCKS 请求到 V2Ray</li><li>请求来到 V2Ray 的 inbound，再到路由过程</li><li><a href="http://www.google.com">www.google.com</a> 不在 gesoite:cn，也没匹配任何规则，本来应该直接走主 outbound: proxy，但因为我们用了 IPIfNonMatch 策略，V2Ray 会去尝试使用内置的 DNS 把 <a href="http://www.google.com">www.google.com</a> 的 IP 解析出来</li><li>V2Ray 使用内置 DNS 向 8.8.8.8 发起针对 <a href="http://www.google.com">www.google.com</a> 的 DNS 请求，这个请求的流量将会是 UDP 流量</li><li>内置 DNS 发出的 DNS 请求会按路由规则走，因为 8.8.8.8 匹配了路由中的第一条规则，这个 DNS 请求的流量会走 proxy</li><li>proxy 向远端代理服务器发起 TCP 代理连接（因为 “network”: “tcp”）</li><li>建立起 TCP 连接后，proxy 向远端代理服务器发出 udp:8.8.8.8:53 这样的代理请求</li><li>远端服务器表示接受这个代理请求后，proxy 用建立好的 TCP 连接向远端服务器发送承载了 DNS 请求的 UDP 流量（所以 V2Ray/VMess 目前是 UDP over TCP）</li><li>远端代理服务器接收到这些承载 DNS 请求的 UDP 流量后，发送给最终目标 udp:8.8.8.8:53</li><li>8.8.8.8 返回给远端代理服务器 DNS 结果后，远端代理服务器原路返回至本地 V2Ray 的内置 DNS，至此，从步骤 5 ~ 11，整个 DNS 解析过程完成。</li><li>接上面步骤 4，V2Ray 得到 <a href="http://www.google.com">www.google.com</a> 的 IP，再进行一次规则匹配，很明显路由规则中没有相关的 IP 规则，所以还是没匹配到任何规则，最终还是走了主 outbound: proxy</li><li>proxy 向远端代理服务器发起 TCP 代理连接（因为 “network”: “tcp”）</li><li>连接建立后，因为 proxy 中所用的 VMess 协议可以像 SOCKS 那样把域名交给代理服务器处理，所以本地的 V2Ray 不需要自己解析 <a href="http://www.google.com">www.google.com</a>，把域名放进 VMess 协议的参数中一并交给代理服务器来处理</li><li>远端的 V2Ray 代理服务器收到这个代理请求后，它可能自己做域名解析，也可能继续交给下一级代理处理，只要后续代理都支持类 SOCKS 的域名处理方式，这个 DNS 请求就可以一推再推，推给最后一个代理服务器来处理，这个超出本文范围不作讨论，反正这个域名不需要我们本地去解析</li><li>远端代理服务器最后会发出针对 <a href="http://www.google.com">www.google.com</a> 的 DNS 请求（至于究竟是如何发，发到哪个 DNS 服务器，我们不一定能知道，也不关心这个）</li><li>远端代理服务器得到 DNS 结果后，可以真正地向 Google 的服务器建立 TCP 连接 18. 远端的 V2Ray 做好准备后告诉本地 V2Ray 连接建立好了，可以传数据了</li><li>本地 V2Ray 就告诉浏览器连接好了，可以传数据了，浏览器就可以把 HTTPS 流量顺着这个代理链发送至 Google 的服务器</li></ol></blockquote><p>在上面 S5 中，步骤 5 ~ 11 做了次 DNS 请求，采用代理转发 DNS 请求流量的方式，而在步骤 14 中，又说可以不解析域名，交给远端服务器来解析，这两者其实并不冲突。一般来说，前者的处理方式就是实实在在的 UDP 流量代理而已，后者一般叫作远程 DNS 解析。用了 <code>IPIfNonMatch</code> ，对域名做一次 DNS 解析要经过 5 ~ 11 这么多步骤，看起来效率很慢，但如果代理服务器不慢的话，这个过程一般是很快的，最重要的是 V2Ray 内置 DNS 对 DNS 结果有一个缓存，所以并不需要每次都去做 DNS 请求。不管怎么说，毕竟还是做了额外的事情，而且有可能涉及到一个 UDP over TCP 的代理请求，的确会相对地慢点。</p><h2 id="DNS-处理流程">DNS 处理流程</h2><p>若当前要查询的域名：</p><ul><li>命中了 <code>hosts</code> 中的「域名 - IP」、「域名 - IP 数组」映射，则将该 IP 或 IP 数组作为 DNS 解析结果返回。</li><li>命中了 <code>hosts</code> 中的「域名 - 域名」映射，则该映射的值（另一个域名）将作为当前要查询的新域名，进入 DNS 处理流程，直到解析出 IP 后返回，或返回空解析。</li><li>没有命中 <code>hosts</code>，但命中了某（几）个 DNS 服务器中的 <code>domains</code> 域名列表，则按照命中的规则的优先级，依次使用该规则对应的 DNS 服务器进行查询。若命中的 DNS 服务器查询失败，或 <code>expectIPs</code> 不匹配，则使用下一个命中的 DNS 服务器进行查询；否则返回解析得到的 IP。若所有命中的 DNS 服务器均查询失败，此时 DNS 组件：<ul><li>默认会进行 「DNS 回退（fallback）查询」：使用「上一轮失败查询中未被使用的、且 <code>skipFallback</code> 为默认值 <code>false</code> 的 DNS 服务器」依次查询。若查询失败，或 <code>expectIPs</code> 不匹配，返回空解析；否则返回解析得到的 IP。</li><li>若 <code>disableFallback</code> 设置为 <code>true</code>，则不会进行「DNS 回退（fallback）查询」。</li></ul></li><li>既没有命中 <code>hosts</code>，又没有命中 DNS 服务器中的 <code>domains</code> 域名列表，则：<ul><li>默认使用「<code>skipFallback</code> 为默认值 <code>false</code> 的 DNS 服务器」依次查询。若第一个被选中的 DNS 服务器查询失败，或 <code>expectIPs</code> 不匹配，则使用下一个被选中的 DNS 服务器进行查询；否则返回解析得到的 IP。若所有被选中的 DNS 服务器均查询失败，返回空解析。</li><li>若「<code>skipFallback</code> 为默认值 <code>false</code> 的 DNS 服务器」数量为 0 或 <code>disableFallback</code> 设置为 <code>true</code>，则使用 DNS 配置中的第一个 DNS 服务器进行查询。查询失败或不匹配 <code>expectIPs</code> 列表，返回空解析；否则返回解析得到的 IP。</li></ul></li></ul><h2 id="Reference">Reference</h2><p><a href="https://medium.com/@TachyonDevel/%E6%BC%AB%E8%B0%88%E5%90%84%E7%A7%8D%E9%BB%91%E7%A7%91%E6%8A%80%E5%BC%8F-dns-%E6%8A%80%E6%9C%AF%E5%9C%A8%E4%BB%A3%E7%90%86%E7%8E%AF%E5%A2%83%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-62c50e58cbd0">漫谈各种黑科技式 DNS 技术在代理环境中的应用(作者@TachyonDevel)</a></p><p><a href="https://www.v2fly.org/config/dns.html#%E6%94%AF%E6%8C%81%E7%9A%84-dns-%E5%8D%8F%E8%AE%AE%E5%8F%8A%E5%85%B6%E8%B7%AF%E7%94%B1%E7%AD%96%E7%95%A5">DNS 域名解析 | V2Fly.org</a></p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;本文为摘选，仅作为备忘录使用&lt;/p&gt;
&lt;p&gt;以以下路由配置为例&lt;/p&gt;
&lt;figure class=&quot;highlight json&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;spa</summary>
      
    
    
    
    
    <category term="v2ray" scheme="https://sekibetu.com/tags/v2ray/"/>
    
    <category term="DNS" scheme="https://sekibetu.com/tags/DNS/"/>
    
  </entry>
  
  <entry>
    <title>什么是Hash算法加盐</title>
    <link href="https://sekibetu.com/salt01.html"/>
    <id>https://sekibetu.com/salt01.html</id>
    <published>2020-12-16T12:15:08.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>以下是一个典型的 Hash 算法加盐思路：</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Hash算法(Hash算法(密码)+盐)</span><br></pre></td></tr></table></figure><p>1、使用慢 Hash 算法可以拖延破解时间【重要】</p><p>2、使用和 Hash 函数输出的字符串等长的盐值，比如 SHA256 算法的输出是 256bits(32 bytes)，那么盐值也至少应该是 32 个随机字节【重要】</p><p>3、使用随机盐还是固定盐，取决于程序是否被泄露，</p><p>一般认为，数据库是第一个被泄露的，那么随机盐是直接被拿走了，而嵌入于程序中的固定盐是安全的；</p><p>但是，能入侵到数据库的黑客一般程序也顺手可以拿走了，所以固定盐反而降低了后续彩虹表的建立时间，</p><p>所以使用随机盐虽然免不了随机盐、密码和算法一起被泄露，但能增加彩虹表攻击的成本(每一个盐都需要建立一个彩虹表，能增加一丢丢破解时间)</p><p>我认为默认使用随机盐是好事，但是有些特殊情况下使用固定盐反而能取胜</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;以下是一个典型的 Hash 算法加盐思路：&lt;/p&gt;
&lt;figure class=&quot;highlight plaintext&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre&gt;&lt;span class=&quot;line&quot;&gt;1&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;&lt;/t</summary>
      
    
    
    
    
    <category term="Hash" scheme="https://sekibetu.com/tags/Hash/"/>
    
    <category term="Salt" scheme="https://sekibetu.com/tags/Salt/"/>
    
  </entry>
  
  <entry>
    <title>个人使用过的git命令记录</title>
    <link href="https://sekibetu.com/git01.html"/>
    <id>https://sekibetu.com/git01.html</id>
    <published>2020-11-22T21:06:42.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<h3 id="经常忘记-git-命令，所以开始记录遇到过的命令，方便自己查阅">经常忘记 git 命令，所以开始记录遇到过的命令，方便自己查阅</h3><blockquote><p>git 是 snapshot 式保存手段(每一次 commit 都是完整的 snapshot)，但又偏向于增量式保存，举例：<br>现有以下两个文件已成为第一次 commit<br>A.txt<br>B.txt<br>那么 git 会将其分为若干个 git 对象，并将这些对象进行切割后压缩保存(delta)，<br>当我修改了 A.txt，再次 commit 时，<br>git 不会存储改动后的整个 A.txt，<br>而是存储一个指向 B.txt 的指针加上 A.txt 改动的部分，这些就是新增的 git 对象，git 接着将其按一定规则切割后压缩保存(delta)<br>总的来说，git 对象偏向于内容，而 delta 偏向于二进制分段压缩包，</p><p>每次 commit 的 delta 部分就像是彩虹六号 Y5S4 赛季这次更新的时候，游戏本体就 70G 左右，补丁却需要下载 60G，<br>因为彩虹六号把材质文件都封装进了 delta 文件，这类文件特别大，根目录下最大的单个材质包文件可达 28G，即使是改动了其中的一张图片，也需要整个重新下载,而 git 的包切得很小，可重复利用的 delta 文件多，每次 commit 就能省下不少空间</p><p>Total A (delta B), reused C (delta D) 中的 A、B、C、D 意思分别为</p><p>A、本次打包总计有 A 个 git 对象</p><p>[每个文件的每一次改动都会创造出一个新的内容级别的对象]，</p><p>B、从第一次 commit 以来的二进制分段压缩包级别的增量改动包 B 个</p><p>[与内容级别的对象不同点是将内容级别的对象按一定规则切割成分段压缩包]</p><p>C、有 C 个可重复使用的 git 对象</p><p>D、有 D 个二进制分段压缩包级别的增量改动包可重复使用而不需要重新打包</p></blockquote><p><code>git config --global user.name &quot;xxx&quot;</code> # 配置用户名<br><code>git config --global user.email &quot;xxx@xxx.com&quot;</code> # 配置邮箱<br><code>git config --global color.ui true</code> # git 命令自动着色<br><code>git config --global color.status auto</code><br><code>git config --global color.diff auto</code><br><code>git config --global color.branch auto</code><br><code>git config --global color.interactive auto</code></p><p><code>git config --global http.https://github.com.proxy socks5://127.0.0.1:2080</code> # 设置代理</p><p><code>git config --global --unset http.proxy</code> # 取消代理<br><code>git clone XXX.git</code> # clone 远程仓库<br><code>git status</code> # 查看当前改动<br><code>git add A</code> # 提交 A 文件至 index<br><code>git add .</code> # 提交所有文件更改<br><code>git commit -m 'xxx'</code> # 提交<br><code>git commit --amend -m 'xxx'</code> # 合并上一次提交（用于反复修改）<br><code>git commit -am 'xxx'</code> # 将 add 和 commit 合为一步<br><code>git rm xxx</code> # 删除 index 中的文件<br><code>git rm -r *</code> # 递归删除<br><code>git log -n</code> # 显示 n 行提交日志<br><code>git log --stat</code> # 显示提交日志及相关变动文件<br><code>git show dfb02e6e4f2f7b573337763e5c0013802e392818</code> # 显示某个提交的详细内容<br><code>git show dfb02</code> # 同上，可只用 commit ID 的前几位<br><code>git show HEAD</code> # 显示 HEAD 提交日志<br><code>git show HEAD^</code> # 显示 HEAD 的父（上一个版本）的提交日志 ^^为上两个版本 ^5 为上 5 个版本</p><p><code>git show main@{yesterday}</code> # 显示 main 分支昨天的状态</p><p><code>git tag</code> # 显示已存在的 tag<br><code>git tag -a v2.0 -m 'xxx'</code> # 增加 v2.0 的 tag<br><code>git show v2.0</code> # 显示 v2.0 的日志及详细内容<br><code>git log v2.0</code> # 显示 v2.0 的日志<br><code>git diff</code> # 显示所有未添加至 index 的变更<br><code>git diff --cached</code> # 显示所有已添加 index 但还未 commit 的变更<br><code>git diff HEAD^</code> # 比较与上一个版本的差异<br><code>git diff HEAD -- ./lib</code> # 比较与 HEAD 版本 lib 目录的差异<br><code>git diff origin/main main</code> # 比较远程分支 main 上有本地分支 main 上没有的<br><code>git diff origin/main main --stat</code> # 只显示差异的文件，不显示具体内容<br><code>git remote add origin XXX.git</code> # 增加远程定义（用于 push/pull/fetch）<br>​<code>git branch</code> # 显示本地分支<br>​<code>git branch --contains 50089</code> # 显示包含提交 50089 的分支<br>​<code>git branch -a</code> # 显示所有分支<br>​<code>git branch -r</code> # 显示所有原创分支<br>​<code>git branch --merged</code> # 显示所有已合并到当前分支的分支<br>​<code>git branch --no-merged</code> # 显示所有未合并到当前分支的分支<br>​<code>git branch -m main main_copy</code> # 本地分支改名<br>​<code>git checkout -b main_copy</code> # 从当前分支创建新分支 main_copy 并切换<br>​<code>git checkout -b main main_copy</code> # 上面的完整版<br>​<code>git checkout branch</code> # 切换已存在的 branch 分支<br>​<code>git checkout --track branch</code> # 切换远程分支 branch 并创建本地跟踪分支<br>​<code>git checkout v2.0</code> # 切换版本 v2.0<br>​<code>git checkout -b dev origin/dev</code> # 从远程分支 dev 创建新本地分支 dev 并切换<br>​<code>git checkout -- README</code> # 检出 head 版本的 README 文件（可用于修改错误回退）<br>​<code>git merge origin/main</code> # 合并远程 main 分支至当前分支<br>​<code>git cherry-pick ff44785404a8e</code> # 合并提交 ff44785404a8e 的修改<br>​<code>git push origin dev:main</code> # 将本地的 dev 分支 push 到远程的 main 分支</p><p><code>git push origin --delete branch</code> # 删除远程仓库的 branch 分支</p><p><code>git push origin :branch</code> # 同上<br>​<code>git push --tags</code> # 把所有 tag 推送到远程仓库<br>​<code>git fetch</code> # 获取所有远程分支（不更新本地分支，另需 merge）<br>​<code>git fetch --prune</code> # 获取所有原创分支并清除服务器上已删掉的分支</p><p><code>git --set-upstream-to=origin/main main</code> # 将 main 分支的远程分支设为 origin/main</p><p><code>git pull --rebase origin main</code> # rebase 式 pull 远程 origin 代码到本地 main 分支(需要与上一步结合确定 pull 哪个分支)</p><p><code>git pull origin main</code> # 获取远程 origin 的分支并 merge 到本地 main 分支<br>​<code>git mv README README2</code> # 重命名文件 README 为 README2<br>​<code>git reset --hard HEAD</code> # 将当前版本重置为 HEAD（通常用于 merge 失败回退）<br>​<code>git rebase main patch</code> # 换底，将 patch 分支的基准换成 main 分支<br>​<code>git branch -d branch</code> # 删除本地分支 branch（本分支修改已合并到其他分支）<br>​<code>git branch -D branch</code> # 强制删除本地分支 branch<br>​<code>git ls-files</code> # 列出 git index 包含的文件<br>​<code>git show-branch</code> # 图示当前分支历史<br>​<code>git show-branch --all</code> # 图示所有分支历史<br>​<code>git whatchanged</code> # 显示提交历史对应的文件修改<br>​<code>git revert dfb02e6e4f2f7b573337763e5c0013802e392818</code> # 撤销提交 dfb02e6e4f2f7b573337763e5c0013802e392818<br>​<code>git ls-tree HEAD</code> # 内部命令：显示某个 git 对象<br>​<code>git rev-parse v2.0</code> # 内部命令：显示某个 ref 对于的 SHA1 HASH<br>​<code>git reflog</code> # 显示所有提交，包括孤立节点</p><p><code>git log --pretty=format:'%h %s' --graph</code> # 图示提交日志<br><code>git stash</code> # 暂存当前修改，将所有文件置为 HEAD 状态<br><code>git stash list</code> # 查看所有暂存<br><code>git stash show -p stash@{0}</code> # 参考第一次暂存<br><code>git stash apply stash@{0}</code> # 应用第一次暂存<br><code>git grep &quot;delete from&quot;</code> # 文件中搜索文本“delete from”<br><code>git gc</code> # 清理不必要的文件并优化本地存储库</p><p><code>git rm -r -f --cached .</code> # 删除缓存区而不删除本地文件(可以配合.gitignore 使用)</p>]]></content>
    
    
      
      
    <summary type="html">&lt;h3 id=&quot;经常忘记-git-命令，所以开始记录遇到过的命令，方便自己查阅&quot;&gt;经常忘记 git 命令，所以开始记录遇到过的命令，方便自己查阅&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;git 是 snapshot 式保存手段(每一次 commit 都是完整的 snapshot</summary>
      
    
    
    
    
    <category term="git" scheme="https://sekibetu.com/tags/git/"/>
    
  </entry>
  
  <entry>
    <title>Docker笔记(自用)</title>
    <link href="https://sekibetu.com/docker01.html"/>
    <id>https://sekibetu.com/docker01.html</id>
    <published>2020-11-17T14:33:16.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>随手记点笔记，不全，自用</p><h1>Docker</h1><h2 id="基础命令">基础命令</h2><h3 id="服务相关命令">服务相关命令</h3><ul><li>systemctl start docker</li><li>systemctl stop docker</li><li>systemctl restart docker</li><li>systemctl status docker</li><li>systemctl enable docker 为 docker 服务设置开机自启</li></ul><h3 id="镜像相关命令">镜像相关命令</h3><ul><li>docker images 查看本地镜像</li><li>docker search 镜像名称 搜索镜像</li><li>docker pull 镜像名称:版本号 从 docker 仓库拉取某版本的镜像到本地</li><li>docker build 创建 dockerfile 镜像</li></ul><h3 id="容器相关命令">容器相关命令</h3><ul><li><p>docker ps -a 查看所有本地容器</p></li><li><p>举例：docker run -it --name=cl centos:7 /bin/bash 创建一个名为 cl 的 centos7 的容器并以 bash 这个 shell 进入交互式界面</p><ul><li>exit 可以退出容器但会使带-t 参数的交互式容器停止，所以要避免-t 参数的使用，但是可以使用^p^q 来退出而不结束容器</li></ul></li><li><p>docker run -id --name=cl centos:7 创建一个名为 cl 的 centos7 的容器在后台运行(守护式容器)</p></li><li><p>docker attach 容器名</p><ul><li>docker exec 容器名 用此命令进入容器，退出后容器不会停止</li></ul></li><li><p>docker start 容器名 重新启动已存在的容器</p></li><li><p>docker stop 容器名 关闭容器</p></li><li><p>删除所有容器的示例命令(慎用)：docker rm ‘docker ps -aq’</p></li><li><p>docker inspect 容器名 查看容器信息</p></li></ul><h2 id="数据卷-挂载">数据卷(挂载)</h2><h3 id="docker-run-…-v-宿主机目录-容器内目录-v-宿主机目录-容器内目录">docker run … -v 宿主机目录 : 容器内目录 -v 宿主机目录 : 容器内目录</h3><ul><li>目录必须是绝对路径</li><li>如果目录不存在会自动创建</li><li>可以挂载多个数据卷</li></ul><h3 id="数据卷容器">数据卷容器</h3><ul><li><p>使用方法</p><ul><li>name=A -v /volume</li><li>–volumes-from A</li><li>–volumes-from A</li><li>即使删除了 A，其余的数据卷也挂在于宿主机，不受影响</li></ul></li><li><p>作用</p><ul><li>容器数据持久化(数据隔离)</li><li>客户端和容器数据交换</li><li>容器间数据交换</li></ul></li></ul><h2 id="应用部署">应用部署</h2><h3 id="MySQL-示例">MySQL 示例</h3><ul><li>docker run -id \ 守护进程<br>-p 3307:3306 \ 映射端口为 3307 与宿主机通信<br>–name=mysql \ 镜像名<br>-v $PWD/conf:/etc/mysql/conf.d \ 挂载配置目录<br>-v $PWD/logs:/logs \ 挂载日志目录<br>-v $PWD/data:/var/lib/mysql \ 挂载数据目录<br>-e MYSQL_ROOT_PASSWORD=123456 \ 密码环境<br>mysql:5.6 镜像和版本</li></ul><h3 id="Tomcat-示例">Tomcat 示例</h3><ul><li>docker run -id --name=tomcat <br>-p 8080:8080 <br>-v $PWD:/usr/local/tomcat/webapps <br>tomcat</li></ul><h3 id="Nginx-示例">Nginx 示例</h3><ul><li>docker run -id --name=nginx <br>-p 80:80 <br>-v $PWD/conf/nginx.conf:/etc/nginx/nginx.conf <br>-v $PWD/logs:/var/log/nginx <br>-v $PWD/html:/usr/share/nginx/html <br>nginx</li></ul><h3 id="Redis-示例">Redis 示例</h3><ul><li>docker run -id --name=redis -p 6379:6379 redis</li><li>./redis-cli.exe -h 主机 IP -p 端口</li></ul><h2 id="Dockerfile">Dockerfile</h2><h3 id="结构">结构</h3><ul><li>Docker 镜像是由特殊的文件系统叠加而成，底层直接沿用宿主机的 bootfs</li><li>第二层为 root 文件系统 rootfs，称为 base image</li><li>可以再往上叠加其他镜像文件</li></ul><h3 id="制作镜像">制作镜像</h3><ul><li><p>容器转镜像</p><ul><li>docker commit 容器 id 镜像名称 : 版本号</li><li>docker save -o 压缩文件名称 镜像名称 : 版本号</li><li>docker load -i 压缩文件名称</li></ul></li><li><p>dockerfile</p></li></ul><h2 id="服务编排-Compose">服务编排 Compose</h2><h3 id="微服务需要部署多个实例，人工进行过于复杂">微服务需要部署多个实例，人工进行过于复杂</h3><h3 id="使用流程">使用流程</h3><ul><li>安装 docker-compose</li><li>编写 docker-compose.yml</li><li>docker-compose up -d 启动即可</li></ul><h2 id="私有仓库">私有仓库</h2><h3 id="搭建流程">搭建流程</h3><ul><li>docker pull registry</li><li>docker run -id --name=registry -p 宿主端口:容器端口 registry</li><li>访问服务器 IP:端口号/v2/_catlog，查看是否有输出{“repositories”:[]}</li><li>修改/etc/docker/daemon.json</li><li>添加{“insecure-registries”:[“服务器 IP:端口号”]}</li><li>重启 docker 服务 systemctl restart docker &amp;&amp; docker start registry</li></ul><h3 id="上传流程">上传流程</h3><ul><li>docker tag 镜像名:版本 服务器 IP:端口号/镜像名:版本</li><li>docker push 服务器 IP:端口号/镜像名:版本</li></ul><h3 id="拉取流程">拉取流程</h3><ul><li>docker pull 服务器 IP:端口号/镜像名:版本</li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;随手记点笔记，不全，自用&lt;/p&gt;
&lt;h1&gt;Docker&lt;/h1&gt;
&lt;h2 id=&quot;基础命令&quot;&gt;基础命令&lt;/h2&gt;
&lt;h3 id=&quot;服务相关命令&quot;&gt;服务相关命令&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;systemctl start docker&lt;/li&gt;
&lt;li&gt;systemctl s</summary>
      
    
    
    
    
    <category term="Docker" scheme="https://sekibetu.com/tags/Docker/"/>
    
  </entry>
  
  <entry>
    <title>Redis笔记02(自用)</title>
    <link href="https://sekibetu.com/redis02.html"/>
    <id>https://sekibetu.com/redis02.html</id>
    <published>2020-10-10T15:09:23.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>随手记点笔记，不全，自用</p><h2 id="删除策略">删除策略</h2><h3 id="定时删除">定时删除</h3><ul><li>定时删除，CPU 占用大</li></ul><h3 id="惰性删除">惰性删除</h3><ul><li>过期数据二次访问后才删除，内存占用大</li></ul><h3 id="定期删除">定期删除</h3><ul><li>随机抽查删除，hz 值决定了 CPU 和内存哪个占用大</li></ul><h3 id="淘汰策略">淘汰策略</h3><ul><li><p>内存不足时按策略删除</p><ul><li><p>maxmemory ?mb 最大可用内存，默认为 0 不限制，一般设置物理机的 50%以上</p></li><li><p>maxmemory-samples count 每次随机删除的数据个数</p></li><li><p>maxmemory-policy policy 删除策略</p><ul><li><p>volatile 易失数据</p><ul><li>volatile-lru 按最后一次使用时间</li><li>volatile-lfu 按最近使用次数</li><li>volatile-ttl 按即将过期的数据</li><li>volatile-random 随机</li></ul></li><li><p>allkeys 全库数据</p><ul><li>allkeys-lru 按最后一次使用时间</li><li>allkeys-lfu 按最近使用次数</li><li>allkeys-random 随机</li></ul></li><li><p>no-enviction 放弃数据驱逐</p></li></ul></li></ul></li></ul><h2 id="主从复制">主从复制</h2><h3 id="建立连接的流程">建立连接的流程</h3><ul><li>设置 master 地址和端口并保存</li><li>建立 socket 连接</li><li>发送 ping 命令(定时器任务)</li><li>身份验证</li><li>发送 slave 端口信息</li></ul><h3 id="数据同步">数据同步</h3><ul><li><p>全量复制</p><ul><li>发送指令 psync2 <runid> <offset></li><li>执行 bgsave</li><li>第一个 slave 连接时创建命令缓冲区</li><li>生成 RDB 文件通过 socket 发给 slave</li><li>接收 RDB，清空数据，执行恢复过程</li></ul></li><li><p>部分复制</p><ul><li>发送命令告知 RDB 已经恢复完成</li><li>发送复制缓冲区信息</li><li>接收信息，执行 bgrewriteaof，恢复数据</li></ul></li><li><p>心跳机制</p><ul><li><p>master 心跳</p><ul><li>内部指令 PING</li><li>周期 repl-ping-slave-period 默认 10 秒</li><li>INFO replication 获取 slave 最后一次连接时间间隔，lag 项维持在 0 或 1 视为正常</li></ul></li><li><p>slave 心跳</p><ul><li>内部指令 REPLCONF ACK {offset}</li><li>周期 1 秒</li><li>汇报 slave 自己的复制偏移量，获取最新的数据变更指令</li><li>判断 master 是否在线</li></ul></li></ul></li><li><p>注意事项</p><ul><li>master 数据同步应避开流量高峰期</li><li>复制缓冲区太小会导致数据溢出，出现数据丢失并自动进行二次全量复制，死循环 repl=backlog-size ?mb 建议留下 30%~50%的内存用于执行 bgsave 命令和创建复制缓冲区</li><li>避免 slave 同步过程服务器响应阻塞或者数据不同步，建议关闭此期间的对外服务 slave-serve-stale-data yes | no</li><li>数据同步阶段，master 主动发送命令给 slave，可以理解为是一个客户端</li><li>多个 slave 同时对 master 请求同步，RDB 只会有一份，但是带宽压力变大，可以适量错峰但是 RDB 会有多份</li><li>slave 过多可以采用树状结构，但是数据一致性差</li></ul></li></ul><h2 id="哨兵模式">哨兵模式</h2><h3 id="检测-master-是否宕机，master-宕机后选举-slave-为-master">检测 master 是否宕机，master 宕机后选举 slave 为 master</h3><h3 id="建立过程配置">建立过程配置</h3><ul><li>sentinel monitor master_name master_host master_port sentinel_number 设置监听的主服务器信息，sentinel_number 表示参与投票的哨兵数量</li><li>sentinel down-after-milliseconds master_name million_seconds 设置宕机时长，控制是否进行主从切换</li><li>sentinel failover-timeout master_name million_seconds 设置故障切换操作的最大超时时长</li><li>sentinel parallel-syncs master_name sync_slave_number 设置主从切换后，同时进行数据同步的 slave 数量，越大网络资源要求越高，越小同步时间越长</li></ul><h3 id="监控阶段">监控阶段</h3><ul><li>检查各个哨兵是否在线</li><li>先向 master 发 info 查询其信息和名下 slave</li><li>再向 slave 发 info 查询 slave 具体信息</li></ul><h3 id="故障转移阶段">故障转移阶段</h3><ul><li><p>单个哨兵监测到 master 无响应（主观下线） SRI_S_DOWN</p></li><li><p>半数哨兵监测到 master 无响应（客观下线） SRI_O_DOWN</p></li><li><p>哨兵选举</p></li><li><p>选举 master 优先级</p><ul><li><p>不在线的</p></li><li><p>响应慢的</p></li><li><p>与原来 master 断开连接时间长的</p></li><li><p>优先原则</p><ul><li>优先级</li><li>offset 偏移量大</li><li>runid</li></ul></li></ul></li></ul><h2 id="Cluster-集群">Cluster 集群</h2><h3 id="数据存储结构">数据存储结构</h3><ul><li><p>保存流程</p><ul><li>CRC(key)%16384 计算结果为某台服务器中的槽位地址，该槽位不止存储一个 key，而是大量 key</li></ul></li><li><p>查询流程</p><ul><li>各个数据库相互通信，保存各个库中槽位的编号数据</li><li>一次查询命中直接返回</li><li>一次未命中，告知具体的位置</li></ul></li></ul><h3 id="配置">配置</h3><ul><li>cluster-enabled yes|no 是否启用 cluster，加入 cluster 节点</li><li>cluster-config-file filename cluster 配置文件名，该文件会自动生成，尽量手动命名否则会共用</li><li>cluster-node-timeout milliseconds 节点服务响应超时时间</li><li>cluster-migration-barrier min_slave_number master 连接的 slave 最小数量</li></ul><h2 id="企业级解决方案">企业级解决方案</h2><h3 id="缓存预热">缓存预热</h3><ul><li>现象：启动服务器后立刻宕机</li><li>解决思路：系统启动前，提前将相关的缓存数据直接加载到缓存系统。避免在用户请求的时候，先查询数据库，然后再将数据缓存的问题！用户直接查询事先被预热的缓存数据！</li></ul><h3 id="缓存雪崩">缓存雪崩</h3><ul><li><p>现象：短时间范围内，大量 key 集中过期导致一系列宕机</p></li><li><p>解决思路</p><ul><li>更多的页面静态化处理</li><li>构建多级缓存架构<br>Nginx 缓存+redis 缓存+ehcache 缓存</li><li>检测 Mysql 严重耗时业务进行优化<br>对数据库的瓶颈排查：例如超时查询、耗时较高事务等</li><li>预警机制</li><li>限流、降级</li></ul></li><li><p>具体解决方案</p><ul><li>切换为 LFU 淘汰策略</li><li>调整过期的时间，使其错峰</li><li>超热数据暂时使用永久 key</li><li>定期维护（自动+人工）<br>对即将过期数据做访问量分析，确认是否延时，配合访问量统计，做热点数据的延时</li><li>加锁：慎用！</li></ul></li></ul><h3 id="缓存击穿">缓存击穿</h3><ul><li><p>现象：Redis 中某个高热点 key 过期，该 key 访问量巨大</p></li><li><p>解决方案</p><ul><li>增加热点 key 的时间</li><li>设置热点 key 为永久</li><li>高峰期来临前自动刷新有效期</li><li>二级缓存，设置不同的过期时间错峰</li><li>分布式锁</li></ul></li></ul><h3 id="缓存穿透">缓存穿透</h3><ul><li><p>现象：黑客大量访问不存在的数据，跳过 redis 直接攻击数据库</p></li><li><p>解决方案</p><ul><li>1、对查询结果为 null 的数据进行缓存（长期使用，定期清理），设定短时限，例如 30-60 秒，最高 5 分钟</li><li>2、白名单策略<br>提前预热各种分类数据 id 对应的 bitmaps，id 作为 bitmaps 的 offset，相当于设置了数据白名单。当加载正常数据时放行，加载异常数据时直接拦截（效率偏低）<br>使用布隆过滤器（有关布隆过滤器的命中问题对当前状况可以忽略）</li><li>3、实时监控 redis 命中率，提前预防，使用黑名单进行防控</li><li>4、key 加密<br>问题出现后，临时启动防灾业务 key，对 key 进行业务层传输加密服务，设定校验程序，过来的 key 校验<br>​ 例如每天随机分配 60 个加密串，挑选 2 到 3 个，混淆到页面数据 id 中，发现访问 key 不满足规则，驳回数据访问</li></ul></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;随手记点笔记，不全，自用&lt;/p&gt;
&lt;h2 id=&quot;删除策略&quot;&gt;删除策略&lt;/h2&gt;
&lt;h3 id=&quot;定时删除&quot;&gt;定时删除&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;定时删除，CPU 占用大&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;惰性删除&quot;&gt;惰性删除&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;过期数据二次</summary>
      
    
    
    
    
    <category term="Redis" scheme="https://sekibetu.com/tags/Redis/"/>
    
  </entry>
  
  <entry>
    <title>MyBatis如何获取刚刚插入数据的ID</title>
    <link href="https://sekibetu.com/mybatis01.html"/>
    <id>https://sekibetu.com/mybatis01.html</id>
    <published>2020-09-04T06:34:25.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>​ 有时业务逻辑中需要获取刚刚插入的数据的自增 ID 值以用于后续使用，MyBatis 提供了 LAST_INSERT_ID() 函数获取该 ID 值：</p><figure class="highlight xml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">mapper</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">insert</span> <span class="attr">id</span>=<span class="string">&quot;add&quot;</span> <span class="attr">parameterType</span>=<span class="string">&quot;pojo&quot;</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="comment">&lt;!--insert操作结束后查询最后一条插入的数据的ID值并将其赋值给pojo对象中的id属性--&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">selectKey</span> <span class="attr">resultType</span>=<span class="string">&quot;java.lang.Integer&quot;</span> <span class="attr">order</span>=<span class="string">&quot;AFTER&quot;</span> <span class="attr">keyProperty</span>=<span class="string">&quot;id&quot;</span>&gt;</span></span><br><span class="line">            select LAST_INSERT_ID()</span><br><span class="line">        <span class="tag">&lt;/<span class="name">selectKey</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        insert into table(items) values(#&#123;items&#125;)</span><br><span class="line">    <span class="tag">&lt;/<span class="name">insert</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">mapper</span>&gt;</span></span><br></pre></td></tr></table></figure>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;​ 有时业务逻辑中需要获取刚刚插入的数据的自增 ID 值以用于后续使用，MyBatis 提供了 LAST_INSERT_ID() 函数获取该 ID 值：&lt;/p&gt;
&lt;figure class=&quot;highlight xml&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutt</summary>
      
    
    
    
    
    <category term="MyBatis" scheme="https://sekibetu.com/tags/MyBatis/"/>
    
  </entry>
  
  <entry>
    <title>Redis笔记(自用)</title>
    <link href="https://sekibetu.com/redis01.html"/>
    <id>https://sekibetu.com/redis01.html</id>
    <published>2020-08-01T07:24:34.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Redis">Redis</h2><p>Redis: <strong>Re</strong>mote <strong>Di</strong>ctionary <strong>S</strong>erver</p><p>三个特点:</p><ul><li>Redis 支持数据持久化. 可以将内存中的数据保持在磁盘中, 重启后可再次使用</li><li>Redis 支持 <code>key-val</code>, <code>list</code>, <code>set</code>, <code>zset</code>, <code>hash</code> 等数据结构存储</li><li>Redis 支持数据备份, master-slave 模式数据备份</li></ul><p><strong>零碎基础知识</strong></p><ol><li>单进程 (*) 单进程处理客户端的请求, 对读写事件响应是通过 <code>epoll</code> 函数而包装来操作. Redis 实际处理速度完全依靠主进程执行效率</li><li>默认 <code>16</code> 个数据库, 类似数组下标从 <code>0</code> 开始, 初始默认使用 <code>0</code> 号库</li><li><code>select</code> 切换数据库</li><li><code>dbsize</code> 查看当前数据库的 <code>key</code> 的数量</li><li><code>flushdb</code> 清空当前数据库</li><li><code>flushall</code> 删全部库</li><li>统一密码管理, <code>16</code> 个库同一个密码</li><li>Redis 索引是从 <code>0</code> 开始</li><li>默认端口 <code>6379</code></li></ol><h2 id="Redis-数据类型">Redis 数据类型</h2><h3 id="五大数据类型">五大数据类型</h3><ol><li>String (字符串)</li><li>Hash (哈希, 类似 Java HashMap)</li><li>List (列表)</li><li>Set (集合)</li><li>Zset (Sorted Set: 有序集合)</li></ol><p><strong>String (字符串)</strong></p><ol><li>一个 <code>key</code> 对应一个 <code>value</code></li><li>二进制安全. 可以包含任何数据, 包括图片或者序列化对象</li><li><code>value</code> 最多可以是 512M</li></ol><p><strong>Hash</strong></p><ol><li>string 类型的 <code>field</code> 和 <code>value</code> 的映射表</li></ol><p><strong>List (列表)</strong></p><ol><li>底层是一个<strong>链表</strong></li><li>按照插入顺序排序, 可以在头部或者尾部插入数据</li></ol><p><strong>Set</strong></p><ol><li>string 类型的无序集合, 是通过 HashTable 实现的</li></ol><p><strong>Zset (Sorted Set)</strong></p><ol><li>string 类型的集合</li><li>与 Set 不同的是: 每个元素都会关联一个 double 类型的分数</li><li>Redis 通过分数来为集合中的成员进行从小到大排序</li><li>zset 成员唯一, 但是分数 (score) 可以重复!</li></ol><h3 id="Redis-键-key">Redis 键 (key)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">key *</span><br><span class="line"></span><br><span class="line"># 判断某个 key 是否存在</span><br><span class="line">exists key</span><br><span class="line"></span><br><span class="line"># 将 key 移动到另一个库</span><br><span class="line">move key db</span><br><span class="line"></span><br><span class="line"># 给 key 设置过期时间</span><br><span class="line">expire key</span><br><span class="line"></span><br><span class="line"># 查看还有多长时间 key 过期, -1 表示永不过期, -2 表示已经过期</span><br><span class="line">ttl key</span><br><span class="line"></span><br><span class="line"># 移除key的过期时间，即设置回永不过期</span><br><span class="line">persist key</span><br><span class="line"></span><br><span class="line"># 查看 key 是什么类型</span><br><span class="line">type key</span><br><span class="line"></span><br><span class="line">get k1</span><br><span class="line"></span><br><span class="line"># 有对应的键值, 覆盖 value</span><br><span class="line">set k1 v1</span><br><span class="line"></span><br><span class="line"># 删除 key</span><br><span class="line">del key</span><br></pre></td></tr></table></figure><h3 id="Redis-字符串-String">Redis 字符串 (String)</h3><p>单值单 value</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">set / get / del / append / strlen</span><br><span class="line">incr / decr / incrby / decrby</span><br><span class="line"></span><br><span class="line"># 获取指定区间范围的值</span><br><span class="line">getrange key 0 -1</span><br><span class="line"></span><br><span class="line"># 范围内设置值 (结果 key 对应的 value 以 &#x27;xxx&#x27;开头)</span><br><span class="line">setrange key 0 xxx</span><br><span class="line"></span><br><span class="line"># 设置过期时间</span><br><span class="line">setex</span><br><span class="line"></span><br><span class="line"># set if not exist</span><br><span class="line">setnx</span><br><span class="line"></span><br><span class="line"># 设置 / 获取 多个键值对</span><br><span class="line">mset / mget / msetnx</span><br></pre></td></tr></table></figure><h3 id="Redis-列表-List">Redis 列表 (List)</h3><p>单值多 value</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">lpush / rpush / lrange</span><br><span class="line"></span><br><span class="line">lpop / rpop</span><br><span class="line"></span><br><span class="line"># 按照索引下标获得元素 (从上到下)</span><br><span class="line">lindex</span><br><span class="line"></span><br><span class="line">llen</span><br><span class="line"></span><br><span class="line"># 删除 n 个 val</span><br><span class="line">lrem key n val</span><br><span class="line"></span><br><span class="line"># 截取指定范围的值然后再赋值给 key</span><br><span class="line">ltrim key index1 index 2</span><br><span class="line"></span><br><span class="line"># 源列表 -&gt; 目标列表</span><br><span class="line">rpoplpush list1 list2</span><br><span class="line"></span><br><span class="line">lset key index value</span><br><span class="line"></span><br><span class="line">linsert key before/after val1 val2</span><br></pre></td></tr></table></figure><p>性能总结</p><ol><li>是一个字符串链表, left, right 都可以插入添加</li><li>如果键不存在, 创建新的链表</li><li>如果键已存在, 新增内容</li><li>如果值完全移除, 对应的键也就消失了</li><li>链表操作头尾效率很高, 中间元素效率不高</li></ol><h3 id="Redis-集合-Set">Redis 集合 (Set)</h3><p>单值多 value</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">sadd / smembers / sismembers</span><br><span class="line"></span><br><span class="line"># 获取集合里元素个数</span><br><span class="line">scard</span><br><span class="line"></span><br><span class="line"># 删除集合中元素</span><br><span class="line">srem key value</span><br><span class="line"></span><br><span class="line">srandmember key 某个整数</span><br><span class="line"></span><br><span class="line"># 随机 pop 元素</span><br><span class="line">spop key</span><br><span class="line"></span><br><span class="line"># 将 key1 里的某个值赋值给 key2</span><br><span class="line">smove set01 set02 5</span><br><span class="line"></span><br><span class="line"># 差集 / 交集 / 并集</span><br><span class="line">sdiff / sinter / sunion</span><br></pre></td></tr></table></figure><h3 id="Redis-哈希-Hash">Redis 哈希 (Hash)</h3><p>KV 模式不变, 但 V 是一个键值对</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">hset / hget / hmset / hmget / hgetall / hdel</span><br><span class="line"></span><br><span class="line">hlen</span><br><span class="line"></span><br><span class="line"># 在 key 里面的某个值的 key</span><br><span class="line">hexists key</span><br><span class="line"></span><br><span class="line">hkeys / hvals</span><br><span class="line"></span><br><span class="line">hincrby / hincrbyfloat</span><br><span class="line"></span><br><span class="line">hsetnx</span><br></pre></td></tr></table></figure><h3 id="Redis-有序集合-Zset">Redis 有序集合 (Zset)</h3><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">zadd / zrange (withscores)</span><br><span class="line"></span><br><span class="line"># 开始 score1 结束 score2</span><br><span class="line">zrangebyscore key score1 score2</span><br><span class="line">withscore</span><br><span class="line">&#x27;(&#x27; 不包含</span><br><span class="line">limit 开始下标步, 多少步</span><br><span class="line"></span><br><span class="line"># 删除元素</span><br><span class="line">zrem key 某 score 下对应的 value</span><br><span class="line"></span><br><span class="line">zcard / zcount key &lt;score_range&gt; / zrank key values</span><br></pre></td></tr></table></figure><h2 id="Reference">Reference</h2><ol><li><p><a href="https://zhenye-na.github.io/2019/08/29/redis-cheatsheet.html#redis-%E4%BA%8B%E5%8A%A1">https://zhenye-na.github.io/2019/08/29/redis-cheatsheet.html#redis-%E4%BA%8B%E5%8A%A1</a></p></li><li><p><a href="https://github.com/LeCoupa/awesome-cheatsheets/blob/master/databases/redis.sh">https://github.com/LeCoupa/awesome-cheatsheets/blob/master/databases/redis.sh</a></p></li></ol>]]></content>
    
    
      
      
    <summary type="html">&lt;h2 id=&quot;Redis&quot;&gt;Redis&lt;/h2&gt;
&lt;p&gt;Redis: &lt;strong&gt;Re&lt;/strong&gt;mote &lt;strong&gt;Di&lt;/strong&gt;ctionary &lt;strong&gt;S&lt;/strong&gt;erver&lt;/p&gt;
&lt;p&gt;三个特点:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Re</summary>
      
    
    
    
    
    <category term="Redis" scheme="https://sekibetu.com/tags/Redis/"/>
    
  </entry>
  
  <entry>
    <title>MySQL事物隔离级别笔记</title>
    <link href="https://sekibetu.com/mysql01.html"/>
    <id>https://sekibetu.com/mysql01.html</id>
    <published>2020-07-18T06:11:17.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<table><thead><tr><th style="text-align:center">隔离级别</th><th style="text-align:center">脏读（Dirty Read）</th><th style="text-align:center">不可重复读（NonRepeatable Read）</th><th style="text-align:center">幻读（Phantom Read）</th></tr></thead><tbody><tr><td style="text-align:center">未提交读（Read uncommitted）</td><td style="text-align:center">yes</td><td style="text-align:center">yes</td><td style="text-align:center">yes</td></tr><tr><td style="text-align:center">已提交读（Read committed）</td><td style="text-align:center">no</td><td style="text-align:center">yes</td><td style="text-align:center">yes</td></tr><tr><td style="text-align:center">可重复读（Repeatable read）</td><td style="text-align:center">no</td><td style="text-align:center">no</td><td style="text-align:center">yes</td></tr><tr><td style="text-align:center">可串行化（Serializable ）</td><td style="text-align:center">no</td><td style="text-align:center">no</td><td style="text-align:center">no</td></tr></tbody></table><ul><li><p>未提交读(Read uncommitted)：能读取到别的事务未提交的数据</p></li><li><p>已提交读(Read committed)：只能读取到别的事务已经提交的数据</p></li><li><p>可重复读(Repeatable)：在读取数据后直接加锁，其他事务无法修改和删除这些数据，但是防不住 insert 的新数据</p></li><li><p>可串行化(Serializable)：读取用读取锁，写入用写入锁，这两个锁互斥，这样能保证数据绝对安全，但是性能低下</p></li><li><p>脏读(Dirty Read)：可以读取到未提交的数据</p></li><li><p><strong>不可重复读(NonRepeatable Read)</strong>：在读取完数据后数据又修改并 commit 了，导致第二次读取的数据与第一次数据不一致(重点在修改数据)</p></li><li><p>幻读(Phantom Read)：两次读取期间有新数据加入或者旧数据删除，导致不一致(重点在增删数据)</p></li></ul>]]></content>
    
    
      
      
    <summary type="html">&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style=&quot;text-align:center&quot;&gt;隔离级别&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;&gt;脏读（Dirty Read）&lt;/th&gt;
&lt;th style=&quot;text-align:center&quot;</summary>
      
    
    
    
    
    <category term="MySQL" scheme="https://sekibetu.com/tags/MySQL/"/>
    
  </entry>
  
  <entry>
    <title>记一次反编译PyInstaller打包的可执行文件获得其Python源码的过程</title>
    <link href="https://sekibetu.com/pydecompile.html"/>
    <id>https://sekibetu.com/pydecompile.html</id>
    <published>2020-05-19T06:32:20.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>笔者因为一些原因，需要反编译别人打包好的 Python3 写的 exe 程序获得其源码，但是本人对于 Python 的反编译是一窍不通的，于是在十分钟的谷歌学习后，这篇文章诞生了</p><h2 id="第一步">第一步</h2><p>首先，我们安装完 python 并且配置好环境变量后，去下载 <a href="http://pyinstxtractor.py">pyinstxtractor.py</a> 这个工具，他能把 PyInstaller 打包的 exe 文件里包含的依赖库和已编译好的.pyd 或者.pyc 字节码文件给“解压”出来，这其中，.pyd 文件的反编译特别复杂（因为.pyd 其实是已经编译成.c 后封装成类似.dll 的东西了，根本看不出 Python 的源码了），技术力不足的我这部分无能为力，本次讲的是.pyc 的反编译。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python pyinstxtractor.py Test.exe</span><br></pre></td></tr></table></figure><p>运行工具“解压”完成后，</p><p><img src="pydecompile/1.jpg" alt=""></p><p>我们看到目录中生成了一个文件夹：</p><p><img src="pydecompile/2.jpg" alt=""></p><p>图中的 Test.exe_extracted 文件夹便是 Test.exe 文件被“解压”后的结果，然后我们找到类型为.pyc 的字节码文件（或者如下图所示的类型为文件的文件）</p><p><img src="pydecompile/3.jpg" alt=""></p><p>然后把他们改为后缀名为.pyc 的字节码文件（因为上述工具解压过程无法识别这些二进制的文件所以没有自动改后缀）</p><p>【这里剧透下：其实是因为这些字节码文件标头的幻数被人删除了】</p><h2 id="第二步">第二步</h2><p>接着，我们开始对上述“解压”出来的已编译的.pyc 字节码文件进行反编译</p><p>首先，pip 安装 uncompyle6：<a href="https://pypi.org/project/uncompyle6/">https://pypi.org/project/uncompyle6/</a></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install uncompyle6</span><br></pre></td></tr></table></figure><p>然后试着直接使用一次：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">uncompyle6 Test.pyc</span><br></pre></td></tr></table></figure><p><img src="pydecompile/4.jpg" alt=""></p><p>然后我们发现，提示的是“导入错误：Test.pyc 中有无法识别的幻数 227”</p><p>这个 227 其实是十六进制的数字，我们用 WinHex 打开 Test.pyc 查看一下：</p><p><img src="pydecompile/5.jpg" alt=""></p><p>我们发现，并没有什么特征，我们继续把同目录的 struct 文件打开看一下：</p><p><img src="pydecompile/6.jpg" alt=""></p><p>我们发现，这里也有一个“E3”，而十六进制的 E3 恰好就是 227，诶，我们发现，幻数 227 是错误的，说明，在这个 E3 前面，本来应该有一个正确的幻数，在编译成.pyc 字节码文件的过程中，可能被人篡改或者删除了，而我这个情况是被人删除了，那我们手动插入这个数字进去试试：</p><p><img src="pydecompile/7.jpg" alt=""></p><p><img src="pydecompile/8.jpg" alt=""></p><p><img src="pydecompile/9.jpg" alt=""></p><p><img src="pydecompile/10.jpg" alt=""></p><p><img src="pydecompile/11.jpg" alt=""></p><p>然后我们再试一次反编译：</p><p><img src="pydecompile/12.jpg" alt=""></p><p>提示成功，源码也显示了出来，查看不方便的话可以这样写：</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">uncompyle6 Test.pyc &gt; Test.py</span><br></pre></td></tr></table></figure><p><img src="pydecompile/13.jpg" alt=""></p><p><a href="http://xn--6oqx3ebybw4oqxa21l7tf2xosa8640awrgdjbz56dvx4b8vm.py">这样根目录就会出现反编译完成的.py</a> 源码文件了</p><p><img src="pydecompile/14.jpg" alt=""></p><h1>后记</h1><p>新版本的 <a href="http://pyinstxtractor.py">pyinstxtractor.py</a> 已经增加了自动补全 python 版本幻数的功能了：</p><p><a href="https://github.com/extremecoders-re/pyinstxtractor">https://github.com/extremecoders-re/pyinstxtractor</a></p><h2 id="批量反编译">批量反编译</h2><p>笔者又在 github 上找到了一个批量反编译.pyc 字节码文件的脚本：</p><p><a href="https://github.com/jazlopez/py-recursive-uncompyle6">https://github.com/jazlopez/py-recursive-uncompyle6</a></p><p>这个脚本会自动搜索自身所在的目录及其子目录下的所有.pyc 字节码文件，然后通过安装好的 uncompyle6 进行反编译，不足之处是，<a href="http://xn--6oq67iba8isht65b71l822b8dqfa7596aga.py">反编译后只会把反编译完的.py</a> 源码文件扔在原文件旁，而不是另建文件夹储存。</p><p>不过，我们可以修改这个脚本中的 uncompyle_to 参数来指定输出文件夹</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">uncompyle_to = os.path.join(parent, i[<span class="string">&quot;dirname&quot;</span>], i[<span class="string">&quot;name&quot;</span>])</span><br></pre></td></tr></table></figure><p>因为笔者没有这个需求，所以这个代码逻辑的修改就留给读者你了，改完记得去给原项目 PR 哦</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;笔者因为一些原因，需要反编译别人打包好的 Python3 写的 exe 程序获得其源码，但是本人对于 Python 的反编译是一窍不通的，于是在十分钟的谷歌学习后，这篇文章诞生了&lt;/p&gt;
&lt;h2 id=&quot;第一步&quot;&gt;第一步&lt;/h2&gt;
&lt;p&gt;首先，我们安装完 python 并且</summary>
      
    
    
    
    
    <category term="Python3" scheme="https://sekibetu.com/tags/Python3/"/>
    
    <category term="反编译" scheme="https://sekibetu.com/tags/%E5%8F%8D%E7%BC%96%E8%AF%91/"/>
    
  </entry>
  
  <entry>
    <title>记一次拿到光猫超管账号改路由为桥接的过程</title>
    <link href="https://sekibetu.com/gmqj.html"/>
    <id>https://sekibetu.com/gmqj.html</id>
    <published>2020-05-09T01:11:01.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>​ 大家都知道，电信的光猫一般性能都比较差，在实现了光电转换功能的同时，默认的路由模式会让光猫背负起本来是路由器在干的拨号上网功能，笔者最近发现家里的网时不时会断流一秒，导致玩彩虹六号卡卡的，就想着如何改桥接，先是在网上搜到了通用的超级管理员密码 telecomadmin nE7jA%5m，但试了下发现是错误的，并且网上那种固定端口获取 dump 文件的方法也不适用于我的光猫，于是拨打客服电话问了问，客服也不愿意说，就只能自己动手了</p><p>​ 以下是全过程记录：</p><h2 id="第一步">第一步</h2><p>​ 首先，安装抓包软件 Fiddler Classic，然后准备好一个 fat32 格式的 U 盘，并在里面新建一个文件夹</p><p><img src="gmqj/1.jpg" alt=""></p><p>然后插到光猫上，浏览器输入 192.168.1.1 进入天翼网关</p><p>输入光猫背后贴的用户账号密码，就是 useradmin 那个</p><p>然后进入存储管理，我们发现，U 盘被识别出来了</p><p><img src="S:/hexo/source/_posts/2.jpg" alt=""></p><p>这时我们启动 fidder，然后选择下图所示的事前断点</p><p><img src="gmqj/3.jpg" alt=""></p><p>然后手动去点击文件夹目录，你会发现，点不动，点不动就对了</p><p>这时去寻找到 cgi-bin/luci/admin/storage/openFolder 这条 URL</p><p>然后我们把其中的 U 盘路径改成斜杠，就是进入光猫根目录的意思</p><p><img src="gmqj/4.jpg" alt=""></p><p>最后点击 Run to Completion，执行完毕</p><p>再把断点给关了</p><p><img src="gmqj/5.jpg" alt=""></p><p>你会发现，我们已经进入到了光猫的根目录（如果没进去，刷新下页面，应该是登录信息过期了，整个过程再做一遍，手速要快点）</p><p><img src="gmqj/6.jpg" alt=""></p><p>接着我们把这个路径下的文件复制出来到你的 U 盘里</p><p><img src="gmqj/7.jpg" alt=""></p><p><img src="S:/hexo/source/_posts/8.jpg" alt=""></p><p>这时候就可以把 U 盘拔了插电脑上了</p><h2 id="第二步">第二步</h2><p>​ 拿到设置文件后，我们发现，表面是 xml 格式，但是实际是加密过的二进制文件，这里引用下 52 破解一个大佬的解码猜测过程</p><p><a href="https://www.52pojie.cn/thread-1005978-1-1.html">https://www.52pojie.cn/thread-1005978-1-1.html</a></p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line">function UnZipCofing(Fname: string): string;</span><br><span class="line">var</span><br><span class="line">  ds: TDecompressionStream;</span><br><span class="line">  ms, fs, tmpfs: TMemoryStream;</span><br><span class="line">  ss: TStringStream;</span><br><span class="line">  bufferSize, blockSize, nextOff: LongWord;</span><br><span class="line">begin</span><br><span class="line">  fs := TMemoryStream.Create;</span><br><span class="line">  tmpfs := TMemoryStream.Create;</span><br><span class="line">  ms := TMemoryStream.Create;</span><br><span class="line">  ss := TStringStream.Create(&#x27;&#x27;);</span><br><span class="line">  if not FileExists(Fname) then</span><br><span class="line">  begin</span><br><span class="line">    ShowMessage(&#x27;文件不存在！&#x27;);</span><br><span class="line">    exit;</span><br><span class="line">  end;</span><br><span class="line">  try</span><br><span class="line">    fs.LoadFromFile(Fname);</span><br><span class="line">    nextOff := 60;</span><br><span class="line">    while nextOff &gt; 0 do</span><br><span class="line">    begin</span><br><span class="line">      fs.Seek(nextOff, soFromBeginning);</span><br><span class="line">  //读取缓冲区大小</span><br><span class="line">      fs.Read(bufferSize, SizeOf(bufferSize));</span><br><span class="line">      bufferSize := Swap32(bufferSize);</span><br><span class="line">  //读取压缩块大小</span><br><span class="line">      fs.Read(blockSize, SizeOf(blockSize));</span><br><span class="line">      blockSize := Swap32(blockSize);</span><br><span class="line">  //读取下一块位置</span><br><span class="line">      fs.Read(nextOff, SizeOf(nextOff));</span><br><span class="line">      nextOff := Swap32(nextOff);</span><br><span class="line">      //复制压缩数据块到临时数据流</span><br><span class="line">      tmpfs.Clear;</span><br><span class="line">      tmpfs.CopyFrom(fs, blockSize);</span><br><span class="line">      tmpfs.Position := 0;</span><br><span class="line">      //解压数据块</span><br><span class="line">      ds := TDecompressionStream.Create(tmpfs);</span><br><span class="line">      ms.SetSize(bufferSize);</span><br><span class="line">      ZeroMemory(ms.Memory, bufferSize);</span><br><span class="line">      ms.Position := 0;</span><br><span class="line">      ds.Read(ms.Memory^, bufferSize);</span><br><span class="line">      //将解压后的数据流复制到字符串数据流</span><br><span class="line">      ss.CopyFrom(ms, 0);</span><br><span class="line">      ds.Free;</span><br><span class="line">    end;&#123;end while&#125;</span><br><span class="line">    //输出合并后的字符串流。</span><br><span class="line">    Result := ss.DataString;</span><br><span class="line">  finally</span><br><span class="line">    //垃圾回收</span><br><span class="line">    fs.Free;</span><br><span class="line">    tmpfs.Free;</span><br><span class="line">    ms.Free;</span><br><span class="line">    ss.Free;</span><br><span class="line">  end;</span><br><span class="line">end;</span><br></pre></td></tr></table></figure><p>鉴于 delphi 太冷门了，没有学习价值，所以可以选择直接下载现成的工具 RouterPassView（软件有壳，杀软会误报）</p><p><a href="https://www.nirsoft.net/utils/router_password_recovery.html">https://www.nirsoft.net/utils/router_password_recovery.html</a></p><p>解密出来之后我们搜索到如下的字段</p><p><img src="S:/hexo/source/_posts/9.jpg" alt=""></p><p>光猫管理员的账号密码也就出来了</p><p>登录之后我们发现，wow，界面都变了，直接迅速找到网络设置，业务类型是上网的那个连接，我们在超管的情况下只能看到拨号上网的账号，密码可以用到网上营业厅的宽带密码服务去重置或者修改，按道理装完宽带给的回执也会记录你的账号密码</p><p>然后路由改成桥接，其他默认配置建议小白不要碰</p><p><img src="gmqj/10.jpg" alt=""></p><p>这里的 QoS 模块也可以顺手设置一下（注意，此处的 QoS 是用来控制你上网流量、电话和 IPTV 流量的优先级的）</p><p><img src="gmqj/11.jpg" alt=""></p><p>然后，我们到路由器上，直接把以前的自动获取 IP 模式换成拨号上网模式（路由器设置地址和界面大家都不一样，发挥主观能动性，找到类似的设置即可，我这边路由器是浏览器输入 192.168.0.1 进入，别的路由器可以找说明书有说如何进入）</p><p><img src="gmqj/12.jpg" alt=""></p><p>然后我们拿国人开发的小工具</p><p><a href="https://github.com/HMBSbige/NatTypeTester/releases">https://github.com/HMBSbige/NatTypeTester/releases</a></p><p>测下 NAT 类型</p><p><img src="gmqj/13.jpg" alt=""></p><p>我们发现，是 NAT1 的 FullCone</p><p>到这一步，就结束了</p><p>enjoy it！</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;​ 大家都知道，电信的光猫一般性能都比较差，在实现了光电转换功能的同时，默认的路由模式会让光猫背负起本来是路由器在干的拨号上网功能，笔者最近发现家里的网时不时会断流一秒，导致玩彩虹六号卡卡的，就想着如何改桥接，先是在网上搜到了通用的超级管理员密码 telecomadmin </summary>
      
    
    
    
    
    <category term="桥接" scheme="https://sekibetu.com/tags/%E6%A1%A5%E6%8E%A5/"/>
    
    <category term="光猫" scheme="https://sekibetu.com/tags/%E5%85%89%E7%8C%AB/"/>
    
    <category term="Fiddler" scheme="https://sekibetu.com/tags/Fiddler/"/>
    
  </entry>
  
  <entry>
    <title>Windows系统如何解除UWP应用的网络隔离</title>
    <link href="https://sekibetu.com/uwp01.html"/>
    <id>https://sekibetu.com/uwp01.html</id>
    <published>2020-05-05T06:09:53.000Z</published>
    <updated>2025-09-16T15:34:20.000Z</updated>
    
    <content type="html"><![CDATA[<p>​微软服务器对于大陆的连接质量不是很好，很多 UWP 应用时常无法正常使用，而且，UWP 应用是与系统网络隔离的，那么，如何让 UWP 的流量走代理呢，微软官方的开发者中心给出了一个方法：</p><p><a href="https://docs.microsoft.com/en-us/windows/iot-core/develop-your-app/loopback">https://docs.microsoft.com/en-us/windows/iot-core/develop-your-app/loopback</a></p><p>以下是实施这个方法的全过程：</p><h2 id="情景一（单个设置）：">情景一（单个设置）：</h2><p>首先打开注册表，Win+R 键，输入 regedit 回车</p><p><img src="uwp01/1.png" alt=""></p><p>找到以下路径：</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Mappings</span><br></pre></td></tr></table></figure><p><img src="uwp01/2.png" alt=""></p><p>其中，左边的注册表项即为应用的 SID 值</p><p><img src="uwp01/3.png" alt=""></p><p>右边的 DisplayName 对应的值即为应用的名称，比如这里就是 Windows 商店</p><p><img src="uwp01/4.png" alt=""></p><p>接着，使用管理员权限打开 CMD 或者 Powershell</p><p><img src="uwp01/5.png" alt=""></p><p>输入</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CheckNetIsolation.exe loopbackexempt -a -p=SID</span><br></pre></td></tr></table></figure><p>其中的 SID 填上之前我们找到的</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">S-1-15-2-1609473798-1231923017-684268153-4268514328-882773646-2760585773-1760938157</span><br></pre></td></tr></table></figure><p>回车之后即可解除 UWP 应用的网络隔离</p><p><img src="uwp01/6.png" alt=""></p><h2 id="情景二（批量设置）：">情景二（批量设置）：</h2><p>使用管理员权限运行 CMD，输入以下的命令，回车即可</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">FOR /F <span class="string">&quot;tokens=11 delims=\&quot; %p IN (&#x27;REG QUERY &quot;</span>HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Mappings<span class="string">&quot;&#x27;) DO CheckNetIsolation.exe LoopbackExempt -a -p=%p</span></span><br></pre></td></tr></table></figure><p><img src="uwp01/7.gif" alt=""></p><p>或者使用 PowerShell 指令也行：</p><figure class="highlight powershell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Get-ChildItem</span> <span class="literal">-Path</span> Registry::<span class="string">&quot;HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\CurrentVersion\AppContainer\Mappings\&quot;</span> <span class="literal">-name</span> | <span class="built_in">ForEach-Object</span> &#123;CheckNetIsolation.exe LoopbackExempt <span class="literal">-a</span> <span class="literal">-p</span>=<span class="string">&quot;<span class="variable">$_</span>&quot;</span>&#125;</span><br></pre></td></tr></table></figure><h2 id="题外话">题外话</h2><p>​ UWP 应用作为微软主推的一种体系，近年来虽然有很多人响应并开发了很多优质的应用，但是，到现在还是半死不活的，和 Chrome 浏览器的 PWA 应用凑成了一对难兄难弟，呜呼哀哉。</p>]]></content>
    
    
      
      
    <summary type="html">&lt;p&gt;​微软服务器对于大陆的连接质量不是很好，很多 UWP 应用时常无法正常使用，而且，UWP 应用是与系统网络隔离的，那么，如何让 UWP 的流量走代理呢，微软官方的开发者中心给出了一个方法：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.microsoft.com</summary>
      
    
    
    
    
    <category term="Windows" scheme="https://sekibetu.com/tags/Windows/"/>
    
    <category term="UWP" scheme="https://sekibetu.com/tags/UWP/"/>
    
  </entry>
  
</feed>
