<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on 猫猫鱼的小窝</title>
    <link>https://csdn.fjh1997.top/posts/</link>
    <description>Recent content from 猫猫鱼的小窝</description>
    <generator>Hugo</generator>
    <language>zh-CN</language>
    
    <managingEditor>xxx@example.com (catcatyu)</managingEditor>
    <webMaster>xxx@example.com (catcatyu)</webMaster>
    
    <copyright>本博客所有文章除特别声明外，均采用 BY-NC-SA 许可协议。转载请注明出处！</copyright>
    
    <lastBuildDate>Wed, 10 Jun 2026 12:40:15 +0800</lastBuildDate>
    
    
    <atom:link href="https://csdn.fjh1997.top/posts/atom.xml" rel="self" type="application/rss&#43;xml" />
    

    
    

    <item>
      <title>阿里云 ECS 控制台远程连接失败、云助手不响应、OSS 内网超时——Tailscale 与阿里云 100.x 段冲突排查全过程</title>
      <link>https://csdn.fjh1997.top/posts/56136.html</link>
      <pubDate>Wed, 10 Jun 2026 12:40:15 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/56136.html</guid>
      <description>
        <![CDATA[<h1>阿里云 ECS 控制台远程连接失败、云助手不响应、OSS 内网超时——Tailscale 与阿里云 100.x 段冲突排查全过程</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="一现象从控制台远程连接打不开开始">
<a class="header-anchor" href="#%e4%b8%80%e7%8e%b0%e8%b1%a1%e4%bb%8e%e6%8e%a7%e5%88%b6%e5%8f%b0%e8%bf%9c%e7%a8%8b%e8%bf%9e%e6%8e%a5%e6%89%93%e4%b8%8d%e5%bc%80%e5%bc%80%e5%a7%8b"></a>
一、现象：从控制台远程连接打不开开始
</h2><p>某天准备登一台跑在杭州地域的阿里云 ECS 改点东西，结果发现三件事同时挂了：</p>
<ol>
<li><strong>阿里云控制台的「远程连接」（Workbench / VNC）打不开</strong>，点击之后转圈，最后报 &ldquo;连接失败&rdquo;；</li>
<li><strong>「云助手」（Cloud Assistant / ECS Run Command）也不响应</strong>，下发任何命令都一直显示「执行中」，永远不返回结果；</li>
<li>业务侧报错：访问 <code>oss-cn-hangzhou-internal.aliyuncs.com</code>（OSS 内网域名）超时，对象读写全部 hang 住。</li>
</ol>
<p>但是奇怪的是：</p>
<ul>
<li><strong>SSH（外网公网 IP）还能正常登录</strong>；</li>
<li><code>ping 8.8.8.8</code>、<code>ping baidu.com</code> 都通；</li>
<li>业务里访问外网 API 也都正常。</li>
</ul>
<p>这就说明 ECS 本身和外网都没问题，<strong>坏的是阿里云自己的内网链路</strong>——控制台远程连接、云助手、OSS 内网域名，全都走阿里云内网 100.x 段。</p>
<blockquote>
<p>这台机器装了 Tailscale 自建 Headscale，这是个非常重要的伏笔。</p>
</blockquote>
<h2 id="二最小化复现定位到内网域名超时">
<a class="header-anchor" href="#%e4%ba%8c%e6%9c%80%e5%b0%8f%e5%8c%96%e5%a4%8d%e7%8e%b0%e5%ae%9a%e4%bd%8d%e5%88%b0%e5%86%85%e7%bd%91%e5%9f%9f%e5%90%8d%e8%b6%85%e6%97%b6"></a>
二、最小化复现：定位到内网域名超时
</h2><p>先确认 OSS 内网到底是 DNS 挂了还是网络挂了：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ nslookup oss-cn-hangzhou-internal.aliyuncs.com
</span></span><span class="line"><span class="cl">Name:   oss-cn-hangzhou-internal.aliyuncs.com
</span></span><span class="line"><span class="cl">Address: 100.118.28.52
</span></span><span class="line"><span class="cl">Address: 100.118.28.43
</span></span></code></pre></td></tr></table>
</div>
</div><p>DNS 没问题，解析出来两个 100.118.x.x 的地址。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ timeout <span class="m">10</span> telnet 100.118.28.52 <span class="m">443</span>
</span></span><span class="line"><span class="cl">Trying 100.118.28.52...
</span></span><span class="line"><span class="cl">（10 秒之后超时）
</span></span></code></pre></td></tr></table>
</div>
</div><p>TCP 不通。再 ping 一下 ECS metadata 服务器（这也是阿里云内部接口）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ ping -c <span class="m">3</span> 100.100.2.136
</span></span><span class="line"><span class="cl"><span class="m">3</span> packets transmitted, <span class="m">0</span> received, 100% packet loss
</span></span></code></pre></td></tr></table>
</div>
</div><p>也不通。再试一下 metadata HTTP 接口：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl --connect-timeout <span class="m">5</span> http://100.100.100.200/latest/meta-data/region-id
</span></span><span class="line"><span class="cl">（超时，无输出）
</span></span></code></pre></td></tr></table>
</div>
</div><p>也不通。<strong>结论</strong>：凡是阿里云内网 <code>100.x.x.x</code> 段，全部访问不到。</p>
<p>到这里就明确了：阿里云控制台远程连接挂掉、云助手不响应，本质上跟 OSS 内网挂掉是<strong>同一个问题</strong>——它们都需要走 ECS 到 100.x 阿里云内网管控面的链路。</p>
<h2 id="三排查防火墙">
<a class="header-anchor" href="#%e4%b8%89%e6%8e%92%e6%9f%a5%e9%98%b2%e7%81%ab%e5%a2%99"></a>
三、排查防火墙
</h2><p>第一反应是 ufw 或者 iptables 把内网段拦了。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo ufw status verbose
</span></span><span class="line"><span class="cl">Status: inactive
</span></span></code></pre></td></tr></table>
</div>
</div><p>ufw 是关的。再看 iptables：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo iptables -L -v -n
</span></span><span class="line"><span class="cl">...
</span></span><span class="line"><span class="cl">Chain ts-input <span class="o">(</span><span class="m">1</span> references<span class="o">)</span>
</span></span><span class="line"><span class="cl"> pkts bytes target  prot opt in        out  <span class="nb">source</span>            destination
</span></span><span class="line"><span class="cl">    <span class="m">0</span>     <span class="m">0</span> ACCEPT  <span class="m">0</span>   --  lo         *    100.64.0.1        0.0.0.0/0
</span></span><span class="line"><span class="cl">    <span class="m">0</span>     <span class="m">0</span> RETURN  <span class="m">0</span>   --  !tailscale0 *   100.115.92.0/23   0.0.0.0/0
</span></span><span class="line"><span class="cl"> 113K 5983K DROP    <span class="m">0</span>   --  !tailscale0 *   100.64.0.0/10     0.0.0.0/0
</span></span><span class="line"><span class="cl"> 189K   26M ACCEPT  <span class="m">0</span>   --  tailscale0  *   0.0.0.0/0         0.0.0.0/0
</span></span><span class="line"><span class="cl">...
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>罪魁祸首找到了</strong>。</p>
<p><code>ts-input</code> 是 Tailscale 自己装的 iptables 链，最关键的是这条：</p>
<pre tabindex="0"><code>DROP  !tailscale0  100.64.0.0/10  0.0.0.0/0
</code></pre><p>翻译一下：<strong>从不是 <code>tailscale0</code> 的网卡进来的包，只要源地址在 <code>100.64.0.0/10</code> 这个段里，全部丢掉。</strong></p>
<p>而这条 DROP 已经累积了 <strong>113000+ 个被丢的包，将近 6MB 流量</strong>——所有访问阿里云内网失败的包，都被这条规则吞了。</p>
<h2 id="四根因cgnat-段撞车">
<a class="header-anchor" href="#%e5%9b%9b%e6%a0%b9%e5%9b%a0cgnat-%e6%ae%b5%e6%92%9e%e8%bd%a6"></a>
四、根因：CGNAT 段撞车
</h2><p>为啥 Tailscale 要装这条 DROP？</p>
<p>Tailscale（包括自建 Headscale）默认使用 <strong><code>100.64.0.0/10</code> 这个 CGNAT（运营商级 NAT）地址段</strong>给 tailnet 里的节点分配虚拟 IP。这条 DROP 是 Tailscale 的反伪造防御：从外部网卡进来的包，源 IP 不可能是 tailnet 内部地址，如果有那就是欺骗，丢掉。</p>
<p><strong>但是！</strong> 阿里云华东 1（杭州）的内网管控面，<strong>也用了 100.x 段</strong>：</p>
<table>
  <thead>
      <tr>
          <th>资源</th>
          <th>地址段</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Tailscale CGNAT（虚拟）</td>
          <td><strong><code>100.64.0.0/10</code></strong>（即 <code>100.64.0.0</code> ～ <code>100.127.255.255</code>）</td>
      </tr>
      <tr>
          <td>阿里云 ECS metadata</td>
          <td><code>100.100.100.200</code>、<code>100.100.2.136</code></td>
      </tr>
      <tr>
          <td>阿里云 OSS 内网（杭州）</td>
          <td><code>100.118.28.0/24</code> 等</td>
      </tr>
      <tr>
          <td>阿里云云助手/Workbench 回调</td>
          <td>部分 100.x 段</td>
      </tr>
  </tbody>
</table>
<p>它们<strong>全在 <code>100.64.0.0/10</code> 区间内</strong>。</p>
<p>链路是这样的：</p>
<ol>
<li>ECS 发起对 <code>100.118.28.52</code>（OSS 内网）的连接，包从 eth0 出去，OSS 服务回包；</li>
<li>回包从 eth0 进来，源 IP 是 <code>100.118.28.52</code>；</li>
<li>进了 <code>INPUT</code> 链 → <code>ts-input</code> 链；</li>
<li>源 IP 在 <code>100.64.0.0/10</code> 里 + 进来的网卡不是 <code>tailscale0</code> → <strong>DROP</strong>；</li>
<li>应用层看到的就是连接超时。</li>
</ol>
<p>控制台远程连接打不开、云助手不响应，也是同样的机制：阿里云管控面发到这台 ECS 的回调走的就是这条链路，全被丢了。</p>
<h2 id="五修复方案">
<a class="header-anchor" href="#%e4%ba%94%e4%bf%ae%e5%a4%8d%e6%96%b9%e6%a1%88"></a>
五、修复方案
</h2><h3 id="方案-a关掉-tailscale-的-netfilter-接管推荐">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-a%e5%85%b3%e6%8e%89-tailscale-%e7%9a%84-netfilter-%e6%8e%a5%e7%ae%a1%e6%8e%a8%e8%8d%90"></a>
方案 A：关掉 Tailscale 的 netfilter 接管（推荐）
</h3><p>最干净的办法是让 Tailscale 不要再托管 iptables，让默认 ACCEPT 策略接管。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ sudo tailscale <span class="nb">set</span> --netfilter-mode<span class="o">=</span>off
</span></span><span class="line"><span class="cl">Warning: <span class="nv">netfilter</span><span class="o">=</span>off<span class="p">;</span> configure iptables yourself.
</span></span></code></pre></td></tr></table>
</div>
</div><p>这条命令告诉 tailscaled：「我不要你的 iptables 规则」。之后 tailscaled 会把它自己加的 <code>ts-input</code>、<code>ts-forward</code> 等链清掉。</p>
<p>立刻验证：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl --connect-timeout <span class="m">5</span> http://100.100.100.200/latest/meta-data/region-id
</span></span><span class="line"><span class="cl">cn-hangzhou
</span></span></code></pre></td></tr></table>
</div>
</div><p>通了！再试 OSS：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ curl -sI http://oss-cn-hangzhou-internal.aliyuncs.com
</span></span><span class="line"><span class="cl">HTTP/1.1 <span class="m">404</span> Not Found
</span></span><span class="line"><span class="cl">Server: AliyunOSS
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>Server: AliyunOSS</code> 头就证明已经打到 OSS 了（404 是因为我们没指定 bucket，正常）。同时阿里云控制台的远程连接和云助手也都恢复。</p>
<p><strong>代价</strong>：失去了 Tailscale 自己装的「外部网卡上源 IP 伪造成 CGNAT 段的包丢掉」这条防御。但是在阿里云 VPC 内部，攻击者要伪造这种源 IP 包到你的 ECS，几乎做不到（VPC 自身的 underlay 会先把它清掉）。所以这个防御<strong>在 VPC 场景下几乎没有实际作用</strong>，关掉是安全的。</p>
<p>而且对 Tailscale 的实际功能没有影响：</p>
<ul>
<li><code>tailscale0</code> 接口还在；</li>
<li>节点间互相访问还能走；</li>
<li>路由还是好的；</li>
<li>唯一不工作的就是那条没意义的 DROP。</li>
</ul>
<h3 id="方案-b保留-netfilter加豁免规则不推荐">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-b%e4%bf%9d%e7%95%99-netfilter%e5%8a%a0%e8%b1%81%e5%85%8d%e8%a7%84%e5%88%99%e4%b8%8d%e6%8e%a8%e8%8d%90"></a>
方案 B：保留 netfilter，加豁免规则（不推荐）
</h3><p>如果非要保留 Tailscale 的完整 iptables 规则，可以加一条豁免，让阿里云 OSS 段不被 DROP：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 在 ts-input 链的 DROP 规则之前插入豁免</span>
</span></span><span class="line"><span class="cl">sudo iptables -I ts-input <span class="m">3</span> -s 100.118.0.0/16 -j RETURN
</span></span></code></pre></td></tr></table>
</div>
</div><p>但是这条规则<strong>不持久</strong>：</p>
<ul>
<li>tailscaled 重启时会重建 <code>ts-input</code> 链，豁免被冲掉；</li>
<li>tailscaled 运行时如果对账（比如对端变化、ACL 推送），也可能重建。</li>
</ul>
<p>要让它持久得写 systemd drop-in：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /etc/systemd/system/tailscaled.service.d/
</span></span><span class="line"><span class="cl">sudo tee /etc/systemd/system/tailscaled.service.d/aliyun-exception.conf &gt; /dev/null <span class="s">&lt;&lt;&#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">[Service]
</span></span></span><span class="line"><span class="cl"><span class="s">ExecStartPost=/bin/sh -c &#39;sleep 3 &amp;&amp; \
</span></span></span><span class="line"><span class="cl"><span class="s">  /usr/sbin/iptables -C ts-input -s 100.118.0.0/16 -j RETURN 2&gt;/dev/null || \
</span></span></span><span class="line"><span class="cl"><span class="s">  /usr/sbin/iptables -I ts-input 3 -s 100.118.0.0/16 -j RETURN&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">sudo systemctl daemon-reload
</span></span><span class="line"><span class="cl">sudo systemctl restart tailscaled
</span></span></code></pre></td></tr></table>
</div>
</div><p>但是 tailscaled 启动到 ExecStartPost 跑完之间仍然有几秒的窗口期，OSS 会短暂断连。所以一般场景下我还是推荐方案 A。</p>
<blockquote>
<p>还要注意：上面的豁免段 <code>100.118.0.0/16</code> 只覆盖了<strong>杭州</strong>地域的 OSS。如果你的 ECS 在别的地域、或者要访问别的内网服务（如 RDS、Redis 内网），需要查到对应的 100.x 段一起豁免。最稳的查法是直接 <code>nslookup</code> 对应内网域名拿 IP，再确定它的 /16 或 /24。</p>
</blockquote>
<h3 id="方案-c换-tailscale-的-ip-段理论上可行但复杂">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-c%e6%8d%a2-tailscale-%e7%9a%84-ip-%e6%ae%b5%e7%90%86%e8%ae%ba%e4%b8%8a%e5%8f%af%e8%a1%8c%e4%bd%86%e5%a4%8d%e6%9d%82"></a>
方案 C：换 Tailscale 的 IP 段（理论上可行，但复杂）
</h3><p>Headscale 配置文件里可以改 <code>prefixes.v4</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">prefixes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">v4</span><span class="p">:</span><span class="w"> </span><span class="m">100.64.0.0</span><span class="l">/10 </span><span class="w"> </span><span class="c"># 默认</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>如果改成不和阿里云冲突的段（比如自建一个 RFC1918 段），就能彻底避开。但是：</p>
<ul>
<li>所有已注册节点都要重新分配 IP；</li>
<li>部分 Tailscale 客户端对非 CGNAT 段的支持有限制；</li>
<li>改完 ACL、DNS 都要重写。</li>
</ul>
<p>对于个人/小团队的 Tailscale 部署，这个改动成本远大于方案 A。<strong>不推荐</strong>。</p>
<h2 id="六为什么阿里云控制台和云助手也会挂">
<a class="header-anchor" href="#%e5%85%ad%e4%b8%ba%e4%bb%80%e4%b9%88%e9%98%bf%e9%87%8c%e4%ba%91%e6%8e%a7%e5%88%b6%e5%8f%b0%e5%92%8c%e4%ba%91%e5%8a%a9%e6%89%8b%e4%b9%9f%e4%bc%9a%e6%8c%82"></a>
六、为什么阿里云控制台和云助手也会挂
</h2><p>很多人不理解：我自己访问 OSS 失败可以理解，<strong>控制台远程连接、云助手为什么会跟着挂？</strong></p>
<p>是因为这两个东西的工作机制：</p>
<ul>
<li>
<p><strong>云助手</strong>（Cloud Assistant）：ECS 里跑了一个 <code>AliyunAssistClient</code> 守护进程，它需要<strong>主动连接阿里云内网的管控接口</strong>拉取要执行的命令。这个接口的接入点同样是 100.x 内网地址，被 DROP 之后客户端连不上服务器，控制台下发的命令就永远是「执行中」。</p>
</li>
<li>
<p><strong>控制台远程连接（Workbench/VNC）</strong>：浏览器走的是阿里云控制台 → 阿里云内网中转 → ECS metadata/agent 通道。中转回来的握手包源 IP 在 100.x 段，被同一条 DROP 吞掉。</p>
</li>
</ul>
<p>所以这是个<strong>典型的「打开了 Tailscale 之后阿里云任何依赖内网管控的功能都坏」综合症</strong>，看到一个症状要联想到一片。</p>
<h2 id="七检查清单">
<a class="header-anchor" href="#%e4%b8%83%e6%a3%80%e6%9f%a5%e6%b8%85%e5%8d%95"></a>
七、检查清单
</h2><p>如果你在阿里云上跑了 Tailscale / Headscale 并且遇到下面任何一个症状，都先去看 <code>iptables -L ts-input -n -v</code> 那条 DROP 的 pkts 计数：</p>
<ul>
<li><input disabled="" type="checkbox"> 控制台「远程连接」打不开；</li>
<li><input disabled="" type="checkbox"> 「云助手」下发的命令永远不返回；</li>
<li><input disabled="" type="checkbox"> <code>curl http://100.100.100.200/latest/meta-data/</code> 超时（元数据服务）；</li>
<li><input disabled="" type="checkbox"> OSS 内网域名 <code>oss-*-internal.aliyuncs.com</code> 超时；</li>
<li><input disabled="" type="checkbox"> RDS、Redis 内网连接超时；</li>
<li><input disabled="" type="checkbox"> SLS 日志服务内网接口超时；</li>
<li><input disabled="" type="checkbox"> 系统初始化时 cloud-init 卡很久；</li>
<li><input disabled="" type="checkbox"> ECS 自动续费、自动伸缩等管控操作异常。</li>
</ul>
<p>如果 DROP 计数在涨，基本就是这个问题，按方案 A 关掉 netfilter 即可。</p>
<h2 id="八复盘">
<a class="header-anchor" href="#%e5%85%ab%e5%a4%8d%e7%9b%98"></a>
八、复盘
</h2><p>这个坑挺典型，关键学习点：</p>
<ol>
<li><strong>DROP 链的统计计数是最快的指纹</strong>。<code>iptables -L -v -n</code> 看到一条 DROP 规则上有大量 pkts/bytes 累积，就要立刻怀疑它。</li>
<li><strong>CGNAT 段 100.64.0.0/10 是公开标准段</strong>（RFC 6598），任何使用方都不能假定自己独占。阿里云、Tailscale、容器网络、Kubernetes 的 Cilium 等等都可能占用这个段，多个一起装就容易撞车。</li>
<li><strong>「我看到的症状」和「真正的根因」之间通常隔了几层</strong>。最初看到的是控制台远程连接失败，最后定位到的是 Tailscale 的 iptables 规则——中间隔着 OSS 超时、metadata 超时、DROP 计数三层证据。</li>
<li><strong>本地 SSH 还能用的时候不要急着重启</strong>。这种 iptables 规则问题，重启不会修，只会让你失去能继续排查的入口。</li>
</ol>
<hr>
<p>排查工具备忘：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># DNS</span>
</span></span><span class="line"><span class="cl">nslookup oss-cn-hangzhou-internal.aliyuncs.com
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># TCP 探测</span>
</span></span><span class="line"><span class="cl">timeout <span class="m">10</span> telnet &lt;IP&gt; &lt;PORT&gt;
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 看防火墙状态</span>
</span></span><span class="line"><span class="cl">sudo ufw status verbose
</span></span><span class="line"><span class="cl">sudo iptables -L -v -n
</span></span><span class="line"><span class="cl">sudo iptables -L ts-input -v -n   <span class="c1"># 直接看 Tailscale 链</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Tailscale 状态</span>
</span></span><span class="line"><span class="cl">tailscale debug prefs <span class="p">|</span> grep -i netfilter
</span></span><span class="line"><span class="cl">tailscale status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Aliyun metadata 自检</span>
</span></span><span class="line"><span class="cl">curl --connect-timeout <span class="m">5</span> http://100.100.100.200/latest/meta-data/region-id
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 关 Tailscale netfilter（修复）</span>
</span></span><span class="line"><span class="cl">sudo tailscale <span class="nb">set</span> --netfilter-mode<span class="o">=</span>off
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2026-06-10首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-06-10</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Xray 新版 VLESS Reverse Proxy 单隧道承载多端口内网穿透</title>
      <link>https://csdn.fjh1997.top/posts/xray-vless-reverse-single-tunnel-port-mapping.html</link>
      <pubDate>Mon, 08 Jun 2026 14:20:46 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/xray-vless-reverse-single-tunnel-port-mapping.html</guid>
      <description>
        <![CDATA[<h1>Xray 新版 VLESS Reverse Proxy 单隧道承载多端口内网穿透</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="前言">
<a class="header-anchor" href="#%e5%89%8d%e8%a8%80"></a>
前言
</h2><p>之前写过一篇 <a href="/posts/xray-reverse-proxy-enterfirewall.html">Xray 反向代理多端口内网穿透配置</a>
，当时使用的是旧版顶层 <code>reverse.portals</code> / <code>reverse.bridges</code> 写法。那套方案能跑，但每暴露一个服务就要维护一组 portal/bridge tag 和一组 <code>.internal</code> 域名，服务数量多了以后配置会变得很长。</p>
<p>这次把同类场景更新为新版 VLESS reverse proxy 写法，并且没有继续采用“一项服务一条反向隧道”的保守迁移方式，而是改成 <strong>一条 VLESS reverse 隧道承载多个公网端口</strong>。</p>
<p>为了避免泄露真实环境，本文中的域名、IP、UUID、服务名、密码、密钥均已脱敏。直接复制配置前需要替换占位符。</p>
<h2 id="迁移目标">
<a class="header-anchor" href="#%e8%bf%81%e7%a7%bb%e7%9b%ae%e6%a0%87"></a>
迁移目标
</h2><p>原来的旧结构大概是这样：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">公网 80   -&gt; external-web     -&gt; portal-web     -&gt; bridge-web     -&gt; 127.0.0.1:80
</span></span><span class="line"><span class="cl">公网 8081 -&gt; external-api     -&gt; portal-api     -&gt; bridge-api     -&gt; 127.0.0.1:8001
</span></span><span class="line"><span class="cl">公网 8082 -&gt; external-admin   -&gt; portal-admin   -&gt; bridge-admin   -&gt; 127.0.0.1:8002
</span></span><span class="line"><span class="cl">公网 2222 -&gt; external-ssh     -&gt; portal-ssh     -&gt; bridge-ssh     -&gt; 127.0.0.1:22
</span></span></code></pre></td></tr></table>
</div>
</div><p>每一行都要在公网端写 portal，在桥接端写 bridge，还要维护一条用于注册隧道的 <code>.internal</code> 域名路由。</p>
<p>更新后的结构：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">公网 80
</span></span><span class="line"><span class="cl">公网 8081
</span></span><span class="line"><span class="cl">公网 8082
</span></span><span class="line"><span class="cl">公网 2222
</span></span><span class="line"><span class="cl">公网 8083
</span></span><span class="line"><span class="cl">公网 8084
</span></span><span class="line"><span class="cl">公网 8085
</span></span><span class="line"><span class="cl">    |
</span></span><span class="line"><span class="cl">    v
</span></span><span class="line"><span class="cl">同一个 reverse-out
</span></span><span class="line"><span class="cl">    |
</span></span><span class="line"><span class="cl">    v
</span></span><span class="line"><span class="cl">同一个 reverse-in
</span></span><span class="line"><span class="cl">    |
</span></span><span class="line"><span class="cl">    +-- 目标端口 80   -&gt; 127.0.0.1:80
</span></span><span class="line"><span class="cl">    +-- 目标端口 8081 -&gt; 127.0.0.1:8001
</span></span><span class="line"><span class="cl">    +-- 目标端口 8082 -&gt; 127.0.0.1:8002
</span></span><span class="line"><span class="cl">    +-- 目标端口 2222 -&gt; 127.0.0.1:22
</span></span></code></pre></td></tr></table>
</div>
</div><p>公网端只负责把外部入口全部转进同一个 <code>reverse-out</code>，桥接端再根据请求保留下来的目标端口做二次分流。</p>
<h2 id="为什么可以这么做">
<a class="header-anchor" href="#%e4%b8%ba%e4%bb%80%e4%b9%88%e5%8f%af%e4%bb%a5%e8%bf%99%e4%b9%88%e5%81%9a"></a>
为什么可以这么做
</h2><p><code>dokodemo-door</code> 入站可以把公网端口上的连接包装成一个带目标地址和目标端口的请求。公网端把这些请求交给 VLESS reverse proxy 后，桥接端的 <code>reverse-in</code> 仍然可以基于 <code>port</code> 做路由匹配。</p>
<p>所以我们不再需要：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;portals&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-web&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-web.internal&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>也不再需要桥接端的：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;bridges&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-web&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-web.internal&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>新版写法把反向代理关系直接写在 VLESS client/outbound 里。</p>
<p>公网服务器侧：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-single@example&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>桥接端侧：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;encryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-in&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意桥接端 outbound 必须使用 simplified outbound config style，也就是把 <code>address</code>、<code>port</code>、<code>id</code>、<code>flow</code>、<code>reverse</code> 直接写在 <code>settings</code> 下面。不要再写成旧的 <code>vnext.users</code> 结构，否则新版 reverse 会报错。</p>
<h2 id="公网服务器配置">
<a class="header-anchor" href="#%e5%85%ac%e7%bd%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae"></a>
公网服务器配置
</h2><p>下面只展示核心配置。假设公网服务器原来已经有一个 VLESS + REALITY + Vision 入站，tag 为 <code>interconn</code>。</p>
<h3 id="vless-入站">
<a class="header-anchor" href="#vless-%e5%85%a5%e7%ab%99"></a>
VLESS 入站
</h3><p>保留原有普通客户端，同时新增一个专门给桥接端使用的 reverse client：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;NORMAL-CLIENT-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-single@example&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;reality&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;realitySettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;show&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;dest&#34;</span><span class="p">:</span> <span class="s2">&#34;www.example.com:443&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;xver&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;serverNames&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;www.example.com&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;privateKey&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REALITY-PRIVATE-KEY&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;shortIds&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;&lt;REALITY-SHORT-ID&gt;&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果你的入口是普通 TLS，就保留原来的 <code>tlsSettings</code>。这里的重点是 <code>clients</code> 里新增了带 <code>reverse.tag</code> 的桥接客户端。</p>
<h3 id="公网入口">
<a class="header-anchor" href="#%e5%85%ac%e7%bd%91%e5%85%a5%e5%8f%a3"></a>
公网入口
</h3><p>公网端仍然用 <code>dokodemo-door</code> 暴露多个端口：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-web&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-api&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8081</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8081</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-ssh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">2222</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">2222</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>settings.port</code> 要保留和公网入口一致，因为桥接端后面会靠这个目标端口分流。</p>
<h3 id="路由规则">
<a class="header-anchor" href="#%e8%b7%af%e7%94%b1%e8%a7%84%e5%88%99"></a>
路由规则
</h3><p>旧配置通常会写成多条：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;external-web&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-web&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>新版单隧道可以合并为一条：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-web&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-api&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-admin&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-ssh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-service-a&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;external-service-b&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;interconn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>reverse-out</code> 不需要出现在 <code>outbounds</code> 数组里。它来自 VLESS client 的：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="s2">&#34;reverse&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-out&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>outbounds</code> 里保留默认出口即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;blackhole&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="桥接端配置">
<a class="header-anchor" href="#%e6%a1%a5%e6%8e%a5%e7%ab%af%e9%85%8d%e7%bd%ae"></a>
桥接端配置
</h2><p>桥接端不再需要顶层 <code>reverse.bridges</code>。它只需要一个主动连接公网服务器的 VLESS outbound。</p>
<h3 id="单-reverse-outbound">
<a class="header-anchor" href="#%e5%8d%95-reverse-outbound"></a>
单 reverse outbound
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;encryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reverse-in&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;reality&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;realitySettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;www.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;publicKey&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REALITY-PUBLIC-KEY&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;shortId&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REALITY-SHORT-ID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;spiderX&#34;</span><span class="p">:</span> <span class="s2">&#34;/&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果公网端是普通 TLS，桥接端就改成：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tlsSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="本地服务出口">
<a class="header-anchor" href="#%e6%9c%ac%e5%9c%b0%e6%9c%8d%e5%8a%a1%e5%87%ba%e5%8f%a3"></a>
本地服务出口
</h3><p>每个本地服务仍然用 <code>freedom.redirect</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-web&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:80&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;finalRules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;allow&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;127.0.0.1&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;80&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-api&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:8001&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;finalRules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;allow&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;127.0.0.1&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;8001&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-ssh&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:22&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;finalRules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;allow&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;127.0.0.1&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;22&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>finalRules</code> 不是必须在所有旧配置里都出现，但新版配置里建议显式写上，只允许 reverse 流量访问需要暴露的本地端口。</p>
<h3 id="按目标端口分流">
<a class="header-anchor" href="#%e6%8c%89%e7%9b%ae%e6%a0%87%e7%ab%af%e5%8f%a3%e5%88%86%e6%b5%81"></a>
按目标端口分流
</h3><p>这是单隧道方案的关键：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;reverse-in&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;80&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-web&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;reverse-in&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;8081&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-api&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;reverse-in&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="s2">&#34;2222&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-ssh&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里匹配的是公网 <code>dokodemo-door</code> 保留下来的目标端口，不是桥接端本地服务的端口。例如公网 <code>8081</code> 最后可以转发到桥接端本机 <code>127.0.0.1:8001</code>。</p>
<h2 id="验证流程">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81%e6%b5%81%e7%a8%8b"></a>
验证流程
</h2><p>先在两端验证配置语法：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xray run -test -config /usr/local/etc/xray/config.json
</span></span><span class="line"><span class="cl">xray run -test -config /usr/local/etc/xray/bridge-config.json
</span></span></code></pre></td></tr></table>
</div>
</div><p>确认通过后再重启：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl restart xray
</span></span><span class="line"><span class="cl">systemctl restart xray-bridge
</span></span></code></pre></td></tr></table>
</div>
</div><p>公网端看日志，应该能看到外部入口进入同一个 <code>reverse-out</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">external-web -&gt; reverse-out
</span></span><span class="line"><span class="cl">external-api -&gt; reverse-out
</span></span><span class="line"><span class="cl">external-ssh -&gt; reverse-out
</span></span></code></pre></td></tr></table>
</div>
</div><p>桥接端看配置摘要，应该没有顶层 <code>reverse</code>，并且 VLESS outbound 带有 <code>reverse</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">has_top_reverse false
</span></span><span class="line"><span class="cl">reverse_outbounds [(&#39;interconn&#39;, &#39;vless&#39;, true)]
</span></span></code></pre></td></tr></table>
</div>
</div><p>最后逐个测公网端口：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -I http://proxy.example.com/
</span></span><span class="line"><span class="cl">curl -I http://proxy.example.com:8081/
</span></span><span class="line"><span class="cl">ssh -p <span class="m">2222</span> root@proxy.example.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果 SSH 能返回 banner，HTTP 服务能返回对应后端响应，说明公网入口、VLESS reverse 隧道和桥接端本地 redirect 都已经打通。</p>
<h2 id="回滚">
<a class="header-anchor" href="#%e5%9b%9e%e6%bb%9a"></a>
回滚
</h2><p>迁移前建议在两端都做备份：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp /usr/local/etc/xray/config.json /usr/local/etc/xray/config.json.bak-before-single-vless-reverse
</span></span><span class="line"><span class="cl">cp /usr/local/etc/xray/bridge-config.json /usr/local/etc/xray/bridge-config.json.bak-before-single-vless-reverse
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果切换后发现某个端口异常，可以直接恢复旧配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp /usr/local/etc/xray/config.json.bak-before-single-vless-reverse /usr/local/etc/xray/config.json
</span></span><span class="line"><span class="cl">systemctl restart xray
</span></span></code></pre></td></tr></table>
</div>
</div><p>桥接端同理：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp /usr/local/etc/xray/bridge-config.json.bak-before-single-vless-reverse /usr/local/etc/xray/bridge-config.json
</span></span><span class="line"><span class="cl">systemctl restart xray-bridge
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="取舍">
<a class="header-anchor" href="#%e5%8f%96%e8%88%8d"></a>
取舍
</h2><p>单隧道方案的优点：</p>
<ul>
<li>配置明显更短；</li>
<li>不需要维护多组 <code>.internal</code> 域名；</li>
<li>只需要一个 bridge UUID；</li>
<li>多端口入口的流量都走同一条 reverse 通道，管理成本低；</li>
<li>从旧 <code>reverse.portals/bridges</code> 迁移到新版 VLESS reverse proxy 后，结构更贴近 Xray 当前推荐写法。</li>
</ul>
<p>缺点也很明确：</p>
<ul>
<li>所有服务共用一条 reverse 通道，故障影响面更大；</li>
<li>桥接端依赖目标端口路由，如果公网端 <code>dokodemo-door</code> 的目标端口写错，分流会错；</li>
<li>迁移时必须两端同时切换，不能只改公网端或只改桥接端。</li>
</ul>
<p>如果是生产环境，保守做法是一项服务一条 reverse 隧道，出错时只影响单个服务。如果是在维护窗口内追求配置简洁和更少的连接管理开销，单隧道方案更合适。</p>

        
        <hr><p>本文2026-06-08首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-06-08</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用新版 VLESS Reverse Proxy 实现海外入口回国内出口</title>
      <link>https://csdn.fjh1997.top/posts/xray-vless-reverse-cn-egress.html</link>
      <pubDate>Mon, 08 Jun 2026 14:00:17 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/xray-vless-reverse-cn-egress.html</guid>
      <description>
        <![CDATA[<h1>使用新版 VLESS Reverse Proxy 实现海外入口回国内出口</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="前言">
<a class="header-anchor" href="#%e5%89%8d%e8%a8%80"></a>
前言
</h2><p>这篇记录一次比较典型的“回国出口”配置：公网服务器在海外，朋友仍然连接这台海外服务器的 VLESS/XTLS 入口，但访问国内网站时，流量会通过一条反向隧道转回国内机器，再从国内宽带出口访问目标网站。</p>
<p>整体目标是：</p>
<ul>
<li>朋友继续使用公网服务器原来的 443 VLESS 入口；</li>
<li>国内机器不需要公网 IP，也不需要在路由器上做端口转发；</li>
<li>只把国内域名和国内 IP 转回国内出口，其他流量仍走海外服务器原来的出口；</li>
<li>使用 Xray 新版 VLESS reverse proxy 写法，不再使用旧的 <code>reverse.portals</code> / <code>reverse.bridges</code>。</li>
</ul>
<p>为了避免泄露真实环境，本文中的域名、UUID、证书路径、用户标识都已经脱敏。直接复制前需要把占位符替换成自己的值。</p>
<h2 id="架构">
<a class="header-anchor" href="#%e6%9e%b6%e6%9e%84"></a>
架构
</h2><pre tabindex="0"><code>朋友客户端
    |
    | VLESS + TLS/REALITY + Vision
    v
海外公网服务器
    |
    | 命中 geosite:cn / geoip:cn
    | 转入 VLESS reverse proxy
    v
国内出口机器
    |
    | freedom 直连
    v
国内网站
</code></pre><p>反向连接由国内出口机器主动发起到海外服务器。海外服务器只需要保留原来的公网 443 入站，国内机器不暴露任何公网端口。</p>
<h2 id="新旧写法区别">
<a class="header-anchor" href="#%e6%96%b0%e6%97%a7%e5%86%99%e6%b3%95%e5%8c%ba%e5%88%ab"></a>
新旧写法区别
</h2><p>旧写法通常会在配置顶层写：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;portals&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel.internal&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>新版 VLESS reverse proxy 不再依赖顶层 <code>reverse.portals</code> / <code>reverse.bridges</code>。它把 <code>reverse</code> 写进 VLESS client 或 VLESS outbound：</p>
<p>公网服务器侧：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-bridge@example&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>国内出口机器侧：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;encryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-in&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>公网服务器上的 <code>cn-reverse-out</code> 会表现为一个可路由的 outbound；国内出口机器上的 <code>cn-reverse-in</code> 会表现为一个可匹配的 inbound。</p>
<h2 id="公网服务器配置">
<a class="header-anchor" href="#%e5%85%ac%e7%bd%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e9%85%8d%e7%bd%ae"></a>
公网服务器配置
</h2><p>下面只展示关键片段。假设公网服务器原来已经有一个 VLESS + TLS/REALITY + Vision 入站，tag 为 <code>vless-in</code>。</p>
<h3 id="入站新增两个用户">
<a class="header-anchor" href="#%e5%85%a5%e7%ab%99%e6%96%b0%e5%a2%9e%e4%b8%a4%e4%b8%aa%e7%94%a8%e6%88%b7"></a>
入站新增两个用户
</h3><p>一个用户给国内机器建立反向隧道，一个用户给朋友使用。不要让朋友和自己共用同一个 UUID，否则服务端无法按用户分流。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;vless-in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;YOUR-OWN-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;self@example&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-bridge@example&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;FRIEND-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;cnfriend@example&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;tls&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;routeOnly&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果你的入口是 REALITY，就保留原来的 <code>realitySettings</code>；如果是普通 TLS 证书，就保留原来的 <code>tlsSettings</code>。这里的核心不是 TLS 还是 REALITY，而是新增的 <code>reverse.tag</code> 和朋友独立用户。</p>
<h3 id="路由规则">
<a class="header-anchor" href="#%e8%b7%af%e7%94%b1%e8%a7%84%e5%88%99"></a>
路由规则
</h3><p>只把朋友访问国内域名和国内 IP 的流量转进反向隧道：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;domainStrategy&#34;</span><span class="p">:</span> <span class="s2">&#34;IPIfNonMatch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;user&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;cnfriend@example&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;geosite:cn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;user&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;cnfriend@example&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;geoip:cn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-out&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果原配置里有 <code>geoip:cn</code> 或 <code>geosite:cn</code> 走 <code>block</code> 的规则，上面两条规则要放在 block 规则之前，否则国内流量会先被拦截。</p>
<p><code>outbounds</code> 里仍然要保留一个默认出口，比如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;blackhole&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样没有命中回国规则的流量不会误入反向隧道。</p>
<h2 id="国内出口机器配置">
<a class="header-anchor" href="#%e5%9b%bd%e5%86%85%e5%87%ba%e5%8f%a3%e6%9c%ba%e5%99%a8%e9%85%8d%e7%bd%ae"></a>
国内出口机器配置
</h2><p>国内机器负责主动连接海外服务器，并把反向进来的流量从本地网络发出去。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;loglevel&#34;</span><span class="p">:</span> <span class="s2">&#34;warning&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;domainStrategy&#34;</span><span class="p">:</span> <span class="s2">&#34;IPIfNonMatch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;cn-reverse-in&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-home-direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-home-direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;finalRules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;allow&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp,udp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;!geoip:private&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">]</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-bridge&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;encryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;BRIDGE-UUID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-reverse-in&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tlsSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里的 <code>finalRules</code> 只允许访问非私网地址，避免朋友通过这条反向隧道访问国内出口机器所在局域网的私有网段。如果你就是要访问内网 NAS、路由器后台等资源，再按需放开具体 IP 和端口，不建议直接放开整个私网。</p>
<p>如果海外入口是 REALITY，国内机器的 <code>streamSettings</code> 改成类似下面这样：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;reality&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;realitySettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;www.example.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;publicKey&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REALITY-PUBLIC-KEY&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;shortId&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REALITY-SHORT-ID&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;spiderX&#34;</span><span class="p">:</span> <span class="s2">&#34;/&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="systemd-用户服务">
<a class="header-anchor" href="#systemd-%e7%94%a8%e6%88%b7%e6%9c%8d%e5%8a%a1"></a>
systemd 用户服务
</h2><p>如果国内机器没有 root 权限，也可以用用户级 systemd 跑 Xray。示例：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Xray CN reverse exit</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
</span></span><span class="line"><span class="cl"><span class="na">Environment</span><span class="o">=</span><span class="s">XRAY_LOCATION_ASSET=%h/.local/share/xray</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">%h/.local/xray/xray run -config %h/.config/xray-cn-exit/config.json</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">on-failure</span>
</span></span><span class="line"><span class="cl"><span class="na">RestartSec</span><span class="o">=</span><span class="s">5</span>
</span></span><span class="line"><span class="cl"><span class="na">NoNewPrivileges</span><span class="o">=</span><span class="s">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">default.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>启动：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl --user daemon-reload
</span></span><span class="line"><span class="cl">systemctl --user <span class="nb">enable</span> --now xray-cn-exit.service
</span></span><span class="line"><span class="cl">systemctl --user status xray-cn-exit.service --no-pager
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果要让用户退出登录后仍然保持运行，需要确认系统是否开启了 linger：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">loginctl enable-linger <span class="s2">&#34;</span><span class="nv">$USER</span><span class="s2">&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这一步通常需要管理员权限。</p>
<h2 id="朋友客户端配置">
<a class="header-anchor" href="#%e6%9c%8b%e5%8f%8b%e5%ae%a2%e6%88%b7%e7%ab%af%e9%85%8d%e7%bd%ae"></a>
朋友客户端配置
</h2><p>普通 TLS 入口的链接大概是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">vless://&lt;FRIEND-UUID&gt;@proxy.example.com:443?encryption=none&amp;security=tls&amp;sni=proxy.example.com&amp;fp=chrome&amp;type=tcp&amp;flow=xtls-rprx-vision#CN-Return
</span></span></code></pre></td></tr></table>
</div>
</div><p>REALITY 入口的链接大概是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">vless://&lt;FRIEND-UUID&gt;@proxy.example.com:443?encryption=none&amp;security=reality&amp;sni=www.example.com&amp;fp=chrome&amp;pbk=&lt;REALITY-PUBLIC-KEY&gt;&amp;sid=&lt;REALITY-SHORT-ID&gt;&amp;type=tcp&amp;flow=xtls-rprx-vision#CN-Return
</span></span></code></pre></td></tr></table>
</div>
</div><p>关键是朋友使用独立的 <code>&lt;FRIEND-UUID&gt;</code>。服务端通过这个 UUID 对应的 <code>email</code> 识别出朋友，然后只把国内目标转进 <code>cn-reverse-out</code>。</p>
<h2 id="验证">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81"></a>
验证
</h2><p>先分别测试配置语法：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xray run -test -config /usr/local/etc/xray/config.json
</span></span><span class="line"><span class="cl">xray run -test -config ~/.config/xray-cn-exit/config.json
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后重启服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl restart xray
</span></span><span class="line"><span class="cl">systemctl --user restart xray-cn-exit.service
</span></span></code></pre></td></tr></table>
</div>
</div><p>可以临时在本地起一个朋友客户端 SOCKS 入站测试：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -x socks5h://127.0.0.1:18088 -I https://www.baidu.com/
</span></span><span class="line"><span class="cl">curl -x socks5h://127.0.0.1:18088 https://api.ipify.org
</span></span></code></pre></td></tr></table>
</div>
</div><p>期望结果：</p>
<ul>
<li><code>www.baidu.com</code> 正常返回；</li>
<li>国内出口机器日志里能看到类似 <code>cn-reverse-in -&gt; cn-home-direct</code>；</li>
<li>非国内目标仍显示海外服务器 IP，说明没有把所有流量都转回国内机器。</li>
</ul>
<h2 id="注意事项">
<a class="header-anchor" href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9"></a>
注意事项
</h2><ol>
<li>朋友必须使用独立 UUID，不要复用自己的 UUID。</li>
<li>服务器上如果已有 <code>geoip:cn</code> / <code>geosite:cn</code> 拦截规则，回国规则要放在拦截规则之前。</li>
<li>不建议在公网服务器上额外开放无认证 SOCKS/HTTP 代理端口，朋友直接复用 VLESS 入口即可。</li>
<li>国内出口机器关机、断网或 Xray 服务停止后，朋友的国内分流会不可用。</li>
<li>国内出口侧建议默认禁止访问私网地址，只按需放开具体内网资源。</li>
</ol>
<p>这套方案的核心是“公网服务器负责入口和分流，国内机器负责主动建立反向隧道和最终出口”。新版 VLESS reverse proxy 把反向代理关系收敛到 VLESS client/outbound 本身，配置比旧的 <code>reverse.portals</code> / <code>reverse.bridges</code> 更直观，也更适合和现有 XTLS/Vision 入口合并使用。</p>

        
        <hr><p>本文2026-06-08首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-06-08</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>解决 Google Play 在 v2rayNG 下卡在等待下载的问题</title>
      <link>https://csdn.fjh1997.top/posts/20260605.html</link>
      <pubDate>Fri, 05 Jun 2026 20:30:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/20260605.html</guid>
      <description>
        <![CDATA[<h1>解决 Google Play 在 v2rayNG 下卡在等待下载的问题</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="问题现象">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e7%8e%b0%e8%b1%a1"></a>
问题现象
</h2><p>一台 OnePlus / ColorOS 设备上，Google Play 可以打开，也能搜索应用，但是安装应用时一直显示“等待中”或者“正在等待下载”。设备已经 root，可以在 Termux 里使用 <code>su</code> 执行系统命令。</p>
<p>当时环境大致如下：</p>
<ul>
<li>Android 16</li>
<li>Google Play 商店版本：<code>40.1.20-23</code></li>
<li>Google Play 服务版本：<code>26.19.34</code></li>
<li>v2rayNG：<code>2.0.18</code></li>
<li>当前代理节点：<code>TLS-Vision-Unlimited-IPv4</code></li>
</ul>
<h2 id="先排除常见问题">
<a class="header-anchor" href="#%e5%85%88%e6%8e%92%e9%99%a4%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98"></a>
先排除常见问题
</h2><p>先看空间：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">df -h /data /storage/emulated/0
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果 <code>/data</code> 可用空间还有几百 GB，所以不是空间不足。</p>
<p>再确认几个核心包是否存在：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pm path com.android.vending
</span></span><span class="line"><span class="cl">pm path com.google.android.gms
</span></span><span class="line"><span class="cl">pm path com.google.android.gsf
</span></span><span class="line"><span class="cl">pm path com.android.providers.downloads
</span></span></code></pre></td></tr></table>
</div>
</div><p>这些包都存在。root 下进一步看包状态：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;/system/bin/dumpsys package com.android.vending | grep -E &#34;versionName|lastUpdateTime|installerPackageName|User 0&#34;&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;/system/bin/dumpsys package com.google.android.gms | grep -E &#34;versionName|lastUpdateTime|installerPackageName|User 0&#34;&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;/system/bin/dumpsys package com.android.providers.downloads | grep -E &#34;versionName|User 0&#34;&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>结论：</p>
<ul>
<li>Play 商店、Play 服务、GSF、下载管理器都没有被禁用。</li>
<li>Play 商店版本比较旧，最后更新时间停在 2025-03-12。</li>
<li>下载管理器正常启用。</li>
</ul>
<h2 id="清掉旧的卡死下载任务">
<a class="header-anchor" href="#%e6%b8%85%e6%8e%89%e6%97%a7%e7%9a%84%e5%8d%a1%e6%ad%bb%e4%b8%8b%e8%bd%bd%e4%bb%bb%e5%8a%a1"></a>
清掉旧的卡死下载任务
</h2><p>一开始在下载管理器数据库里发现了一个旧的 Play 下载任务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;content query --uri content://downloads/all_downloads&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中有一条记录类似：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">notificationpackage=com.android.vending
</span></span><span class="line"><span class="cl">allowed_network_types=2
</span></span><span class="line"><span class="cl">status=194
</span></span><span class="line"><span class="cl">errorMsg=Binding socket to network 182 failed: EPERM (Operation not permitted)
</span></span><span class="line"><span class="cl">uri=https://rr5---sn-a5mekn6r.gvt1.com/play-apps-download-default/download/by-id/...
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里有两个重点：</p>
<ul>
<li><code>allowed_network_types=2</code> 表示任务只允许 Wi-Fi。</li>
<li><code>Binding socket to network 182 failed</code> 表示它还绑到了一个已经失效的网络。</li>
</ul>
<p>删除这条旧任务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;content delete --uri content://downloads/all_downloads/103519&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;am force-stop com.android.vending; am force-stop com.android.providers.downloads; am force-stop com.google.android.gms&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;cmd package clear --user 0 --cache-only com.android.providers.downloads; cmd package clear --user 0 --cache-only com.android.vending&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这一步可以解决旧任务残留导致的“等待中”，但本次问题还没有完全解决。</p>
<h2 id="抓-play-下载服务日志">
<a class="header-anchor" href="#%e6%8a%93-play-%e4%b8%8b%e8%bd%bd%e6%9c%8d%e5%8a%a1%e6%97%a5%e5%bf%97"></a>
抓 Play 下载服务日志
</h2><p>重新点下载后，继续抓日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;logcat -d -t 3000 | grep -Ei &#34;Finsky|DownloadService|CronetDownloader|CANNOT_CONNECT|ERR_QUIC|ERR_CONNECTION|WAITING_FOR_RETRY|RUNNING|QUEUED|gvt1|CronetUrlRequest&#34;&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>关键日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">CronetDownloader: onFailed
</span></span><span class="line"><span class="cl">Exception in CronetUrlRequest: net::ERR_CONNECTION_CLOSED
</span></span><span class="line"><span class="cl">Download Service Error: CANNOT_CONNECT (8)
</span></span><span class="line"><span class="cl">Updating listeners of &lt;... QUEUED with WAITING_FOR_RETRY ...&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>中间还出现过：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">net::ERR_QUIC_PROTOCOL_ERROR
</span></span></code></pre></td></tr></table>
</div>
</div><p>这说明 Play 不是真的单纯排队，而是下载服务连接失败后进入等待重试。</p>
<p>为了排除 QUIC/HTTP3 影响，我临时对 Play 和 GMS 禁了 UDP 443：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;iptables -I OUTPUT -p udp --dport 443 -m owner --uid-owner 10248 -j REJECT&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;iptables -I OUTPUT -p udp --dport 443 -m owner --uid-owner 10242 -j REJECT&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中：</p>
<ul>
<li><code>10248</code> 是 Play 商店 UID。</li>
<li><code>10242</code> 是 Google Play 服务 UID。</li>
</ul>
<p>禁掉 UDP 443 后，QUIC 错误减少，但仍然出现 TCP 层的 <code>ERR_CONNECTION_CLOSED</code>，所以问题不只是 QUIC。</p>
<h2 id="找到真正失败的域名">
<a class="header-anchor" href="#%e6%89%be%e5%88%b0%e7%9c%9f%e6%ad%a3%e5%a4%b1%e8%b4%a5%e7%9a%84%e5%9f%9f%e5%90%8d"></a>
找到真正失败的域名
</h2><p>Play 的下载 URL 不一定直接出现在 logcat 里，可以复制它的本地数据库出来读：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;cp /data/data/com.android.vending/databases/download_service /tmp/play_download_service.db; chmod 644 /tmp/play_download_service.db&#39;</span>
</span></span><span class="line"><span class="cl">python3 - <span class="s">&lt;&lt;&#39;PY&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">import pathlib, re
</span></span></span><span class="line"><span class="cl"><span class="s">data = pathlib.Path(&#39;/tmp/play_download_service.db&#39;).read_bytes()
</span></span></span><span class="line"><span class="cl"><span class="s">urls = sorted(set(m.decode(&#39;utf-8&#39;, &#39;ignore&#39;) for m in re.findall(rb&#39;https?://[^\x00\s&#34;\&#39;]+&#39;, data)))
</span></span></span><span class="line"><span class="cl"><span class="s">for u in urls:
</span></span></span><span class="line"><span class="cl"><span class="s">    print(u[:500])
</span></span></span><span class="line"><span class="cl"><span class="s">PY</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>查到当前 Play 下载库里实际使用的是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://services.googleapis.cn/download/by-token/download?token=...
</span></span></code></pre></td></tr></table>
</div>
</div><p>旧任务里还出现过：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">https://rr5---sn-a5mekn6r.gvt1.com/play-apps-download-default/download/by-id/...
</span></span></code></pre></td></tr></table>
</div>
</div><p>因此重点域名是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">services.googleapis.cn
</span></span><span class="line"><span class="cl">redirector.gvt1.com
</span></span><span class="line"><span class="cl">*.gvt1.com
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="本机连通性测试">
<a class="header-anchor" href="#%e6%9c%ac%e6%9c%ba%e8%bf%9e%e9%80%9a%e6%80%a7%e6%b5%8b%e8%af%95"></a>
本机连通性测试
</h2><p>直接在 Termux 里测试：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://redirector.gvt1.com
</span></span><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://rr5---sn-a5mekn6r.gvt1.com
</span></span><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://play.googleapis.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>一开始结果是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">services.googleapis.cn      TLS connect error: unexpected eof while reading
</span></span><span class="line"><span class="cl">redirector.gvt1.com         TLS connect error: unexpected eof while reading
</span></span><span class="line"><span class="cl">rr5---sn-a5mekn6r.gvt1.com  HTTP/1.1 404 Not Found
</span></span><span class="line"><span class="cl">play.googleapis.com         HTTP/2 404
</span></span></code></pre></td></tr></table>
</div>
</div><p>404 在这里反而说明 TLS 和 HTTP 都是通的，只是访问根路径不是有效接口。真正有问题的是 <code>unexpected eof while reading</code>，也就是 TLS 握手阶段被断开。</p>
<p>为了判断是不是域名本身的问题，又用 check-host 从第三方节点测：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s <span class="s1">&#39;https://check-host.net/check-http?host=https://services.googleapis.cn&amp;max_nodes=8&#39;</span> -H <span class="s1">&#39;Accept: application/json&#39;</span>
</span></span><span class="line"><span class="cl">curl -s <span class="s1">&#39;https://check-host.net/check-http?host=https://redirector.gvt1.com&amp;max_nodes=8&#39;</span> -H <span class="s1">&#39;Accept: application/json&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>外部节点访问 <code>services.googleapis.cn</code> 和 <code>redirector.gvt1.com</code> 基本都返回 404，说明域名本身没有挂，是本机当前代理线路有问题。</p>
<h2 id="检查-v2rayng-路由配置">
<a class="header-anchor" href="#%e6%a3%80%e6%9f%a5-v2rayng-%e8%b7%af%e7%94%b1%e9%85%8d%e7%bd%ae"></a>
检查 v2rayNG 路由配置
</h2><p>v2rayNG 2.0.18 的配置存在 MMKV 里：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;strings /data/data/com.v2ray.ang/files/mmkv/SETTING | grep -Ei &#34;routing|geosite|gvt1|googleapis|services.googleapis|direct|proxy&#34; -C2&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>当时配置里能看到类似规则：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;services.googleapis.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;*.gvt1.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;redirector.gvt1.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;*.googleusercontent.com&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;remarks&#34;</span><span class="p">:</span> <span class="s2">&#34;playstore&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>而且它的位置在 <code>geosite:cn -&gt; direct</code> 前面。分应用代理里也包含：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">com.android.vending
</span></span><span class="line"><span class="cl">com.google.android.gms
</span></span><span class="line"><span class="cl">com.android.providers.downloads
</span></span><span class="line"><span class="cl">com.termux
</span></span></code></pre></td></tr></table>
</div>
</div><p>所以表面看路由顺序没问题。</p>
<p>为了进一步排除“VPN 路由没生效”，我直接强制使用 v2rayNG 的本地 socks 端口测试：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl --socks5-hostname 127.0.0.1:10808 -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span><span class="line"><span class="cl">curl --socks5-hostname 127.0.0.1:10808 -I --connect-timeout <span class="m">10</span> https://redirector.gvt1.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果强制 socks 也失败，说明不是路由规则顺序问题，而是当前节点或服务端出站本身连不上这些域名。</p>
<p>当时测试结果就是强制 socks 也失败：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">TLS connect error: unexpected eof while reading
</span></span></code></pre></td></tr></table>
</div>
</div><p>因此定位为当前节点对 <code>services.googleapis.cn</code> 和 <code>redirector.gvt1.com</code> 的 TLS 握手不正常。</p>
<h2 id="修复办法">
<a class="header-anchor" href="#%e4%bf%ae%e5%a4%8d%e5%8a%9e%e6%b3%95"></a>
修复办法
</h2><p>最终调整 v2rayNG 路由，让 Play 下载相关域名明确走代理，并确保规则在 <code>geosite:cn</code> 直连规则前面：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">full:services.googleapis.cn
</span></span><span class="line"><span class="cl">full:redirector.gvt1.com
</span></span><span class="line"><span class="cl">domain:gvt1.com
</span></span><span class="line"><span class="cl">domain:googleapis.cn
</span></span><span class="line"><span class="cl">domain:googleusercontent.com
</span></span><span class="line"><span class="cl">geosite:google
</span></span></code></pre></td></tr></table>
</div>
</div><p>出站选择 <code>proxy</code>。</p>
<p>如果用的是简单路由界面，逻辑应该是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">代理：
</span></span><span class="line"><span class="cl">full:services.googleapis.cn
</span></span><span class="line"><span class="cl">full:redirector.gvt1.com
</span></span><span class="line"><span class="cl">domain:gvt1.com
</span></span><span class="line"><span class="cl">domain:googleapis.cn
</span></span><span class="line"><span class="cl">domain:googleusercontent.com
</span></span><span class="line"><span class="cl">geosite:google
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">直连：
</span></span><span class="line"><span class="cl">geosite:cn
</span></span><span class="line"><span class="cl">geoip:cn
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意：<code>services.googleapis.cn</code> 虽然是 <code>.cn</code> 域名，但它是 Google Play 下载入口，不能让它被 <code>geosite:cn</code> 提前命中走直连。</p>
<p>调整后重新测试：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://redirector.gvt1.com
</span></span><span class="line"><span class="cl">curl --socks5-hostname 127.0.0.1:10808 -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span><span class="line"><span class="cl">curl --socks5-hostname 127.0.0.1:10808 -I --connect-timeout <span class="m">10</span> https://redirector.gvt1.com
</span></span></code></pre></td></tr></table>
</div>
</div><p>正常结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">services.googleapis.cn   HTTP/2 404
</span></span><span class="line"><span class="cl">redirector.gvt1.com      HTTP/2 404
</span></span></code></pre></td></tr></table>
</div>
</div><p>出现 404 没关系，说明 TLS/HTTPS 已经通了。</p>
<p>最后强停 Play 商店和下载管理器，再重新下载：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;am force-stop com.android.vending; am force-stop com.android.providers.downloads; am force-stop com.google.android.gms&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后打开 Google Play，取消旧的等待任务，重新点安装。</p>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>这次问题有三层：</p>
<ol>
<li>下载管理器里曾经残留一个只允许 Wi-Fi 且绑定旧网络的 Play 下载任务，需要删除。</li>
<li>Play 下载服务使用 Cronet，失败时界面会显示“等待中”，日志里实际是 <code>CANNOT_CONNECT (8)</code>。</li>
<li>真正导致下载失败的域名是 <code>services.googleapis.cn</code>，它虽然属于 <code>.cn</code>，但应该走代理，不能被 <code>geosite:cn</code> 规则直连。</li>
</ol>
<p>最有用的几条排查命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">su -c <span class="s1">&#39;content query --uri content://downloads/all_downloads&#39;</span>
</span></span><span class="line"><span class="cl">su -c <span class="s1">&#39;logcat -d -t 3000 | grep -Ei &#34;Finsky|DownloadService|CronetDownloader|CANNOT_CONNECT|ERR_CONNECTION|ERR_QUIC&#34;&#39;</span>
</span></span><span class="line"><span class="cl">curl -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span><span class="line"><span class="cl">curl --socks5-hostname 127.0.0.1:10808 -I --connect-timeout <span class="m">10</span> https://services.googleapis.cn
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果 <code>curl --socks5-hostname 127.0.0.1:10808</code> 都连不上，那就不是 v2rayNG 路由写法的问题，而是节点或服务端出站本身的问题。</p>

        
        <hr><p>本文2026-06-05首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-06-05</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Claude Code与Codebuddy Code配置自动审批与无代理fetch全攻略</title>
      <link>https://csdn.fjh1997.top/posts/73921.html</link>
      <pubDate>Tue, 02 Jun 2026 12:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/73921.html</guid>
      <description>
        <![CDATA[<h1>Claude Code与Codebuddy Code配置自动审批与无代理fetch全攻略</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>用 AI 编程工具最烦的两件事：一是每次执行命令都要点&quot;同意&quot;，二是 WebFetch/WebSearch 在国内网络环境下动不动就超时。本文分别介绍 Claude Code 和 Codebuddy Code 如何配置自动审批权限，以及如何让 fetch 类命令在无代理（翻墙）情况下正常工作。</p>
<h2 id="一claude-code-配置">
<a class="header-anchor" href="#%e4%b8%80claude-code-%e9%85%8d%e7%bd%ae"></a>
一、Claude Code 配置
</h2><p>Claude Code 的配置文件位于 <code>~/.claude/settings.json</code>（Windows 为 <code>%USERPROFILE%\.claude\settings.json</code>）。</p>
<h3 id="11-自动审批无需手动确认">
<a class="header-anchor" href="#11-%e8%87%aa%e5%8a%a8%e5%ae%a1%e6%89%b9%e6%97%a0%e9%9c%80%e6%89%8b%e5%8a%a8%e7%a1%ae%e8%ae%a4"></a>
1.1 自动审批（无需手动确认）
</h3><p>Claude Code 的权限系统核心是 <code>defaultMode</code>，它决定了工具调用的默认审批行为。将其设为 <code>bypassPermissions</code> 即可跳过所有权限弹窗：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;defaultMode&#34;</span><span class="p">:</span> <span class="s2">&#34;bypassPermissions&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;allow&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Bash(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebFetch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebSearch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Edit(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Write(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Read(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;NotebookEdit(*)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong><code>defaultMode</code> 的可选值</strong>（这是 Claude Code 权限系统的关键，很多人只配了 <code>allow</code> 却没生效，就是缺了这个）：</p>
<table>
  <thead>
      <tr>
          <th>模式</th>
          <th>行为</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>default</code></td>
          <td>标准行为：首次使用每个工具时弹窗确认</td>
      </tr>
      <tr>
          <td><code>acceptEdits</code></td>
          <td>自动接受文件编辑和常见文件操作（mkdir、touch、mv、cp 等）</td>
      </tr>
      <tr>
          <td><code>plan</code></td>
          <td>计划模式：只读，不编辑源文件</td>
      </tr>
      <tr>
          <td><code>auto</code></td>
          <td>自动审批工具调用，但有后台安全检查（研究预览功能）</td>
      </tr>
      <tr>
          <td><code>dontAsk</code></td>
          <td>未在 <code>allow</code> 中预审批的工具自动拒绝（而非弹窗询问）</td>
      </tr>
      <tr>
          <td><strong><code>bypassPermissions</code></strong></td>
          <td><strong>跳过所有权限弹窗</strong>，仅保留 <code>rm -rf /</code> 和 <code>rm -rf ~</code> 的硬编码熔断保护</td>
      </tr>
  </tbody>
</table>
<p><strong>为什么 <code>defaultMode</code> 才是关键</strong>：只配 <code>allow</code> 列表而不设 <code>defaultMode</code>，Claude Code 仍然会对未匹配的工具弹出确认框。<code>bypassPermissions</code> 是全局开关，<code>allow</code> 列表则用于更细粒度的控制（如只允许特定命令 <code>Bash(npm run *)</code> 而非全部）。两者配合使用效果最佳。</p>
<blockquote>
<p>⚠️ <code>bypassPermissions</code> 会跳过对 <code>.git</code>、<code>.claude</code>、<code>.vscode</code> 等目录的写入保护，建议仅在隔离环境（容器、虚拟机）中使用。</p>
</blockquote>
<p>如果你还想跳过危险模式的二次确认提示，再加上：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;skipDangerousModePermissionPrompt&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="12-让-fetch-在国内网络下可用">
<a class="header-anchor" href="#12-%e8%ae%a9-fetch-%e5%9c%a8%e5%9b%bd%e5%86%85%e7%bd%91%e7%bb%9c%e4%b8%8b%e5%8f%af%e7%94%a8"></a>
1.2 让 Fetch 在国内网络下可用
</h3><p>Claude Code 的 WebFetch 和 WebSearch 需要访问外部 API，在国内直连经常超时。解决方法是配置 HTTP 代理环境变量，在 <code>settings.json</code> 的 <code>env</code> 字段中设置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;env&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;http_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;https_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>其中 <code>10808</code> 是你本地代理客户端（如 Clash/V2Ray）的 HTTP 代理端口，请按实际情况修改。</p>
</blockquote>
<p>另外，如果你使用的代理存在自签证书，还需要设置跳过 TLS 验证（启动 Claude Code 前在终端执行）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nv">$env:NODE_TLS_REJECT_UNAUTHORIZED</span> <span class="p">=</span> <span class="s2">&#34;0&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="13-其他实用配置">
<a class="header-anchor" href="#13-%e5%85%b6%e4%bb%96%e5%ae%9e%e7%94%a8%e9%85%8d%e7%bd%ae"></a>
1.3 其他实用配置
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;opus&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;theme&#34;</span><span class="p">:</span> <span class="s2">&#34;dark&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;autoUpdates&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;skipWebFetchPreflight&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>model</code>：指定默认模型</li>
<li><code>skipWebFetchPreflight</code>：跳过 WebFetch 的预检请求（OPTIONS），某些代理环境下 preflight 会被拦截，开启后直接发 GET 请求</li>
</ul>
<h3 id="14-claude-code-完整配置参考">
<a class="header-anchor" href="#14-claude-code-%e5%ae%8c%e6%95%b4%e9%85%8d%e7%bd%ae%e5%8f%82%e8%80%83"></a>
1.4 Claude Code 完整配置参考
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;enabledPlugins&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rust-analyzer-lsp@claude-plugins-official&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;env&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;http_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;https_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;model&#34;</span><span class="p">:</span> <span class="s2">&#34;opus&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;theme&#34;</span><span class="p">:</span> <span class="s2">&#34;dark&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;autoUpdates&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;skipWebFetchPreflight&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;skipDangerousModePermissionPrompt&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;defaultMode&#34;</span><span class="p">:</span> <span class="s2">&#34;bypassPermissions&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;allow&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Bash(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebFetch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebSearch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Edit(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Write(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Read(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;NotebookEdit(*)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="二codebuddy-code-配置">
<a class="header-anchor" href="#%e4%ba%8ccodebuddy-code-%e9%85%8d%e7%bd%ae"></a>
二、Codebuddy Code 配置
</h2><p>Codebuddy Code 的配置文件位于 <code>~/.codebuddy/config.json</code>（Windows 为 <code>%USERPROFILE%\.codebuddy\config.json</code>）。</p>
<h3 id="21-自动审批">
<a class="header-anchor" href="#21-%e8%87%aa%e5%8a%a8%e5%ae%a1%e6%89%b9"></a>
2.1 自动审批
</h3><p>Codebuddy Code 同样采用 <code>defaultMode</code> + <code>allow</code> 白名单的权限模型，配置方式与 Claude Code 一致：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;defaultMode&#34;</span><span class="p">:</span> <span class="s2">&#34;bypassPermissions&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;allow&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Bash(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebFetch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebSearch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Edit(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Write(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Read(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;NotebookEdit(*)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li><code>defaultMode: &quot;bypassPermissions&quot;</code> 是关键全局开关，跳过所有权限审批</li>
<li><code>allow</code> 列表定义了具体允许的工具操作，与 Claude Code 的写法一致</li>
</ul>
<h3 id="22-让-fetch-正常工作">
<a class="header-anchor" href="#22-%e8%ae%a9-fetch-%e6%ad%a3%e5%b8%b8%e5%b7%a5%e4%bd%9c"></a>
2.2 让 Fetch 正常工作
</h3><p>和 Claude Code 类似，在 <code>env</code> 字段中配置代理：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;env&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;http_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;https_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果代理有自签证书问题，启动前同样需要设置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nv">$env:NODE_TLS_REJECT_UNAUTHORIZED</span> <span class="p">=</span> <span class="s2">&#34;0&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="23-codebuddy-code-完整配置参考">
<a class="header-anchor" href="#23-codebuddy-code-%e5%ae%8c%e6%95%b4%e9%85%8d%e7%bd%ae%e5%8f%82%e8%80%83"></a>
2.3 Codebuddy Code 完整配置参考
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;env&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;http_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;https_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://127.0.0.1:10808&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;defaultMode&#34;</span><span class="p">:</span> <span class="s2">&#34;bypassPermissions&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;allow&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Bash(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebFetch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;WebSearch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Edit(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Write(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;Read(*)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;NotebookEdit(*)&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="三无代理环境下的替代方案">
<a class="header-anchor" href="#%e4%b8%89%e6%97%a0%e4%bb%a3%e7%90%86%e7%8e%af%e5%a2%83%e4%b8%8b%e7%9a%84%e6%9b%bf%e4%bb%a3%e6%96%b9%e6%a1%88"></a>
三、无代理环境下的替代方案
</h2><p>如果你没有本地代理客户端，还有几种方式让 Fetch 生效：</p>
<h3 id="方案-a使用系统代理">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-a%e4%bd%bf%e7%94%a8%e7%b3%bb%e7%bb%9f%e4%bb%a3%e7%90%86"></a>
方案 A：使用系统代理
</h3><p>如果公司/学校网络有统一代理，直接把代理地址填入 <code>env</code> 即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;env&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;http_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://proxy.company.com:8080&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;https_proxy&#34;</span><span class="p">:</span> <span class="s2">&#34;http://proxy.company.com:8080&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="方案-bcloudflare-worker-反代">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-bcloudflare-worker-%e5%8f%8d%e4%bb%a3"></a>
方案 B：Cloudflare Worker 反代
</h3><p>对于 WebFetch 抓取特定网站的场景，可以部署一个 Cloudflare Worker 作为反向代理，然后在工具中直接访问 Worker 地址，无需翻墙。具体方法参考之前的<a href="https://blog.csdn.net/fjh1997/article/details/135051515" target="_blank" rel="noopener noreferrer nofollow">文章</a>
。</p>
<h3 id="方案-c跳过-preflight-请求">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88-c%e8%b7%b3%e8%bf%87-preflight-%e8%af%b7%e6%b1%82"></a>
方案 C：跳过 Preflight 请求
</h3><p>部分代理环境会拦截 OPTIONS 预检请求导致 WebFetch 失败。Claude Code 可设置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;skipWebFetchPreflight&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Codebuddy Code 中同样有类似配置项，开启后直接发送 GET 请求，绕过 preflight。</p>
<h2 id="四安全提醒">
<a class="header-anchor" href="#%e5%9b%9b%e5%ae%89%e5%85%a8%e6%8f%90%e9%86%92"></a>
四、安全提醒
</h2><p>自动审批模式虽然方便，但也意味着 AI 工具可以不经确认地执行任何命令、读写任何文件。建议：</p>
<ol>
<li><strong>仅在受控环境中使用</strong>，不要在生产服务器上开启</li>
<li><strong>定期检查操作日志</strong>，确认没有误操作</li>
<li><strong>敏感目录可以用 <code>deny</code> 列表排除</strong>，例如：
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;defaultMode&#34;</span><span class="p">:</span> <span class="s2">&#34;bypassPermissions&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;allow&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Bash(*)&#34;</span><span class="p">,</span> <span class="s2">&#34;Read(*)&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;deny&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;Bash(rm -rf /*)&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
<hr>
<p>配置完成后，AI 编程助手就能丝滑地自动执行命令和访问网络了，再也不用频繁点确认了。</p>

        
        <hr><p>本文2026-06-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-06-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>记录一次因 Nginx 转发 H3 速度慢而改用 Envoy 前置 Xray XHTTP</title>
      <link>https://csdn.fjh1997.top/posts/20260523.html</link>
      <pubDate>Sat, 23 May 2026 21:56:28 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/20260523.html</guid>
      <description>
        <![CDATA[<h1>记录一次因 Nginx 转发 H3 速度慢而改用 Envoy 前置 Xray XHTTP</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="前言">
<a class="header-anchor" href="#%e5%89%8d%e8%a8%80"></a>
前言
</h2><p>这次记录的是一套代理服务端配置的调整过程：最开始尝试用 Nginx 做前置转发 Xray XHTTP，但 H3/UDP 下行经过 Nginx 后速度明显偏低；同样的 Xray 直连 H3 诊断入口可以跑满，所以瓶颈基本可以定位在前置层。最后把公网入口改成 Envoy，由 Envoy 接管 TCP/443 的 HTTPS/H2 和 UDP/443 的 HTTP/3，再把 XHTTP 流量转发给本机 Xray，把普通网页流量转发给本机 Nginx 伪装站。</p>
<p>简单对比一下当时的测试结果：</p>
<table>
  <thead>
      <tr>
          <th>方案</th>
          <th>下行表现</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>XHTTP H2 上行 + H2 下行</td>
          <td>约 334-339 Mbps</td>
          <td>不走 H3 下行时基本正常</td>
      </tr>
      <tr>
          <td>XHTTP H2 上行 + H3 下行，经 Nginx 前置</td>
          <td>约 7-15 Mbps</td>
          <td>主要瓶颈出现在 Nginx 前置转发 H3</td>
      </tr>
      <tr>
          <td>XHTTP H3 直连 Xray 9443 诊断口</td>
          <td>约 367 Mbps</td>
          <td>说明 Xray 自身和线路并不是主要瓶颈</td>
      </tr>
      <tr>
          <td>Caddy 前置 H3</td>
          <td>约 41 Mbps</td>
          <td>比 Nginx 好，但仍不理想</td>
      </tr>
      <tr>
          <td>Envoy 前置 H3</td>
          <td>作为最终方案</td>
          <td>用 Envoy 替代 Nginx 做公网 H3 入口</td>
      </tr>
  </tbody>
</table>
<p>为了避免泄露真实信息，本文里的域名、UUID、密码、统计密钥、XHTTP 路径 token 都已经脱敏。直接复制前需要把占位符替换成自己的值。</p>
<h2 id="当前架构">
<a class="header-anchor" href="#%e5%bd%93%e5%89%8d%e6%9e%b6%e6%9e%84"></a>
当前架构
</h2><p>调整后的架构里，Nginx 不再作为公网 443 前置，只保留为本机静态伪装站后端；公网 TCP/80、TCP/443、UDP/443 都交给 Envoy。</p>
<p>公网入口：</p>
<table>
  <thead>
      <tr>
          <th>端口</th>
          <th>协议</th>
          <th>服务</th>
          <th>作用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>TCP/80</td>
          <td>HTTP</td>
          <td>Envoy</td>
          <td>HTTP 跳转 HTTPS，ACME challenge 转发到 Nginx</td>
      </tr>
      <tr>
          <td>TCP/443</td>
          <td>HTTPS/H2</td>
          <td>Envoy</td>
          <td>XHTTP 上行、普通 HTTPS 伪装站</td>
      </tr>
      <tr>
          <td>UDP/443</td>
          <td>HTTP/3</td>
          <td>Envoy</td>
          <td>XHTTP H3 下行、普通 H3 入口</td>
      </tr>
      <tr>
          <td>UDP/9443</td>
          <td>Xray</td>
          <td>XHTTP/H3 诊断入口</td>
          <td>绕过前置的测试入口，不作为常规使用</td>
      </tr>
  </tbody>
</table>
<p>本机后端：</p>
<table>
  <thead>
      <tr>
          <th>地址</th>
          <th>服务</th>
          <th>作用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>127.0.0.1:10000</td>
          <td>Xray</td>
          <td>Envoy 转发过来的 XHTTP 后端</td>
      </tr>
      <tr>
          <td>127.0.0.1:10085</td>
          <td>Xray API</td>
          <td>stats、在线用户、限额脚本</td>
      </tr>
      <tr>
          <td>127.0.0.1:18080</td>
          <td>Nginx</td>
          <td>伪装站和 ACME challenge</td>
      </tr>
      <tr>
          <td>127.0.0.1:9901</td>
          <td>Envoy admin</td>
          <td>Envoy 本机管理接口</td>
      </tr>
  </tbody>
</table>
<p>软件版本：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Xray 26.3.27
</span></span><span class="line"><span class="cl">Envoy 1.32.2
</span></span><span class="line"><span class="cl">nginx 1.31.1
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="xray-配置">
<a class="header-anchor" href="#xray-%e9%85%8d%e7%bd%ae"></a>
Xray 配置
</h2><p>配置文件路径：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">/usr/local/etc/xray/config.json
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里 Xray 只监听本机 XHTTP 后端和 API，TLS/H2/H3 由 Envoy 在公网侧处理。<code>diag-xhttp-h3-direct</code> 是直连 H3 诊断入口，用来判断瓶颈是否来自前置代理。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;loglevel&#34;</span><span class="p">:</span> <span class="s2">&#34;warning&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;access&#34;</span><span class="p">:</span> <span class="s2">&#34;/var/log/xray/access.log&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;error&#34;</span><span class="p">:</span> <span class="s2">&#34;/var/log/xray/error.log&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;api&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;api&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;services&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;HandlerService&#34;</span><span class="p">,</span> <span class="s2">&#34;StatsService&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;stats&#34;</span><span class="p">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;policy&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;levels&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;0&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;statsUserUplink&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;statsUserDownlink&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;statsUserOnline&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;system&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;statsInboundUplink&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;statsInboundDownlink&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;statsOutboundUplink&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;statsOutboundDownlink&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;inbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;api-in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">10085</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;reality-in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;/dev/shm/xrxh.socket,0666&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-50G&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-50g@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-1&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-2&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited2@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;xhttp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;xhttpSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;mode&#34;</span><span class="p">:</span> <span class="s2">&#34;stream-up&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;routeOnly&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;xhttp-caddy-backend&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">10000</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-50G&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-50g@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-1&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-2&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited2@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;xhttp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;xhttpSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;mode&#34;</span><span class="p">:</span> <span class="s2">&#34;stream-up&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;routeOnly&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;diag-xhttp-h3-direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">9443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-50G&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-50g@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-1&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">},</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;UUID-UNLIMITED-2&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;email&#34;</span><span class="p">:</span> <span class="s2">&#34;client-unlimited2@local&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;xhttp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tlsSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;alpn&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;h3&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;minVersion&#34;</span><span class="p">:</span> <span class="s2">&#34;1.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;certificates&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nt">&#34;certificateFile&#34;</span><span class="p">:</span> <span class="s2">&#34;/usr/local/etc/xray/certs/fullchain.pem&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">              <span class="nt">&#34;keyFile&#34;</span><span class="p">:</span> <span class="s2">&#34;/usr/local/etc/xray/certs/privkey.pem&#34;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;xhttpSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;mode&#34;</span><span class="p">:</span> <span class="s2">&#34;auto&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;routeOnly&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;blackhole&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;blocked&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;domainStrategy&#34;</span><span class="p">:</span> <span class="s2">&#34;IPIfNonMatch&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;api-in&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;api&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;geoip:cn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;blocked&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;geosite:cn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;blocked&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;geoip:private&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;blocked&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bittorrent&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;blocked&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里有两个关键点：</p>
<ol>
<li><code>policy</code> 里开启了用户上行、下行和在线统计，所以 <code>xray api statsquery</code>、<code>statsonline</code>、<code>statsonlineiplist</code> 可以正常使用。</li>
<li>路由里拒绝了中国 IP、中国域名、私网地址和 BitTorrent，避免节点被拿来访问国内或跑 BT。</li>
</ol>
<h2 id="envoy-配置">
<a class="header-anchor" href="#envoy-%e9%85%8d%e7%bd%ae"></a>
Envoy 配置
</h2><p>配置文件路径：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">/etc/envoy/envoy.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>Envoy 的作用是统一接管公网 TCP/80、TCP/443、UDP/443。TCP/443 提供 H2，UDP/443 提供 H3；命中 XHTTP 随机路径的请求转给 Xray，其他请求转给 Nginx 伪装站。</p>
<p>之所以让 Envoy 接管公网入口，是因为 Nginx 做 H3/UDP 前置时下行速度明显掉到十几 Mbps，和 Xray 直连 H3 的三百多 Mbps 不在一个量级。Envoy 的 HTTP/3 支持更适合这个场景，也方便同时保留 HTTP 跳转、ACME challenge 和普通伪装站路由。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span><span class="lnt">341
</span><span class="lnt">342
</span><span class="lnt">343
</span><span class="lnt">344
</span><span class="lnt">345
</span><span class="lnt">346
</span><span class="lnt">347
</span><span class="lnt">348
</span><span class="lnt">349
</span><span class="lnt">350
</span><span class="lnt">351
</span><span class="lnt">352
</span><span class="lnt">353
</span><span class="lnt">354
</span><span class="lnt">355
</span><span class="lnt">356
</span><span class="lnt">357
</span><span class="lnt">358
</span><span class="lnt">359
</span><span class="lnt">360
</span><span class="lnt">361
</span><span class="lnt">362
</span><span class="lnt">363
</span><span class="lnt">364
</span><span class="lnt">365
</span><span class="lnt">366
</span><span class="lnt">367
</span><span class="lnt">368
</span><span class="lnt">369
</span><span class="lnt">370
</span><span class="lnt">371
</span><span class="lnt">372
</span><span class="lnt">373
</span><span class="lnt">374
</span><span class="lnt">375
</span><span class="lnt">376
</span><span class="lnt">377
</span><span class="lnt">378
</span><span class="lnt">379
</span><span class="lnt">380
</span><span class="lnt">381
</span><span class="lnt">382
</span><span class="lnt">383
</span><span class="lnt">384
</span><span class="lnt">385
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">admin</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">9901</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">static_resources</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">listeners</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_http_redirect_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;::&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ipv4_compat</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">http_redirect_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">http_redirect_route_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">redirect_all_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/.well-known/acme-challenge/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">redirect</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">https_redirect</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_http_redirect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">80</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">http_redirect</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">http_redirect_route</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">redirect_all</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/.well-known/acme-challenge/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">redirect</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">https_redirect</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_https_tcp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">codec_type</span><span class="p">:</span><span class="w"> </span><span class="l">AUTO</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">https_tcp_ingress</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stream_idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">request_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_http_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http2_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">max_concurrent_streams</span><span class="p">:</span><span class="w"> </span><span class="m">1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">initial_stream_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">initial_connection_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">16777216</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">upgrade_configs</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">upgrade_type</span><span class="p">:</span><span class="w"> </span><span class="l">CONNECT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">https_route</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">xhttp_hosts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&lt;UPLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">response_headers_to_add</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">alt-svc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">h3=&#34;:443&#34;; ma=86400</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">append_action</span><span class="p">:</span><span class="w"> </span><span class="l">OVERWRITE_IF_EXISTS_OR_ADD</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">x-content-type-options</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">nosniff</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">referrer-policy</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">strict-origin-when-cross-origin</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">0s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix_rewrite</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">default_host</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">transport_socket</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.transport_sockets.tls</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">alpn_protocols</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;h2&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;http/1.1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">tls_certificates</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">certificate_chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/fullchain.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">private_key</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/privkey.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_https_tcp_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;::&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ipv4_compat</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">codec_type</span><span class="p">:</span><span class="w"> </span><span class="l">AUTO</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">https_tcp_ingress_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stream_idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">request_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_http_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http2_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">max_concurrent_streams</span><span class="p">:</span><span class="w"> </span><span class="m">1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">initial_stream_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">initial_connection_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">16777216</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">https_route_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">xhttp_hosts_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&lt;UPLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">response_headers_to_add</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">alt-svc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">h3=&#34;:443&#34;; ma=86400</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">append_action</span><span class="p">:</span><span class="w"> </span><span class="l">OVERWRITE_IF_EXISTS_OR_ADD</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">0s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">default_host_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">transport_socket</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.transport_sockets.tls</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">alpn_protocols</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;h2&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;http/1.1&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">tls_certificates</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">certificate_chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/fullchain.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">private_key</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/privkey.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_https_quic_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">UDP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;::&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ipv4_compat</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">udp_listener_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">quic_options</span><span class="p">:</span><span class="w"> </span>{}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">codec_type</span><span class="p">:</span><span class="w"> </span><span class="l">HTTP3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">https_quic_ingress_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stream_idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">request_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_http_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http3_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">quic_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">max_concurrent_streams</span><span class="p">:</span><span class="w"> </span><span class="m">1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">initial_stream_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">initial_connection_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">16777216</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">https_quic_route_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">xhttp_hosts_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&lt;UPLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">response_headers_to_add</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">alt-svc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">h3=&#34;:443&#34;; ma=86400</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">append_action</span><span class="p">:</span><span class="w"> </span><span class="l">OVERWRITE_IF_EXISTS_OR_ADD</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">0s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">default_host_v6</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">transport_socket</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.transport_sockets.quic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">downstream_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">common_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">alpn_protocols</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;h3&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">tls_certificates</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">certificate_chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/fullchain.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">private_key</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/privkey.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">listener_https_quic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">protocol</span><span class="p">:</span><span class="w"> </span><span class="l">UDP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">udp_listener_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">quic_options</span><span class="p">:</span><span class="w"> </span>{}<span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">filter_chains</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="nt">filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.network.http_connection_manager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">codec_type</span><span class="p">:</span><span class="w"> </span><span class="l">HTTP3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stat_prefix</span><span class="p">:</span><span class="w"> </span><span class="l">https_quic_ingress</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">stream_idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">request_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">common_http_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http3_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">quic_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">max_concurrent_streams</span><span class="p">:</span><span class="w"> </span><span class="m">1024</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">initial_stream_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">initial_connection_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">16777216</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">route_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">https_quic_route</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">virtual_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">xhttp_hosts</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;&lt;UPLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span><span class="w"> </span><span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">response_headers_to_add</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">header</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l">alt-svc</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span><span class="l">h3=&#34;:443&#34;; ma=86400</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">append_action</span><span class="p">:</span><span class="w"> </span><span class="l">OVERWRITE_IF_EXISTS_OR_ADD</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">0s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">idle_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">3600s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">default_host</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">domains</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;*&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">routes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">match</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">prefix</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;/&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">route</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">cluster</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">timeout</span><span class="p">:</span><span class="w"> </span><span class="l">60s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">http_filters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.filters.http.router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.filters.http.router.v3.Router</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">transport_socket</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">envoy.transport_sockets.quic</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">typed_config</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">&#34;@type&#34;: </span><span class="l">type.googleapis.com/envoy.extensions.transport_sockets.quic.v3.QuicDownstreamTransport</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">downstream_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">common_tls_context</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">alpn_protocols</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s2">&#34;h3&#34;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">tls_certificates</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span>- <span class="nt">certificate_chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/fullchain.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">private_key</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                  </span><span class="nt">filename</span><span class="p">:</span><span class="w"> </span><span class="l">/etc/envoy/certs/privkey.pem</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">clusters</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">connect_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">5s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">STATIC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">lb_policy</span><span class="p">:</span><span class="w"> </span><span class="l">ROUND_ROBIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">http2_protocol_options</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">initial_stream_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">1048576</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">initial_connection_window_size</span><span class="p">:</span><span class="w"> </span><span class="m">16777216</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">load_assignment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cluster_name</span><span class="p">:</span><span class="w"> </span><span class="l">xray_xhttp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">endpoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">lb_endpoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">endpoint</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">10000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">connect_timeout</span><span class="p">:</span><span class="w"> </span><span class="l">5s</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">STATIC</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">lb_policy</span><span class="p">:</span><span class="w"> </span><span class="l">ROUND_ROBIN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">load_assignment</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">cluster_name</span><span class="p">:</span><span class="w"> </span><span class="l">nginx_site</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">endpoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">lb_endpoints</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">endpoint</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="nt">address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">socket_address</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">address</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">                </span><span class="nt">port_value</span><span class="p">:</span><span class="w"> </span><span class="m">18080</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>当时测试过几种前置方式，H3 经过 Nginx Stream 时下行明显掉速，Caddy 有改善但仍不理想，最后切到 Envoy 做 HTTP/3 入口。实际环境里建议保留一个 Xray 直连 H3 诊断端口，用来判断是 Xray 自身、前置代理还是网络路径造成的瓶颈。</p>
<h2 id="nginx-伪装站配置">
<a class="header-anchor" href="#nginx-%e4%bc%aa%e8%a3%85%e7%ab%99%e9%85%8d%e7%bd%ae"></a>
Nginx 伪装站配置
</h2><p>Nginx 不再监听公网 80/443，也不再承担 H3/UDP 前置转发。它只监听本机端口，作为 Envoy 的静态伪装站后端。这样既保留 Nginx 处理静态文件的简单性，又避开了它在这次 H3 转发测试中的速度瓶颈。</p>
<p>主配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="k">user</span>  <span class="s">nginx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">worker_processes</span>  <span class="s">auto</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">worker_rlimit_nofile</span>  <span class="mi">200000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">error_log</span>  <span class="s">/var/log/nginx/error.log</span> <span class="s">notice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">pid</span>        <span class="s">/run/nginx.pid</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">events</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">worker_connections</span>  <span class="mi">8192</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">http</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">include</span>       <span class="s">/etc/nginx/mime.types</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">default_type</span>  <span class="s">application/octet-stream</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">log_format</span>  <span class="s">main</span>  <span class="s">&#39;</span><span class="nv">$remote_addr</span> <span class="s">-</span> <span class="nv">$remote_user</span> <span class="s">[</span><span class="nv">$time_local]</span> <span class="s">&#34;</span><span class="nv">$request&#34;</span> <span class="s">&#39;</span>
</span></span><span class="line"><span class="cl">                      <span class="s">&#39;</span><span class="nv">$status</span> <span class="nv">$body_bytes_sent</span> <span class="s">&#34;</span><span class="nv">$http_referer&#34;</span> <span class="s">&#39;</span>
</span></span><span class="line"><span class="cl">                      <span class="s">&#39;&#34;</span><span class="nv">$http_user_agent&#34;</span> <span class="s">&#34;</span><span class="nv">$http_x_forwarded_for&#34;&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">access_log</span>  <span class="s">/var/log/nginx/access.log</span>  <span class="s">main</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">sendfile</span>        <span class="no">on</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">keepalive_timeout</span>  <span class="mi">65</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">keepalive_requests</span> <span class="mi">10000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">client_body_buffer_size</span> <span class="mi">32m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">client_body_timeout</span> <span class="mi">5m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">send_timeout</span> <span class="mi">5m</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">proxy_buffering</span> <span class="no">off</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">include</span> <span class="s">/etc/nginx/conf.d/*.conf</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>伪装站配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">18080</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">server_name</span> <span class="s">&lt;UPLOAD-DOMAIN&gt;</span> <span class="s">&lt;DOWNLOAD-DOMAIN&gt;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">root</span> <span class="s">/var/www/fjh-site</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">index</span> <span class="s">index.html</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="s">/.well-known/acme-challenge/</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">root</span> <span class="s">/var/www/letsencrypt</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri/</span> <span class="s">/index.html</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>默认站也改成本机监听，避免和 Envoy 的公网端口冲突：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-nginx" data-lang="nginx"><span class="line"><span class="cl"><span class="k">server</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kn">listen</span> <span class="n">127.0.0.1</span><span class="p">:</span><span class="mi">18081</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">server_name</span> <span class="s">localhost</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="s">/</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">root</span> <span class="s">/usr/share/nginx/html</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="kn">index</span> <span class="s">index.html</span> <span class="s">index.htm</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kn">error_page</span> <span class="mi">500</span> <span class="mi">502</span> <span class="mi">503</span> <span class="mi">504</span> <span class="s">/50x.html</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kn">location</span> <span class="p">=</span> <span class="s">/50x.html</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kn">root</span> <span class="s">/usr/share/nginx/html</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="caddy-备用配置">
<a class="header-anchor" href="#caddy-%e5%a4%87%e7%94%a8%e9%85%8d%e7%bd%ae"></a>
Caddy 备用配置
</h2><p>当前 Caddy 是 disabled，不参与公网入口。机器上仍保留过一版 Caddyfile，方便后续需要时切回 Caddy 前置。这里同样做了脱敏：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-caddyfile" data-lang="caddyfile"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">servers</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">protocols</span> <span class="s">h1</span> <span class="s">h2</span> <span class="s">h3</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gh">&lt;UPLOAD-DOMAIN&gt;</span>, <span class="gh">&lt;DOWNLOAD-DOMAIN&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">tls</span> <span class="s">/etc/caddy/certs/fullchain.pem</span> <span class="s">/etc/caddy/certs/privkey.pem</span>
</span></span><span class="line"><span class="cl">    <span class="k">root</span> <span class="nd">*</span> <span class="s">/var/www/fjh-site</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@acme</span> <span class="k">path</span> <span class="s">/.well-known/acme-challenge/*</span>
</span></span><span class="line"><span class="cl">    <span class="k">handle</span> <span class="nd">@acme</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">root</span> <span class="nd">*</span> <span class="s">/var/www/letsencrypt</span>
</span></span><span class="line"><span class="cl">        <span class="k">file_server</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nd">@xhttp</span> <span class="k">path</span> <span class="s">/api/v1/&lt;XHTTP-PATH-TOKEN&gt;*</span>
</span></span><span class="line"><span class="cl">    <span class="k">reverse_proxy</span> <span class="nd">@xhttp</span> <span class="s">h2c://127.0.0.1:10000</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">header_up</span> <span class="s">Host</span> <span class="se">{host}</span>
</span></span><span class="line"><span class="cl">        <span class="k">flush_interval</span> <span class="s">-1</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">file_server</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="证书部署-hook">
<a class="header-anchor" href="#%e8%af%81%e4%b9%a6%e9%83%a8%e7%bd%b2-hook"></a>
证书部署 Hook
</h2><p>证书由 Let&rsquo;s Encrypt 生成后，通过 deploy hook 同步到 Envoy、Xray 等服务目录，并重载或重启相关服务。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl"><span class="cp">#!/usr/bin/env sh
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -eu
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">install -d -o root -g caddy -m <span class="m">750</span> /etc/caddy/certs
</span></span><span class="line"><span class="cl">install -o root -g caddy -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/fullchain.pem /etc/caddy/certs/fullchain.pem
</span></span><span class="line"><span class="cl">install -o root -g caddy -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/privkey.pem /etc/caddy/certs/privkey.pem
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">install -d -o root -g envoy -m <span class="m">750</span> /etc/envoy/certs
</span></span><span class="line"><span class="cl">install -o root -g envoy -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/fullchain.pem /etc/envoy/certs/fullchain.pem
</span></span><span class="line"><span class="cl">install -o root -g envoy -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/privkey.pem /etc/envoy/certs/privkey.pem
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">install -d -o root -g nogroup -m <span class="m">750</span> /usr/local/etc/xray/certs
</span></span><span class="line"><span class="cl">install -o root -g nogroup -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/fullchain.pem /usr/local/etc/xray/certs/fullchain.pem
</span></span><span class="line"><span class="cl">install -o root -g nogroup -m <span class="m">640</span> /etc/letsencrypt/live/&lt;CERT-DOMAIN&gt;/privkey.pem /usr/local/etc/xray/certs/privkey.pem
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> systemctl is-active --quiet nginx<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    systemctl reload nginx &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> systemctl restart nginx &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> systemctl is-active --quiet caddy<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    systemctl reload caddy &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> systemctl restart caddy &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> systemctl is-active --quiet envoy<span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">    systemctl reload envoy &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> systemctl restart envoy &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span><span class="line"><span class="cl">systemctl restart xray &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> <span class="nb">true</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>虽然当前入口已经换成 Envoy，hook 里仍然保留了 Caddy 证书同步和 reload 逻辑，是为了以后切换前置时少改一点东西。当前 Caddy 是 disabled，不参与公网入口。</p>
<p>证书私钥文件、证书链文件、历史备份配置和临时诊断客户端配置不适合原样贴到博客里。本文只记录路径和引用方式，不包含任何 PEM 私钥内容。</p>
<h2 id="systemd-服务">
<a class="header-anchor" href="#systemd-%e6%9c%8d%e5%8a%a1"></a>
systemd 服务
</h2><p>Xray：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Xray Service</span>
</span></span><span class="line"><span class="cl"><span class="na">Documentation</span><span class="o">=</span><span class="s">https://github.com/xtls</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network.target nss-lookup.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">nobody</span>
</span></span><span class="line"><span class="cl"><span class="na">CapabilityBoundingSet</span><span class="o">=</span><span class="s">CAP_NET_ADMIN CAP_NET_BIND_SERVICE</span>
</span></span><span class="line"><span class="cl"><span class="na">AmbientCapabilities</span><span class="o">=</span><span class="s">CAP_NET_ADMIN CAP_NET_BIND_SERVICE</span>
</span></span><span class="line"><span class="cl"><span class="na">NoNewPrivileges</span><span class="o">=</span><span class="s">true</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/local/bin/xray run -config /usr/local/etc/xray/config.json</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">on-failure</span>
</span></span><span class="line"><span class="cl"><span class="na">RestartPreventExitStatus</span><span class="o">=</span><span class="s">23</span>
</span></span><span class="line"><span class="cl"><span class="na">LimitNPROC</span><span class="o">=</span><span class="s">10000</span>
</span></span><span class="line"><span class="cl"><span class="na">LimitNOFILE</span><span class="o">=</span><span class="s">1000000</span>
</span></span><span class="line"><span class="cl"><span class="na">RuntimeDirectory</span><span class="o">=</span><span class="s">xray</span>
</span></span><span class="line"><span class="cl"><span class="na">RuntimeDirectoryMode</span><span class="o">=</span><span class="s">0755</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Envoy：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Envoy Proxy</span>
</span></span><span class="line"><span class="cl"><span class="na">Documentation</span><span class="o">=</span><span class="s">https://www.envoyproxy.io/docs</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl"><span class="na">Wants</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">envoy</span>
</span></span><span class="line"><span class="cl"><span class="na">Group</span><span class="o">=</span><span class="s">envoy</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/envoy -c /etc/envoy/envoy.yaml --concurrency 1 --log-level warning</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">on-failure</span>
</span></span><span class="line"><span class="cl"><span class="na">RestartSec</span><span class="o">=</span><span class="s">3</span>
</span></span><span class="line"><span class="cl"><span class="na">LimitNOFILE</span><span class="o">=</span><span class="s">200000</span>
</span></span><span class="line"><span class="cl"><span class="na">AmbientCapabilities</span><span class="o">=</span><span class="s">CAP_NET_BIND_SERVICE</span>
</span></span><span class="line"><span class="cl"><span class="na">CapabilityBoundingSet</span><span class="o">=</span><span class="s">CAP_NET_BIND_SERVICE</span>
</span></span><span class="line"><span class="cl"><span class="na">NoNewPrivileges</span><span class="o">=</span><span class="s">true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="xray-流量统计和-50gb-限额">
<a class="header-anchor" href="#xray-%e6%b5%81%e9%87%8f%e7%bb%9f%e8%ae%a1%e5%92%8c-50gb-%e9%99%90%e9%a2%9d"></a>
Xray 流量统计和 50GB 限额
</h2><p>Xray 通过 API 统计每个用户的上下行，并用 systemd timer 每分钟运行一次限额脚本。50GB 用户超过累计流量后，通过 Xray API 删除对应用户。</p>
<p><code>/etc/systemd/system/xray-traffic-limit.service</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Xray per-user traffic quota enforcer</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">xray.service</span>
</span></span><span class="line"><span class="cl"><span class="na">Requires</span><span class="o">=</span><span class="s">xray.service</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">oneshot</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/local/bin/xray-traffic-limit.sh</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>/etc/systemd/system/xray-traffic-limit.timer</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Run xray traffic limiter every minute</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Timer]</span>
</span></span><span class="line"><span class="cl"><span class="na">OnBootSec</span><span class="o">=</span><span class="s">1min</span>
</span></span><span class="line"><span class="cl"><span class="na">OnUnitActiveSec</span><span class="o">=</span><span class="s">1min</span>
</span></span><span class="line"><span class="cl"><span class="na">AccuracySec</span><span class="o">=</span><span class="s">10s</span>
</span></span><span class="line"><span class="cl"><span class="na">Unit</span><span class="o">=</span><span class="s">xray-traffic-limit.service</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">timers.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>限额脚本：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="cp">#!/usr/bin/env bash
</span></span></span><span class="line"><span class="cl"><span class="nb">set</span> -euo pipefail
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">API_ADDR</span><span class="o">=</span><span class="s2">&#34;127.0.0.1:10085&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">EMAIL</span><span class="o">=</span><span class="s2">&#34;client-50g@local&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">LIMIT_BYTES</span><span class="o">=</span><span class="k">$((</span><span class="m">50</span> <span class="o">*</span> <span class="m">1024</span> <span class="o">*</span> <span class="m">1024</span> <span class="o">*</span> <span class="m">1024</span><span class="k">))</span>
</span></span><span class="line"><span class="cl"><span class="nv">STATE_DIR</span><span class="o">=</span><span class="s2">&#34;/var/lib/xray-limiter&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">DISABLED_FLAG</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$STATE_DIR</span><span class="s2">/</span><span class="si">${</span><span class="nv">EMAIL</span><span class="si">}</span><span class="s2">.disabled&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">CUM_FILE</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$STATE_DIR</span><span class="s2">/</span><span class="si">${</span><span class="nv">EMAIL</span><span class="si">}</span><span class="s2">.cum&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">LOG_TAG</span><span class="o">=</span><span class="s2">&#34;xray-limiter&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">mkdir -p <span class="s2">&#34;</span><span class="nv">$STATE_DIR</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">get_counter<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">local</span> out
</span></span><span class="line"><span class="cl">  <span class="nv">out</span><span class="o">=</span><span class="k">$(</span>xray api statsquery --server<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$API_ADDR</span><span class="s2">&#34;</span> -reset -pattern <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> 2&gt;/dev/null <span class="o">||</span> <span class="nb">true</span><span class="k">)</span>
</span></span><span class="line"><span class="cl">  <span class="o">[[</span> -z <span class="s2">&#34;</span><span class="nv">$out</span><span class="s2">&#34;</span> <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="o">{</span>
</span></span><span class="line"><span class="cl">    <span class="nb">echo</span> <span class="m">0</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span>
</span></span><span class="line"><span class="cl">  <span class="o">}</span>
</span></span><span class="line"><span class="cl">  <span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$out</span><span class="s2">&#34;</span> <span class="p">|</span> python3 -c <span class="s1">&#39;
</span></span></span><span class="line"><span class="cl"><span class="s1">import sys, json
</span></span></span><span class="line"><span class="cl"><span class="s1">try:
</span></span></span><span class="line"><span class="cl"><span class="s1">    d = json.load(sys.stdin)
</span></span></span><span class="line"><span class="cl"><span class="s1">    v = 0
</span></span></span><span class="line"><span class="cl"><span class="s1">    for s in d.get(&#34;stat&#34;, []):
</span></span></span><span class="line"><span class="cl"><span class="s1">        v += int(s.get(&#34;value&#34;, 0) or 0)
</span></span></span><span class="line"><span class="cl"><span class="s1">    print(v)
</span></span></span><span class="line"><span class="cl"><span class="s1">except Exception:
</span></span></span><span class="line"><span class="cl"><span class="s1">    print(0)
</span></span></span><span class="line"><span class="cl"><span class="s1">&#39;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">UP</span><span class="o">=</span><span class="k">$(</span>get_counter <span class="s2">&#34;user&gt;&gt;&gt;</span><span class="si">${</span><span class="nv">EMAIL</span><span class="si">}</span><span class="s2">&gt;&gt;&gt;traffic&gt;&gt;&gt;uplink&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">DOWN</span><span class="o">=</span><span class="k">$(</span>get_counter <span class="s2">&#34;user&gt;&gt;&gt;</span><span class="si">${</span><span class="nv">EMAIL</span><span class="si">}</span><span class="s2">&gt;&gt;&gt;traffic&gt;&gt;&gt;downlink&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">UP</span><span class="o">=</span><span class="si">${</span><span class="nv">UP</span><span class="k">:-</span><span class="nv">0</span><span class="si">}</span>
</span></span><span class="line"><span class="cl"><span class="nv">DOWN</span><span class="o">=</span><span class="si">${</span><span class="nv">DOWN</span><span class="k">:-</span><span class="nv">0</span><span class="si">}</span>
</span></span><span class="line"><span class="cl"><span class="nv">DELTA</span><span class="o">=</span><span class="k">$((</span>UP <span class="o">+</span> DOWN<span class="k">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">CUM</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="o">[[</span> -f <span class="s2">&#34;</span><span class="nv">$CUM_FILE</span><span class="s2">&#34;</span> <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nv">CUM</span><span class="o">=</span><span class="k">$(</span>cat <span class="s2">&#34;</span><span class="nv">$CUM_FILE</span><span class="s2">&#34;</span><span class="k">)</span>
</span></span><span class="line"><span class="cl"><span class="nv">CUM</span><span class="o">=</span><span class="k">$((</span>CUM <span class="o">+</span> DELTA<span class="k">))</span>
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;</span><span class="nv">$CUM</span><span class="s2">&#34;</span> &gt; <span class="s2">&#34;</span><span class="nv">$CUM_FILE</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">logger -t <span class="s2">&#34;</span><span class="nv">$LOG_TAG</span><span class="s2">&#34;</span> <span class="s2">&#34;email=</span><span class="nv">$EMAIL</span><span class="s2"> delta=</span><span class="nv">$DELTA</span><span class="s2"> cum=</span><span class="nv">$CUM</span><span class="s2"> limit=</span><span class="nv">$LIMIT_BYTES</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="o">((</span> CUM &gt;<span class="o">=</span> LIMIT_BYTES <span class="o">))</span> <span class="o">&amp;&amp;</span> <span class="o">[[</span> ! -f <span class="s2">&#34;</span><span class="nv">$DISABLED_FLAG</span><span class="s2">&#34;</span> <span class="o">]]</span><span class="p">;</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  logger -t <span class="s2">&#34;</span><span class="nv">$LOG_TAG</span><span class="s2">&#34;</span> <span class="s2">&#34;limit exceeded, removing user </span><span class="nv">$EMAIL</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">  xray api rmu --server<span class="o">=</span><span class="s2">&#34;</span><span class="nv">$API_ADDR</span><span class="s2">&#34;</span> -tag<span class="o">=</span>reality-in <span class="s2">&#34;</span><span class="nv">$EMAIL</span><span class="s2">&#34;</span> &gt;/dev/null 2&gt;<span class="p">&amp;</span><span class="m">1</span> <span class="o">||</span> <span class="nb">true</span>
</span></span><span class="line"><span class="cl">  touch <span class="s2">&#34;</span><span class="nv">$DISABLED_FLAG</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">fi</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意：如果 Xray 的入口 tag 改了，限额脚本里的 <code>-tag=reality-in</code> 也要同步修改，否则删除用户不会命中正确 inbound。当前配置里公网 XHTTP 实际走的是 <code>xhttp-caddy-backend</code>，如果需要同时封禁所有入口，脚本里应对相关 inbound tag 都执行一次 <code>rmu</code>。</p>
<h2 id="分享链接模板">
<a class="header-anchor" href="#%e5%88%86%e4%ba%ab%e9%93%be%e6%8e%a5%e6%a8%a1%e6%9d%bf"></a>
分享链接模板
</h2><p>XHTTP 上下行分离的分享链接大致如下。这里把关键值都替换成了占位符：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">vless://&lt;UUID&gt;@&lt;UPLOAD-DOMAIN&gt;:443?encryption=none&amp;security=tls&amp;sni=&lt;UPLOAD-DOMAIN&gt;&amp;fp=chrome&amp;type=xhttp&amp;host=&lt;UPLOAD-DOMAIN&gt;&amp;path=%2Fapi%2Fv1%2F&lt;XHTTP-PATH-TOKEN&gt;&amp;mode=stream-up&amp;alpn=h2&amp;extra=&lt;URL-ENCODED-EXTRA&gt;#TLS-XHTTP-H2up-H2down
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>extra</code> 里可以放 padding、xmux 和 <code>downloadSettings</code>。例如下载侧使用另一个域名：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;xPaddingBytes&#34;</span><span class="p">:</span> <span class="s2">&#34;100-1000&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;xmux&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;maxConcurrency&#34;</span><span class="p">:</span> <span class="s2">&#34;16-32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;hMaxRequestTimes&#34;</span><span class="p">:</span> <span class="s2">&#34;600-900&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;hMaxReusableSecs&#34;</span><span class="p">:</span> <span class="s2">&#34;1800-3000&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;downloadSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;xhttp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;tlsSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;alpn&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;h2&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;xhttpSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;host&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;DOWNLOAD-DOMAIN&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/api/v1/&lt;XHTTP-PATH-TOKEN&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;extra&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;xPaddingBytes&#34;</span><span class="p">:</span> <span class="s2">&#34;100-1000&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="验证命令">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81%e5%91%bd%e4%bb%a4"></a>
验证命令
</h2><p>看服务状态：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">systemctl status xray envoy nginx --no-pager
</span></span></code></pre></td></tr></table>
</div>
</div><p>看监听端口：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ss -lntup <span class="p">|</span> grep -E <span class="s1">&#39;(:80|:443|:9443|:10000|:10085|:18080|:9901)&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>验证 Envoy 配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">envoy --mode validate -c /etc/envoy/envoy.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>看 Envoy H3 统计：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s http://127.0.0.1:9901/stats <span class="p">|</span> grep http3
</span></span></code></pre></td></tr></table>
</div>
</div><p>看 Xray 用户统计：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">xray api statsquery --server<span class="o">=</span>127.0.0.1:10085 -pattern <span class="s1">&#39;user&gt;&gt;&gt;client-unlimited@local&gt;&gt;&gt;traffic&gt;&gt;&gt;&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="结论">
<a class="header-anchor" href="#%e7%bb%93%e8%ae%ba"></a>
结论
</h2><p>这套配置的核心是把入口层和代理层分开：Envoy 负责公网 HTTPS/H2/H3 和伪装站转发，Xray 专注处理 XHTTP，Nginx 只做本机静态站。改成 Envoy 的直接原因，是 Nginx 作为 H3 前置时下行速度明显偏低，而 Xray 直连 H3 诊断口能跑满，说明继续调 Xray 参数意义不大，应该替换前置层。</p>
<p>实际测试中，XHTTP H2/H2 可以跑满链路，H3 下行是否高性能和前置实现关系很大。Nginx Stream 转发 H3 时容易成为瓶颈，Caddy 有改善，Envoy 更适合做这类 HTTP/3 入口。如果遇到速度异常，建议保留一个 Xray 直连 H3 诊断入口，先确认 Xray 自身在当前线路下能否跑满。</p>

        
        <hr><p>本文2026-05-23首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-05-23</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Headscale &#43; Tailscale &#43; sing-box for Android：利用家宽打洞实现公司环境安全“科学上网”</title>
      <link>https://csdn.fjh1997.top/posts/51814.html</link>
      <pubDate>Fri, 08 May 2026 17:10:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/51814.html</guid>
      <description>
        <![CDATA[<h1>Headscale + Tailscale + sing-box for Android：利用家宽打洞实现公司环境安全“科学上网”</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="背景">
<a class="header-anchor" href="#%e8%83%8c%e6%99%af"></a>
背景
</h2><p>在当前的工作环境下，公司对网络合规和出口流量审计的要求日益严苛。办公网络不仅严查各类 VPN 协议，还会对所有通往境外的连接记录进行深度审计。为了在满足个人上网需求的同时，彻底避免将个人设备的代理链路暴露在办公网络出口上，我构建了一套基于“组网即代理”的方案。</p>
<p>核心思路是利用家里的宽带作为唯一的“科学上网”出口，而办公环境下的手机仅作为一个纯粹的内网接入点，通过自建的 Tailscale 网络连接回自家的电脑进行“打洞”。具体设计动机如下：</p>
<ol>
<li><strong>规避办公网审计</strong>：通过将真正的代理入口放在家里的 Windows 电脑上，手机在办公网环境下只产生与国内服务器（阿里云）或家宽公网 IP 的通信。所有对境外的访问流量均被封装在隧道内部，并最终在家宽出口解封，从而确保办公网出口没有任何境外 IP 的访问记录。</li>
<li><strong>阿里云控制面（Headscale）</strong>：为了实现稳定且不经过境外的控制平面，我在国内的<strong>阿里云 ECS</strong> 上部署了 <strong>Headscale</strong>（Tailscale 的开源替代方案）。需要注意，阿里云在这里仅作为**控制面（Control Plane）**负责节点发现和 NAT 穿透握手，<strong>并不负责数据中转</strong>。流量最终是通过 P2P 打洞直连到家里的，这样既保证了低延迟，也避免了阿里云因流量中转产生高昂的带宽费用。</li>
<li><strong>完全物理隔离</strong>：本方案实现了个人访问链路与办公网络的物理级隔离。办公网出口看到的只是前往阿里云的合规 HTTPS 流量，真正的互联网访问逻辑完全托管在自有设备和自有宽带上。</li>
</ol>
<h3 id="整体思路">
<a class="header-anchor" href="#%e6%95%b4%e4%bd%93%e6%80%9d%e8%b7%af"></a>
整体思路
</h3><ol>
<li><strong>阿里云 ECS</strong> 上部署 <strong>Headscale</strong>，作为 Tailscale 控制面（仅负责握手，记得关闭或不使用 DERP 中转，以节省阿里云流量）。</li>
<li><strong>家里的 Windows 电脑</strong> 加入这个 tailnet，作为代理网关，获得内网 IP <code>100.64.0.2</code>。</li>
<li><strong>家里电脑</strong> 本地运行 SOCKS5 服务（如 Clash/v2ray），并监听 <code>100.64.0.2:10808</code> 端口。</li>
<li><strong>Android 手机</strong> 使用 sing-box for Android，通过内置的 Tailscale endpoint 登录 Headscale。</li>
<li><strong>手机流量路由</strong>：Android 的 TUN 流量通过 Tailscale 隧道转发到家里的 <code>100.64.0.2:10808</code>。</li>
</ol>
<p>技术架构示意图：</p>
<pre class="mermaid">
  flowchart LR
  subgraph Phone["Android 手机"]
    App["App 流量"]
    Tun["sing-box TUN"]
    TsEndpoint["Tailscale endpoint<br/>ts-ep"]
  end

  subgraph Cloud["阿里云 ECS"]
    Headscale["Headscale 控制面<br/>:8443"]
  end

  subgraph Home["家里宽带"]
    Windows["Windows 网关<br/>100.64.0.2"]
    Socks["SOCKS5 服务<br/>100.64.0.2:10808"]
    HomeWan["家里宽带出口"]
  end

  App --> Tun --> TsEndpoint
  TsEndpoint -.->|登录 / 节点发现 / NAT 打洞| Headscale
  TsEndpoint ==>|加密 tailnet 连接| Socks
  Windows --- Socks
  Socks --> HomeWan
</pre><p>这样手机侧的链路是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Android App 流量
</span></span><span class="line"><span class="cl">  -&gt; sing-box TUN
</span></span><span class="line"><span class="cl">  -&gt; sing-box 内置 Tailscale endpoint (通过阿里云 Headscale 握手)
</span></span><span class="line"><span class="cl">  -&gt; tailnet 内内的 100.64.0.2:10808 (加密隧道)
</span></span><span class="line"><span class="cl">  -&gt; 家里电脑上的 SOCKS5 代理
</span></span><span class="line"><span class="cl">  -&gt; 家里宽带出口 (真正的境外访问发生在这里)
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意：这只是个人设备访问个人授权网络的记录。实际使用时要严格遵守所在单位、学校和网络服务提供方的安全合规准则。</p>
<h2 id="版本要求">
<a class="header-anchor" href="#%e7%89%88%e6%9c%ac%e8%a6%81%e6%b1%82"></a>
版本要求
</h2><p>Android 端需要使用支持 sing-box 1.14 新字段的 SFA/sing-box 版本。实测 <code>sing-box for Android 1.14.0-alpha.21</code> 以上可用。</p>
<p>低版本如果导入下面的配置，可能会报类似错误：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">unknown field accept_search_domain
</span></span></code></pre></td></tr></table>
</div>
</div><p>原因是 <code>accept_search_domain</code>、<code>control_http_client</code>、<code>dns_mode</code>、<code>preferred_by</code> 等字段属于较新的 sing-box 配置格式。</p>
<h2 id="headscale-服务端配置">
<a class="header-anchor" href="#headscale-%e6%9c%8d%e5%8a%a1%e7%ab%af%e9%85%8d%e7%bd%ae"></a>
Headscale 服务端配置
</h2><p>服务端部署在阿里云 ECS，公网地址、域名和密钥在这里都做了脱敏。</p>
<p>采集到的版本：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">headscale version v0.28.0
</span></span></code></pre></td></tr></table>
</div>
</div><p>配置文件路径：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">/etc/headscale/config.yaml
</span></span></code></pre></td></tr></table>
</div>
</div><p>核心配置如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">server_url</span><span class="p">:</span><span class="w"> </span><span class="l">https://&lt;HEADSCALE_DOMAIN&gt;:8443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">listen_addr</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="p">:</span><span class="m">8443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">grpc_listen_addr</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="p">:</span><span class="m">50443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metrics_listen_addr</span><span class="p">:</span><span class="w"> </span><span class="m">127.0.0.1</span><span class="p">:</span><span class="m">9090</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">database</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">sqlite</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">sqlite</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l">/var/lib/headscale/db.sqlite</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">write_ahead_log</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">prefixes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">allocation</span><span class="p">:</span><span class="w"> </span><span class="l">sequential</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">v4</span><span class="p">:</span><span class="w"> </span><span class="m">100.64.0.0</span><span class="l">/10</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">v6</span><span class="p">:</span><span class="w"> </span><span class="l">fd7a:115c:a1e0::/48</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">dns</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">magic_dns</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">base_domain</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;TAILNET_DNS_SUFFIX&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">override_local_dns</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">nameservers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">global</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">1.1.1.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">1.0.0.1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">2606</span><span class="p">:</span><span class="m">4700</span><span class="p">:</span><span class="m">4700</span><span class="p">::</span><span class="m">1111</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="m">2606</span><span class="p">:</span><span class="m">4700</span><span class="p">:</span><span class="m">4700</span><span class="p">::</span><span class="m">1001</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">derp</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">auto_update_enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">paths</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">/etc/headscale/derp-stun-only.yaml</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">server</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">enabled</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c"># 启用内置 STUN，继续监听 UDP 3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">automatically_add_embedded_derp_region</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="c"># 不把内置 DERP 加入 DERP map，避免客户端走 DERP 中转</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">region_id</span><span class="p">:</span><span class="w"> </span><span class="m">999</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">region_code</span><span class="p">:</span><span class="w"> </span><span class="l">headscale</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">region_name</span><span class="p">:</span><span class="w"> </span><span class="l">Headscale Embedded DERP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">stun_listen_addr</span><span class="p">:</span><span class="w"> </span><span class="m">0.0.0.0</span><span class="p">:</span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">private_key_path</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;REDACTED&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">verify_clients</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">urls</span><span class="p">:</span><span class="w"> </span><span class="p">[]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">update_frequency</span><span class="p">:</span><span class="w"> </span><span class="l">3h</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">noise</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">private_key_path</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;REDACTED&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">tls_cert_path</span><span class="p">:</span><span class="w"> </span><span class="l">/path/to/&lt;HEADSCALE_DOMAIN&gt;.cer</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">tls_key_path</span><span class="p">:</span><span class="w"> </span><span class="l">/path/to/&lt;HEADSCALE_DOMAIN&gt;.key</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>同时创建 <code>/etc/headscale/derp-stun-only.yaml</code>，只下发 STUN，不提供可用 DERP 中继。这里可以配置多个 STUN 节点，让客户端在多出口网络里探测到更多 NAT 映射候选：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">regions</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">999</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">999</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-self</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Self STUN</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">999a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">999</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;HEADSCALE_DOMAIN&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ipv4</span><span class="p">:</span><span class="w"> </span><span class="l">&lt;HEADSCALE_PUBLIC_IPV4&gt;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1000</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-ali</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN 39.107</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1000a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1000</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="m">39.107.142.158</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">ipv4</span><span class="p">:</span><span class="w"> </span><span class="m">39.107.142.158</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1001</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1001</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-hitv</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN HITV</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1001a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1001</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.hitv.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1002</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1002</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-miwifi</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN MiWiFi</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1002a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1002</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.miwifi.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1003</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1003</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-bilibili</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Bilibili</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1003a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1003</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.chat.bilibili.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1004</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1004</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-cloudflare</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Cloudflare</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1004a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1004</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.cloudflare.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1005</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1005</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-nextcloud</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Nextcloud</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1005a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1005</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.nextcloud.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1006</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1006</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-nextcloud-443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Nextcloud 443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1006a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1006</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.nextcloud.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1007</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1007</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-google-1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Google 1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1007a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1007</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun1.l.google.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">19302</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1008</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1008</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-google-3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Google 3</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1008a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1008</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun3.l.google.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">19302</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1009</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1009</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-google-4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Google 4</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1009a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1009</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun4.l.google.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">19302</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1010</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1010</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-voipbuster</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Voipbuster</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1010a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1010</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.voipbuster.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1011</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1011</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-voipstunt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Voipstunt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1011a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1011</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.voipstunt.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1012</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1012</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-sipnet</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Sipnet</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1012a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1012</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.sipnet.net</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1013</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1013</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-telnyx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Telnyx</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1013a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1013</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">stun.telnyx.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">1014</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1014</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regioncode</span><span class="p">:</span><span class="w"> </span><span class="l">stun-twilio</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">regionname</span><span class="p">:</span><span class="w"> </span><span class="l">Public STUN Twilio</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">1014a</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">regionid</span><span class="p">:</span><span class="w"> </span><span class="m">1014</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">global.stun.twilio.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">stunport</span><span class="p">:</span><span class="w"> </span><span class="m">3478</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">derpport</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>这里的效果是：Headscale 继续提供 STUN 给 <code>tailscale netcheck</code> 和打洞探测使用，但 DERP 中继端口不可用，打洞失败时不会通过服务器中转流量。多 STUN 的意义是增加公网映射候选，尤其适合学校、公司这类可能按目标 IP 分配不同出口的网络；如果某个 STUN 服务器和真实 peer 目标走到同一个出口，直连打洞成功率会更高。</p>
<p>systemd 服务使用发行版默认的 <code>headscale serve</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">headscale</span>
</span></span><span class="line"><span class="cl"><span class="na">Group</span><span class="o">=</span><span class="s">headscale</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/bin/headscale serve</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
</span></span><span class="line"><span class="cl"><span class="na">WorkingDirectory</span><span class="o">=</span><span class="s">/var/lib/headscale</span>
</span></span><span class="line"><span class="cl"><span class="na">StateDirectory</span><span class="o">=</span><span class="s">headscale</span>
</span></span><span class="line"><span class="cl"><span class="na">RuntimeDirectory</span><span class="o">=</span><span class="s">headscale</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>节点列表脱敏后大概是这样：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">100.64.0.1  headscale-server  linux
</span></span><span class="line"><span class="cl">100.64.0.2  home-windows-pc   windows
</span></span><span class="line"><span class="cl">100.64.0.3  other-windows-pc  windows
</span></span><span class="line"><span class="cl">100.64.0.4  sfa-android       android
</span></span></code></pre></td></tr></table>
</div>
</div><p>其中 <code>100.64.0.2</code> 是家里的 Windows 电脑，也是 Android 最终要访问的 SOCKS5 节点。</p>
<h2 id="家里-windows-电脑的-tailscale-配置">
<a class="header-anchor" href="#%e5%ae%b6%e9%87%8c-windows-%e7%94%b5%e8%84%91%e7%9a%84-tailscale-%e9%85%8d%e7%bd%ae"></a>
家里 Windows 电脑的 Tailscale 配置
</h2><p>Windows 端不需要额外写复杂配置，核心就是在 Headscale 服务端生成一个预授权 key，然后在 Windows 上用这个 key 加入自建控制面。</p>
<p>在 Headscale 服务端生成 Windows 节点使用的 key：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">headscale preauthkeys create --user <span class="m">1</span> --expiration 24h
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果希望这个 key 可以给多台设备重复使用，可以加 <code>--reusable</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">headscale preauthkeys create --user <span class="m">1</span> --expiration 24h --reusable
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后在家里的 Windows 电脑上执行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">up</span> <span class="p">-</span><span class="n">-login-server</span> <span class="n">https</span><span class="err">:</span><span class="p">//&lt;</span><span class="n">HEADSCALE_DOMAIN</span><span class="p">&gt;</span><span class="err">:</span><span class="mf">8443</span> <span class="p">-</span><span class="n">-auth-key</span> <span class="p">&lt;</span><span class="n">WINDOWS_AUTH_KEY</span><span class="p">&gt;</span> <span class="p">-</span><span class="n">-hostname</span> <span class="nb">home-windows</span><span class="n">-pc</span> <span class="p">-</span><span class="n">-accept-dns</span><span class="p">=</span><span class="n">true</span> <span class="p">-</span><span class="n">-accept-routes</span><span class="p">=</span><span class="n">true</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这台电脑上需要有一个 SOCKS5 服务监听 <code>10808</code>。如果只监听 <code>127.0.0.1:10808</code>，tailnet 里的手机访问不到；需要确保它监听在 <code>0.0.0.0:10808</code>，或者至少监听到 Tailscale 网卡的 <code>100.64.0.2:10808</code>，同时 Windows 防火墙允许 tailnet 访问这个端口。</p>
<h2 id="android-sing-box-配置">
<a class="header-anchor" href="#android-sing-box-%e9%85%8d%e7%bd%ae"></a>
Android sing-box 配置
</h2><p>Android 端不要同时开官方 Tailscale App 的 VPN。Android 通常只能稳定运行一个 VPN，SFA 的 TUN 已经占用 VPN 入口，所以这里让 sing-box 自己内置一个 Tailscale endpoint。</p>
<p>Android 端同样需要先在 Headscale 服务端生成一个 auth key：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">headscale preauthkeys create --user <span class="m">1</span> --expiration 24h
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果只是给手机导入一次配置，建议使用一次性 key，不加 <code>--reusable</code>。生成出来的 key 填到下面 sing-box 配置的 <code>auth_key</code> 字段里。</p>
<p>完整配置如下，<code>auth_key</code> 已脱敏。这一份是基础版，默认最终出站都是家里电脑的 SOCKS5：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;level&#34;</span><span class="p">:</span> <span class="s2">&#34;info&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dns&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;servers&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;https&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;remote-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;1.1.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/dns-query&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tls&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;server_name&#34;</span><span class="p">:</span> <span class="s2">&#34;cloudflare-dns.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;detour&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;endpoint&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;accept_default_resolvers&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;accept_search_domain&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;&lt;HEADSCALE_DOMAIN&gt;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;preferred_by&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;ts-dns&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;final&#34;</span><span class="p">:</span> <span class="s2">&#34;remote-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;strategy&#34;</span><span class="p">:</span> <span class="s2">&#34;prefer_ipv4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;timeout&#34;</span><span class="p">:</span> <span class="s2">&#34;10s&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;endpoints&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;state_directory&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale-home&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;auth_key&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REDACTED_AUTH_KEY&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;control_url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://&lt;HEADSCALE_DOMAIN&gt;:8443&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;control_http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;hostname&#34;</span><span class="p">:</span> <span class="s2">&#34;sfa-android&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;accept_routes&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;udp_timeout&#34;</span><span class="p">:</span> <span class="s2">&#34;5m&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;inbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tun&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;tun-in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;172.19.0.1/30&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;fdfe:dcba:9876::1/126&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;auto_route&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;strict_route&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;dns_mode&#34;</span><span class="p">:</span> <span class="s2">&#34;hijack&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;stack&#34;</span><span class="p">:</span> <span class="s2">&#34;mixed&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;endpoint_independent_nat&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;socks&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;100.64.0.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">10808</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;udp&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;detour&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;route&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">53</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;hijack-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;sniff&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;preferred_by&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip_is_private&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;final&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;auto_detect_interface&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;default_domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="国内外分流版本">
<a class="header-anchor" href="#%e5%9b%bd%e5%86%85%e5%a4%96%e5%88%86%e6%b5%81%e7%89%88%e6%9c%ac"></a>
国内外分流版本
</h3><p>上面的基础版会把手机侧流量默认全部送到家里电脑的 <code>100.64.0.2:10808</code>。如果希望国内站点直连、国外站点仍然走家里 SOCKS5，可以使用下面这个分流版。它使用 <code>geosite-cn</code>、<code>geoip-cn</code> 做国内直连，使用 <code>geosite-geolocation-!cn</code> 做国外代理，国内 DNS 走 <code>223.5.5.5</code>，国外 DNS 走 Cloudflare DoH 并通过家里 SOCKS5 出口。没有命中规则的流量默认直连，避免微信这类国内 App 因规则缺失误走隧道。</p>
<p>这个版本会在首次启动时下载远程 <code>.srs</code> 规则集，后续由 <code>cache_file</code> 缓存。注意 <code>cn-dns</code> 这个 UDP DNS 服务器不要写 <code>&quot;detour&quot;: &quot;direct&quot;</code>，新版 sing-box 会报 <code>detour to an empty direct outbound makes no sense</code>，因为 UDP DNS 默认就是直连。这里也不再全局阻断 UDP 443；阻断 QUIC 虽然能让部分连接回退到 TCP，但放在国内规则前面容易误伤微信、小程序和国内 App。</p>
<p>分流版完整配置如下，<code>auth_key</code> 和 Headscale 域名已脱敏：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;level&#34;</span><span class="p">:</span> <span class="s2">&#34;info&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dns&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;servers&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;udp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;223.5.5.5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">53</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;https&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;remote-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;1.1.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/dns-query&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tls&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;server_name&#34;</span><span class="p">:</span> <span class="s2">&#34;cloudflare-dns.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;detour&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;endpoint&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;accept_default_resolvers&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;accept_search_domain&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;&lt;HEADSCALE_DOMAIN&gt;&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;preferred_by&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;ts-dns&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;googleapis.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;gstatic.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain_suffix&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;googleapis.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;gstatic.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;remote-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-geolocation-!cn&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;remote-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-category-ads-all&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;predefined&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rcode&#34;</span><span class="p">:</span> <span class="s2">&#34;NOERROR&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-private&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-cn&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;final&#34;</span><span class="p">:</span> <span class="s2">&#34;cn-dns&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;strategy&#34;</span><span class="p">:</span> <span class="s2">&#34;prefer_ipv4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;timeout&#34;</span><span class="p">:</span> <span class="s2">&#34;10s&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;endpoints&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;state_directory&#34;</span><span class="p">:</span> <span class="s2">&#34;tailscale-home&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;auth_key&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;REDACTED_AUTH_KEY&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;control_url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://&lt;HEADSCALE_DOMAIN&gt;:8443&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;control_http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;hostname&#34;</span><span class="p">:</span> <span class="s2">&#34;sfa-android&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;accept_routes&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;udp_timeout&#34;</span><span class="p">:</span> <span class="s2">&#34;5m&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;inbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;tun&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;tun-in&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;172.19.0.1/30&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;fdfe:dcba:9876::1/126&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;auto_route&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;strict_route&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;dns_mode&#34;</span><span class="p">:</span> <span class="s2">&#34;hijack&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;stack&#34;</span><span class="p">:</span> <span class="s2">&#34;mixed&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;endpoint_independent_nat&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;socks&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;100.64.0.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">10808</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;5&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;udp&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;detour&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;route&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">53</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;hijack-dns&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;sniff&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;preferred_by&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;package_name&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;com.tencent.mm&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;com.tencent.mobileqq&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;googleapis.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;gstatic.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain_suffix&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;googleapis.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;gstatic.com&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-category-ads-all&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-geolocation-!cn&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip_is_private&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-private&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;ip_cidr&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;223.5.5.5/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;223.6.6.6/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2400:3200::1/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2400:3200:baba::1/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;119.29.29.29/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;1.12.12.12/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;120.53.53.53/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2402:4e00::/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2402:4e00:1::/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;180.76.76.76/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2400:da00::6666/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.114.114/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.115.115/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.114.119/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.115.119/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.114.110/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;114.114.115.110/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;180.184.1.1/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;180.184.2.2/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;101.226.4.6/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;218.30.118.6/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;123.125.81.6/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;140.207.198.6/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;1.2.4.8/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;210.2.4.8/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;52.80.66.66/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;117.50.22.22/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2400:7fc0:849e:200::4/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2404:c2c0:85d8:901::4/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;117.50.10.10/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;52.80.52.52/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2400:7fc0:849e:200::8/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;2404:c2c0:85d8:901::8/128&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;117.50.60.30/32&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;52.80.60.30/32&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;alidns.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;doh.pub&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;dot.pub&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;360.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;onedns.net&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain_suffix&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;alidns.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;doh.pub&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;dot.pub&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;360.cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;onedns.net&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geosite-cn&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="s2">&#34;geoip-cn&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;action&#34;</span><span class="p">:</span> <span class="s2">&#34;route&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outbound&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rule_set&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;remote&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;geosite-category-ads-all&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;binary&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;update_interval&#34;</span><span class="p">:</span> <span class="s2">&#34;24h&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;remote&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;geosite-geolocation-!cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;binary&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;update_interval&#34;</span><span class="p">:</span> <span class="s2">&#34;24h&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;remote&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;geosite-private&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;binary&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-private.srs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;update_interval&#34;</span><span class="p">:</span> <span class="s2">&#34;24h&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;remote&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;geosite-cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;binary&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;update_interval&#34;</span><span class="p">:</span> <span class="s2">&#34;24h&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;remote&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;geoip-cn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;format&#34;</span><span class="p">:</span> <span class="s2">&#34;binary&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-cn.srs&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;http_client&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;update_interval&#34;</span><span class="p">:</span> <span class="s2">&#34;24h&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;final&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;auto_detect_interface&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;default_domain_resolver&#34;</span><span class="p">:</span> <span class="s2">&#34;local&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;experimental&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;cache_file&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;store_dns&#34;</span><span class="p">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>关键点是这个出站：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;socks&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;proxy&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;100.64.0.2&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;server_port&#34;</span><span class="p">:</span> <span class="mi">10808</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;detour&#34;</span><span class="p">:</span> <span class="s2">&#34;ts-ep&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>detour: ts-ep</code> 表示连接 SOCKS5 服务本身时先走 Tailscale endpoint。没有这个字段，Android 的普通网络无法直接访问 <code>100.64.0.2</code>。</p>
<p>分流规则的关键点是：微信和 QQ 先按包名强制 <code>direct</code>，避免国内 IM 流量误走家里 SOCKS5；<code>geosite-geolocation-!cn</code> 明确送到 <code>proxy</code>，用于国外站点；<code>final</code> 保持 <code>direct</code>，让未知流量默认直连。不要把 UDP 443 阻断规则放在国内规则前面，否则微信、小程序或国内 App 的 QUIC/UDP 连接可能先被拦截，表现为发消息慢、加载卡顿。</p>
<h2 id="启动顺序">
<a class="header-anchor" href="#%e5%90%af%e5%8a%a8%e9%a1%ba%e5%ba%8f"></a>
启动顺序
</h2><ol>
<li>Headscale 服务端先启动，确认 <code>server_url</code> 能访问。</li>
<li>家里 Windows 电脑登录 Headscale，确认拿到 <code>100.64.0.2</code>。</li>
<li>家里电脑启动 SOCKS5 服务，确认 <code>100.64.0.2:10808</code> 可访问。</li>
<li>Android 导入 sing-box 配置，启动 SFA。</li>
<li>在 Headscale 上查看 <code>sfa-android</code> 节点是否在线。</li>
</ol>
<p>常用检查命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">headscale nodes list
</span></span></code></pre></td></tr></table>
</div>
</div><p>Windows 上检查：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">status</span>
</span></span><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">debug</span> <span class="n">prefs</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>NAT 类型也要检查一下。Tailscale 打洞最怕的是两端都是对称型 NAT；办公网这边是对称型 NAT 问题不大，只要家宽这一端不是对称型 NAT，通常仍然可以打出直连。如果两端都是对称型 NAT，P2P 直连大概率失败，最终会退回 DERP 中转。</p>
<p>在家里 Windows 电脑上跑：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">netcheck</span>
</span></span><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">netcheck</span> <span class="p">-</span><span class="n">-format</span> <span class="n">json</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在办公网络侧也找一台同网段设备跑同样的命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">netcheck</span>
</span></span><span class="line"><span class="cl"><span class="n">tailscale</span> <span class="n">netcheck</span> <span class="p">-</span><span class="n">-format</span> <span class="n">json</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>重点看输出里的 <code>MappingVariesByDestIP</code>。如果是 <code>true</code>，基本可以认为这一侧是对称型 NAT 或 hard NAT；如果是 <code>false</code>，打洞条件会好很多。本方案里最关键的是家宽侧尽量保持 <code>MappingVariesByDestIP: false</code>。</p>
<p>sing-box 配置可以先用本地源码检查：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">go</span> <span class="n">run</span> <span class="n">-tags</span> <span class="s2">&#34;with_gvisor,with_tailscale&#34;</span> <span class="p">./</span><span class="n">cmd</span><span class="p">/</span><span class="nb">sing-box</span> <span class="n">check</span> <span class="n">-c</span> <span class="p">.\</span><span class="nb">sing-box</span><span class="n">-android-tailscale</span><span class="p">.</span><span class="py">json</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="排错">
<a class="header-anchor" href="#%e6%8e%92%e9%94%99"></a>
排错
</h2><p>如果 Android 报 <code>unknown field accept_search_domain</code>，升级 SFA/sing-box 到 <code>1.14.0-alpha.21</code> 以上。</p>
<p>如果 Android 能登录 Headscale 但不能访问 <code>100.64.0.2:10808</code>，先检查家里电脑上的 SOCKS5 是否监听在 Tailscale 可访问的地址上，再检查 Windows 防火墙。</p>
<p>如果 Headscale 控制面域名解析失败，确保 Android 配置里的 <code>control_http_client.domain_resolver</code> 指向 <code>local</code>，避免控制面解析也走还没建立起来的代理链路。</p>
<p>如果 DNS 查询异常，确认 <code>dns_mode</code> 是 <code>hijack</code>，并且 <code>route.rules</code> 里有 <code>port: 53</code> 的 <code>hijack-dns</code> 规则。</p>
<h2 id="脱敏清单">
<a class="header-anchor" href="#%e8%84%b1%e6%95%8f%e6%b8%85%e5%8d%95"></a>
脱敏清单
</h2><p>这篇文章里隐藏了这些内容：</p>
<ol>
<li>Headscale 服务器公网 IP。</li>
<li>Headscale 域名。</li>
<li>SSH 密码。</li>
<li>Tailscale auth key。</li>
<li>节点公钥、机器密钥和私钥路径。</li>
<li>证书文件真实路径。</li>
</ol>
<p>真实环境里不要把 auth key、SSH 密码、私钥、节点 key 写进博客仓库。首次注册成功后，也建议把一次性 auth key 作废。</p>

        
        <hr><p>本文2026-05-08首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-05-08</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Xray反向代理——多端口内网穿透绕过企业级防火墙兼容梯子配置方法</title>
      <link>https://csdn.fjh1997.top/posts/xray-reverse-proxy-enterfirewall.html</link>
      <pubDate>Tue, 05 May 2026 20:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/xray-reverse-proxy-enterfirewall.html</guid>
      <description>
        <![CDATA[<h1>Xray反向代理——多端口内网穿透绕过企业级防火墙兼容梯子配置方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="背景">
<a class="header-anchor" href="#%e8%83%8c%e6%99%af"></a>
背景
</h2><p>在企业内网环境中部署服务时，经常会遇到这样的问题：</p>
<ul>
<li>公司防火墙拦截了frp、rathole等常见内网穿透工具的协议特征</li>
<li>SSH隧道被DPI（深度包检测）识别并阻断</li>
<li>开放的端口有限，仅允许80/443等常见端口出站</li>
<li>传统穿透方案需要额外开放端口，增加了暴露面</li>
</ul>
<p>我们需要一种方案：<strong>既能穿透内网暴露服务，又能伪装成正常HTTPS流量绕过防火墙检测，同时还能作为梯子使用</strong>。</p>
<h3 id="方案对比">
<a class="header-anchor" href="#%e6%96%b9%e6%a1%88%e5%af%b9%e6%af%94"></a>
方案对比
</h3><table>
  <thead>
      <tr>
          <th>方案</th>
          <th>性能</th>
          <th>抗检测</th>
          <th>备注</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>frp</td>
          <td>高</td>
          <td>差</td>
          <td>自定义协议特征明显，容易被DPI识别和阻断</td>
      </tr>
      <tr>
          <td>rathole</td>
          <td>高</td>
          <td>差</td>
          <td>基于Noise协议，性能优秀但协议指纹已进入黑名单</td>
      </tr>
      <tr>
          <td>SSH隧道</td>
          <td>中</td>
          <td>中</td>
          <td>加密流量，但SSH握手特征明显，企业防火墙通常直接拦截</td>
      </tr>
      <tr>
          <td>Xray VLESS+REALITY</td>
          <td>高</td>
          <td>强</td>
          <td>流量与正常HTTPS访问完全一致，目前无已知检测手段</td>
      </tr>
  </tbody>
</table>
<p>frp和rathole在性能上表现优秀，连接稳定、延迟低，但它们的协议特征已经被主流防火墙和DPI设备收录。在企业环境中，这些工具的连接往往在建立阶段就被拦截。</p>
<p>Xray的VLESS+REALITY+Vision组合完美解决了这个问题。REALITY协议不需要域名和证书，直接复用TLS握手，流量特征与访问正常HTTPS网站完全一致。配合反向代理功能，一个443端口同时承载多服务穿透和梯子。</p>
<h2 id="架构说明">
<a class="header-anchor" href="#%e6%9e%b6%e6%9e%84%e8%af%b4%e6%98%8e"></a>
架构说明
</h2><pre tabindex="0"><code>┌──────────────────┐                    ┌──────────────────┐
│   内网机器(A)     │                    │  公网服务器(B)    │
│                  │   vless+reality    │                  │
│  ┌────────────┐  │ ◄════════════════► │ ┌────────────┐  │
│  │ xray-bridge│  │    port 443        │ │xray-portal │  │
│  └────┬───────┘  │                    │ └────┬───────┘  │
│       │          │                    │      │          │
│  ┌────┴───────┐  │                    │ ┌────┴───────┐  │
│  │ 本地服务    │  │                    │ │ 80/8081/   │  │
│  │ :80        │  │                    │ │ 8082端口    │  │
│  │ :8001      │  │                    │ │ (公网访问)  │  │
│  │ :8002      │  │                    │ └────────────┘  │
│  └────────────┘  │                    │                  │
└──────────────────┘                    └──────────────────┘
</code></pre><h3 id="流量走向">
<a class="header-anchor" href="#%e6%b5%81%e9%87%8f%e8%b5%b0%e5%90%91"></a>
流量走向
</h3><ol>
<li><strong>内网穿透</strong>：bridge用<code>.internal</code>域名连接portal → portal识别为隧道注册 → 外部HTTP流量通过dokodemo-door进入 → portal转发给bridge → bridge转发给本地服务</li>
<li><strong>梯子</strong>：普通客户端用任意域名连接443 → portal识别为普通流量 → freedom直连出站</li>
</ol>
<p>两种流量共用同一个vless+reality入站，portal通过域名自动区分。</p>
<h2 id="关键配置">
<a class="header-anchor" href="#%e5%85%b3%e9%94%ae%e9%85%8d%e7%bd%ae"></a>
关键配置
</h2><h3 id="公网服务器portal端">
<a class="header-anchor" href="#%e5%85%ac%e7%bd%91%e6%9c%8d%e5%8a%a1%e5%99%a8portal%e7%ab%af"></a>
公网服务器（portal端）
</h3><p><code>/usr/local/etc/xray/config.json</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;loglevel&#34;</span><span class="p">:</span> <span class="s2">&#34;warning&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;portals&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-ctfd&#34;</span><span class="p">,</span>        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-ctfd.internal&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-param&#34;</span><span class="p">,</span>       <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-param.internal&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-unserialize&#34;</span><span class="p">,</span> <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-unserialize.internal&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;inbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;clients&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span> <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为你的UUID&#34;</span><span class="p">,</span> <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;decryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;reality&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;realitySettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;show&#34;</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;dest&#34;</span><span class="p">:</span> <span class="s2">&#34;www.microsoft.com:443&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;xver&#34;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;serverNames&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;www.microsoft.com&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;privateKey&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为xray x25519生成的私钥&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;shortIds&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;替换为openssl rand -hex 8生成的值&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;sniffing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;enabled&#34;</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;destOverride&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;http&#34;</span><span class="p">,</span> <span class="s2">&#34;tls&#34;</span><span class="p">,</span> <span class="s2">&#34;quic&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-ctfd&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span> <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">80</span><span class="p">,</span> <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-param&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8081</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span> <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8081</span><span class="p">,</span> <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;external-unserialize&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;listen&#34;</span><span class="p">:</span> <span class="s2">&#34;::&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8082</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;dokodemo-door&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;0.0.0.0&#34;</span><span class="p">,</span> <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">8082</span><span class="p">,</span> <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span><span class="p">,</span> <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;block&#34;</span><span class="p">,</span> <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;blackhole&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;comment&#34;</span><span class="p">:</span> <span class="s2">&#34;公网 HTTP 流量 → 对应 portal&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;external-ctfd&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-ctfd&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;external-param&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-param&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;external-unserialize&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-unserialize&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;comment&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge 来的隧道注册请求 → 对应 portal&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;interconn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-ctfd.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-ctfd&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;interconn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-param.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-param&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;interconn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-unserialize.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;portal-unserialize&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;comment&#34;</span><span class="p">:</span> <span class="s2">&#34;梯子流量（非 .internal 流量）&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;type&#34;</span><span class="p">:</span> <span class="s2">&#34;field&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;interconn&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;direct&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="内网机器bridge端">
<a class="header-anchor" href="#%e5%86%85%e7%bd%91%e6%9c%ba%e5%99%a8bridge%e7%ab%af"></a>
内网机器（bridge端）
</h3><p><code>/usr/local/etc/xray/bridge-config.json</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span><span class="lnt">81
</span><span class="lnt">82
</span><span class="lnt">83
</span><span class="lnt">84
</span><span class="lnt">85
</span><span class="lnt">86
</span><span class="lnt">87
</span><span class="lnt">88
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;log&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;loglevel&#34;</span><span class="p">:</span> <span class="s2">&#34;warning&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;reverse&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;bridges&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-ctfd&#34;</span><span class="p">,</span>        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-ctfd.internal&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-param&#34;</span><span class="p">,</span>       <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-param.internal&#34;</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span> <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge-unserialize&#34;</span><span class="p">,</span> <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="s2">&#34;tunnel-unserialize.internal&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;outbounds&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;vless&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;vnext&#34;</span><span class="p">:</span> <span class="p">[{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为公网服务器IP&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;port&#34;</span><span class="p">:</span> <span class="mi">443</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;users&#34;</span><span class="p">:</span> <span class="p">[{</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;id&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为你的UUID&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;flow&#34;</span><span class="p">:</span> <span class="s2">&#34;xtls-rprx-vision&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nt">&#34;encryption&#34;</span><span class="p">:</span> <span class="s2">&#34;none&#34;</span>
</span></span><span class="line"><span class="cl">          <span class="p">}]</span>
</span></span><span class="line"><span class="cl">        <span class="p">}]</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;streamSettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;network&#34;</span><span class="p">:</span> <span class="s2">&#34;tcp&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;security&#34;</span><span class="p">:</span> <span class="s2">&#34;reality&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;realitySettings&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;fingerprint&#34;</span><span class="p">:</span> <span class="s2">&#34;chrome&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;serverName&#34;</span><span class="p">:</span> <span class="s2">&#34;www.microsoft.com&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;publicKey&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为xray x25519生成的公钥&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;shortId&#34;</span><span class="p">:</span> <span class="s2">&#34;替换为openssl rand -hex 8生成的值&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nt">&#34;spiderX&#34;</span><span class="p">:</span> <span class="s2">&#34;/&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-ctfd&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:80&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-param&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:8001&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;tag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-unserialize&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;protocol&#34;</span><span class="p">:</span> <span class="s2">&#34;freedom&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nt">&#34;settings&#34;</span><span class="p">:</span> <span class="p">{</span> <span class="nt">&#34;redirect&#34;</span><span class="p">:</span> <span class="s2">&#34;127.0.0.1:8002&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;routing&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;rules&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;comment&#34;</span><span class="p">:</span> <span class="s2">&#34;bridge 注册握手 → 连接 portal&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-ctfd&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-ctfd.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-param&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-param.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-unserialize&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;domain&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;full:tunnel-unserialize.internal&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;interconn&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;comment&#34;</span><span class="p">:</span> <span class="s2">&#34;portal 转发来的实际流量 → 本地服务&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-ctfd&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-ctfd&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-param&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-param&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;inboundTag&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;bridge-unserialize&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nt">&#34;outboundTag&#34;</span><span class="p">:</span> <span class="s2">&#34;out-unserialize&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="systemd-服务配置">
<a class="header-anchor" href="#systemd-%e6%9c%8d%e5%8a%a1%e9%85%8d%e7%bd%ae"></a>
Systemd 服务配置
</h2><h3 id="bridge端">
<a class="header-anchor" href="#bridge%e7%ab%af"></a>
bridge端
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># /etc/systemd/system/xray-bridge.service</span>
</span></span><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Xray Bridge (reverse proxy client)</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network.target</span>
</span></span><span class="line"><span class="cl"><span class="na">Wants</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/local/bin/xray run -config /usr/local/etc/xray/bridge-config.json</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
</span></span><span class="line"><span class="cl"><span class="na">RestartSec</span><span class="o">=</span><span class="s">5</span>
</span></span><span class="line"><span class="cl"><span class="na">LimitNOFILE</span><span class="o">=</span><span class="s">1048576</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">root</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="portal端">
<a class="header-anchor" href="#portal%e7%ab%af"></a>
portal端
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="c1"># /etc/systemd/system/xray.service</span>
</span></span><span class="line"><span class="cl"><span class="k">[Unit]</span>
</span></span><span class="line"><span class="cl"><span class="na">Description</span><span class="o">=</span><span class="s">Xray Portal (reverse proxy server)</span>
</span></span><span class="line"><span class="cl"><span class="na">After</span><span class="o">=</span><span class="s">network.target</span>
</span></span><span class="line"><span class="cl"><span class="na">Wants</span><span class="o">=</span><span class="s">network-online.target</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Service]</span>
</span></span><span class="line"><span class="cl"><span class="na">Type</span><span class="o">=</span><span class="s">simple</span>
</span></span><span class="line"><span class="cl"><span class="na">ExecStart</span><span class="o">=</span><span class="s">/usr/local/bin/xray run -config /usr/local/etc/xray/config.json</span>
</span></span><span class="line"><span class="cl"><span class="na">Restart</span><span class="o">=</span><span class="s">always</span>
</span></span><span class="line"><span class="cl"><span class="na">RestartSec</span><span class="o">=</span><span class="s">5</span>
</span></span><span class="line"><span class="cl"><span class="na">LimitNOFILE</span><span class="o">=</span><span class="s">1048576</span>
</span></span><span class="line"><span class="cl"><span class="na">User</span><span class="o">=</span><span class="s">root</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">[Install]</span>
</span></span><span class="line"><span class="cl"><span class="na">WantedBy</span><span class="o">=</span><span class="s">multi-user.target</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="生成-reality-密钥对">
<a class="header-anchor" href="#%e7%94%9f%e6%88%90-reality-%e5%af%86%e9%92%a5%e5%af%b9"></a>
生成 Reality 密钥对
</h2><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 安装 xray</span>
</span></span><span class="line"><span class="cl">bash -c <span class="s2">&#34;</span><span class="k">$(</span>curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh<span class="k">)</span><span class="s2">&#34;</span> @ install
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成密钥对（portal端用私钥，bridge端用公钥）</span>
</span></span><span class="line"><span class="cl">xray x25519
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成 shortId（两端保持一致）</span>
</span></span><span class="line"><span class="cl">openssl rand -hex <span class="m">8</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 生成 UUID（两端保持一致）</span>
</span></span><span class="line"><span class="cl">xray uuid
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="作为梯子使用">
<a class="header-anchor" href="#%e4%bd%9c%e4%b8%ba%e6%a2%af%e5%ad%90%e4%bd%bf%e7%94%a8"></a>
作为梯子使用
</h2><p>portal的443端口同时支持梯子功能。任何支持VLESS的客户端都可以连接使用。</p>
<h3 id="节点链接可直接导入v2raynclash">
<a class="header-anchor" href="#%e8%8a%82%e7%82%b9%e9%93%be%e6%8e%a5%e5%8f%af%e7%9b%b4%e6%8e%a5%e5%af%bc%e5%85%a5v2raynclash"></a>
节点链接（可直接导入v2rayN/Clash）
</h3><pre tabindex="0"><code>vless://替换UUID@替换公网IP:443?encryption=none&amp;flow=xtls-rprx-vision&amp;security=reality&amp;sni=www.microsoft.com&amp;fp=chrome&amp;pbk=替换公钥&amp;sid=替换shortId&amp;spx=%2F&amp;type=tcp#节点名称
</code></pre><h3 id="clash配置示例">
<a class="header-anchor" href="#clash%e9%85%8d%e7%bd%ae%e7%a4%ba%e4%be%8b"></a>
Clash配置示例
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">proxies</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;xray-reality&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">vless</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">server</span><span class="p">:</span><span class="w"> </span><span class="l">替换公网IP</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">443</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">uuid</span><span class="p">:</span><span class="w"> </span><span class="l">替换UUID</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">network</span><span class="p">:</span><span class="w"> </span><span class="l">tcp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">tls</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">udp</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">flow</span><span class="p">:</span><span class="w"> </span><span class="l">xtls-rprx-vision</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">servername</span><span class="p">:</span><span class="w"> </span><span class="l">www.microsoft.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">reality-opts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">public-key</span><span class="p">:</span><span class="w"> </span><span class="l">替换公钥</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">short-id</span><span class="p">:</span><span class="w"> </span><span class="l">替换shortId</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">client-fingerprint</span><span class="p">:</span><span class="w"> </span><span class="l">chrome</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="注意事项">
<a class="header-anchor" href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9"></a>
注意事项
</h2><ol>
<li><strong>版本一致性</strong>：bridge和portal必须使用相同版本的Xray</li>
<li><strong>不要重复开启Mux</strong>：反向代理底层已使用Mux.cool，不要在interconn outbound上再次开启mux</li>
<li><strong>启动顺序</strong>：建议先启动bridge，再启动portal</li>
<li><strong>bridge端不需要inbound</strong>：reverse.bridges本身就是虚拟inbound，不需要额外配置dokodemo-door</li>
<li><strong>域名路由规则顺序</strong>：<code>.internal</code>的规则必须放在<code>direct</code>规则之前</li>
<li><strong>穿透服务数量</strong>：每增加一个穿透服务，需要在两端各加一组bridge/portal + 对应的路由规则</li>
</ol>
<h2 id="参考文档">
<a class="header-anchor" href="#%e5%8f%82%e8%80%83%e6%96%87%e6%a1%a3"></a>
参考文档
</h2><ul>
<li><a href="https://xtls.github.io/config/reverse.html" target="_blank" rel="noopener noreferrer nofollow">Xray 官方反向代理文档</a>
</li>
<li><a href="https://github.com/XTLS/Xray-core" target="_blank" rel="noopener noreferrer nofollow">XTLS/Xray-core GitHub</a>
</li>
</ul>

        
        <hr><p>本文2026-05-05首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-05-05</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>windows下安装openssh server卡顿的时候使用代理安装的方法</title>
      <link>https://csdn.fjh1997.top/posts/2026042801.html</link>
      <pubDate>Tue, 28 Apr 2026 23:55:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/2026042801.html</guid>
      <description>
        <![CDATA[<h1>windows下安装openssh server卡顿的时候使用代理安装的方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="问题现象">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e7%8e%b0%e8%b1%a1"></a>
问题现象
</h2><p>一开始我是从 Windows 的“设置 -&gt; 系统 -&gt; 可选功能 -&gt; 查看功能”里添加 <code>OpenSSH 服务器</code>，界面一直停在“正在添加”，进度很慢：</p>
<p><img src="/images/windows-openssh-server-optional-feature-stuck.png" alt="可选功能里安装 OpenSSH 服务器卡住"></p>
<p>后面不再等可选功能页面，改成用命令行安装和排查 OpenSSH Server：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Add-WindowsCapability</span> <span class="n">-Online</span> <span class="n">-Name</span> <span class="n">OpenSSH</span><span class="p">.</span><span class="n">Server</span><span class="p">~~~~</span><span class="mf">0.0</span><span class="p">.</span><span class="py">1</span><span class="p">.</span><span class="py">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>命令执行很慢，长时间没有进度。即使给当前 PowerShell 加了代理，例如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nv">$env:http_proxy</span><span class="p">=</span><span class="s2">&#34;http://127.0.0.1:10809&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$env:https_proxy</span><span class="p">=</span><span class="s2">&#34;http://127.0.0.1:10809&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>也不一定有用。</p>
<p>原因是 <code>Add-WindowsCapability</code> 背后不是简单的 PowerShell 下载，而是通过 Windows Update、BITS、CBS/TrustedInstaller 这些系统组件去获取 FoD（Features on Demand）内容。当前用户的环境变量代理不等于系统服务账户代理。</p>
<h2 id="排查过程">
<a class="header-anchor" href="#%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b"></a>
排查过程
</h2><p>先看 WinHTTP 代理：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">netsh</span> <span class="n">winhttp</span> <span class="n">show</span> <span class="n">proxy</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>再看代理端口是否真的在监听：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-NetTCPConnection</span> <span class="n">-LocalAddress</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="py">1</span> <span class="n">-LocalPort</span> <span class="mf">10809</span> <span class="n">-State</span> <span class="n">Listen</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果使用 v2rayN/xray，通常 HTTP 代理端口是 <code>127.0.0.1:10809</code>；如果使用 Clash，常见端口是 <code>127.0.0.1:7890</code>。</p>
<p>然后看 CBS/DISM 日志：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Select-String</span> <span class="n">-Path</span> <span class="n">C:</span><span class="p">\</span><span class="n">Windows</span><span class="p">\</span><span class="n">Logs</span><span class="p">\</span><span class="n">CBS</span><span class="p">\</span><span class="n">CBS</span><span class="p">.</span><span class="py">log</span> <span class="n">-Pattern</span> <span class="s2">&#34;FCAcquirerWUClient|DownloadProgress|0x&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">Select-String</span> <span class="n">-Path</span> <span class="n">C:</span><span class="p">\</span><span class="n">Windows</span><span class="p">\</span><span class="n">Logs</span><span class="p">\</span><span class="n">DISM</span><span class="p">\</span><span class="n">dism</span><span class="p">.</span><span class="py">log</span> <span class="n">-Pattern</span> <span class="s2">&#34;OpenSSH|Add-Capability|0x&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>我这里看到的关键日志是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">FCAcquirerWUClient: WULib DownloadProgress: [0 / 100]
</span></span></code></pre></td></tr></table>
</div>
</div><p>也就是卡在 Windows Update 下载阶段，并不是 OpenSSH 本身安装慢。</p>
<p>还要检查 CBS 是否有待重启事务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Test-Path</span> <span class="s2">&#34;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">Test-Path</span> <span class="s2">&#34;HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果返回 <code>True</code>，建议先重启。CBS 有 pending reboot 时，<code>Add-WindowsCapability</code> 很容易卡住、失败或重复下载。</p>
<h2 id="正确的代理配置">
<a class="header-anchor" href="#%e6%ad%a3%e7%a1%ae%e7%9a%84%e4%bb%a3%e7%90%86%e9%85%8d%e7%bd%ae"></a>
正确的代理配置
</h2><p>以 <code>127.0.0.1:10809</code> 为例，管理员 PowerShell 执行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">netsh</span> <span class="n">winhttp</span> <span class="nb">set </span><span class="n">proxy</span> <span class="nb">proxy-server</span><span class="p">=</span><span class="s2">&#34;http=127.0.0.1:10809;https=127.0.0.1:10809&#34;</span> <span class="nb">bypass-list</span><span class="p">=</span><span class="s2">&#34;localhost;127.0.0.1;&lt;local&gt;&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>再给 BITS 的三个服务账户设置代理：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">localsystem</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">networkservice</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">localservice</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>重启相关服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Restart-Service</span> <span class="n">wuauserv</span><span class="p">,</span><span class="n">bits</span><span class="p">,</span><span class="n">DoSvc</span><span class="p">,</span><span class="n">cryptsvc</span> <span class="n">-Force</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果之前已经卡了很久，建议直接重启系统。我的情况就是代理配置正确后仍然卡在 0%，重启清掉 CBS pending 状态后才成功。</p>
<h2 id="重新安装-openssh-server">
<a class="header-anchor" href="#%e9%87%8d%e6%96%b0%e5%ae%89%e8%a3%85-openssh-server"></a>
重新安装 OpenSSH Server
</h2><p>重启后确认代理程序已经启动，端口能连通：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Test-NetConnection</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="py">1</span> <span class="n">-Port</span> <span class="mf">10809</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后执行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">dism</span><span class="p">.</span><span class="py">exe</span> <span class="p">/</span><span class="n">Online</span> <span class="p">/</span><span class="nb">Add-Capability</span> <span class="p">/</span><span class="n">CapabilityName</span><span class="err">:</span><span class="n">OpenSSH</span><span class="p">.</span><span class="n">Server</span><span class="p">~~~~</span><span class="mf">0.0</span><span class="p">.</span><span class="py">1</span><span class="p">.</span><span class="py">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>也可以继续使用 PowerShell：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Add-WindowsCapability</span> <span class="n">-Online</span> <span class="n">-Name</span> <span class="n">OpenSSH</span><span class="p">.</span><span class="n">Server</span><span class="p">~~~~</span><span class="mf">0.0</span><span class="p">.</span><span class="py">1</span><span class="p">.</span><span class="py">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意 capability 名称最后是 <code>0.0.1.0</code>，不要写成 <code>0.0.1.</code>。</p>
<h2 id="安装后启用-sshd">
<a class="header-anchor" href="#%e5%ae%89%e8%a3%85%e5%90%8e%e5%90%af%e7%94%a8-sshd"></a>
安装后启用 sshd
</h2><p>安装成功后检查文件和服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Test-Path</span> <span class="n">C:</span><span class="p">\</span><span class="n">Windows</span><span class="p">\</span><span class="n">System32</span><span class="p">\</span><span class="n">OpenSSH</span><span class="p">\</span><span class="n">sshd</span><span class="p">.</span><span class="py">exe</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-Service</span> <span class="n">sshd</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>启用并启动服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Set-Service</span> <span class="n">-Name</span> <span class="n">sshd</span> <span class="n">-StartupType</span> <span class="n">Automatic</span>
</span></span><span class="line"><span class="cl"><span class="nb">Start-Service</span> <span class="n">-Name</span> <span class="n">sshd</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>开放防火墙 22 端口：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">New-NetFirewallRule</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-Name</span> <span class="s2">&#34;OpenSSH-Server-In-TCP&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-DisplayName</span> <span class="s2">&#34;OpenSSH SSH Server (sshd)&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-Enabled</span> <span class="n">True</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-Direction</span> <span class="n">Inbound</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-Protocol</span> <span class="n">TCP</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-Action</span> <span class="n">Allow</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">  <span class="n">-LocalPort</span> <span class="mf">22</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果规则已经存在，可以改成所有网络配置文件都生效：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Set-NetFirewallRule</span> <span class="n">-Name</span> <span class="s2">&#34;OpenSSH-Server-In-TCP&#34;</span> <span class="n">-Enabled</span> <span class="n">True</span> <span class="n">-Profile</span> <span class="n">Any</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="验证">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81"></a>
验证
</h2><p>查看服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-Service</span> <span class="n">sshd</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>正常应该是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">Status   : Running
</span></span><span class="line"><span class="cl">StartType: Automatic
</span></span></code></pre></td></tr></table>
</div>
</div><p>查看监听：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">netstat</span> <span class="n">-ano</span> <span class="n">-p</span> <span class="n">tcp</span> <span class="p">|</span> <span class="nb">Select-String</span> <span class="s2">&#34;:22 &#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>正常会看到：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">TCP    0.0.0.0:22    0.0.0.0:0    LISTENING
</span></span></code></pre></td></tr></table>
</div>
</div><p>局域网其他机器连接：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh 用户名@Windows主机IP
</span></span></code></pre></td></tr></table>
</div>
</div><p>例如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh fjh1996@192.168.1.10
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>这个问题的关键点是：</p>
<ol>
<li><code>http_proxy</code> / <code>https_proxy</code> 只影响当前进程，不足以让 Windows Update 服务走代理。</li>
<li><code>Add-WindowsCapability</code> 背后依赖 Windows Update、BITS 和 CBS。</li>
<li>需要同时配置 WinHTTP 代理和 BITS 服务账户代理。</li>
<li>如果 CBS 已经有 <code>RebootPending</code>，先重启，否则可能一直卡在 <code>DownloadProgress: [0 / 100]</code>。</li>
<li>安装成功后还要启动 <code>sshd</code> 服务并检查防火墙规则。</li>
</ol>
<p>最终有效流程就是：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">netsh</span> <span class="n">winhttp</span> <span class="nb">set </span><span class="n">proxy</span> <span class="nb">proxy-server</span><span class="p">=</span><span class="s2">&#34;http=127.0.0.1:10809;https=127.0.0.1:10809&#34;</span> <span class="nb">bypass-list</span><span class="p">=</span><span class="s2">&#34;localhost;127.0.0.1;&lt;local&gt;&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">localsystem</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">networkservice</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span><span class="line"><span class="cl"><span class="n">bitsadmin</span> <span class="p">/</span><span class="n">util</span> <span class="p">/</span><span class="n">setieproxy</span> <span class="n">localservice</span> <span class="n">MANUAL_PROXY</span> <span class="mf">127.0</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">1</span><span class="err">:</span><span class="mf">10809</span> <span class="n">NULL</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">Restart-Service</span> <span class="n">wuauserv</span><span class="p">,</span><span class="n">bits</span><span class="p">,</span><span class="n">DoSvc</span><span class="p">,</span><span class="n">cryptsvc</span> <span class="n">-Force</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">dism</span><span class="p">.</span><span class="py">exe</span> <span class="p">/</span><span class="n">Online</span> <span class="p">/</span><span class="nb">Add-Capability</span> <span class="p">/</span><span class="n">CapabilityName</span><span class="err">:</span><span class="n">OpenSSH</span><span class="p">.</span><span class="n">Server</span><span class="p">~~~~</span><span class="mf">0.0</span><span class="p">.</span><span class="py">1</span><span class="p">.</span><span class="py">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">Set-Service</span> <span class="n">-Name</span> <span class="n">sshd</span> <span class="n">-StartupType</span> <span class="n">Automatic</span>
</span></span><span class="line"><span class="cl"><span class="nb">Start-Service</span> <span class="n">-Name</span> <span class="n">sshd</span>
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2026-04-28首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-04-28</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>VMware Workstation 虚拟网卡丢失 &#43; VMware Tools 复制粘贴失效的完整排查与修复</title>
      <link>https://csdn.fjh1997.top/posts/10604.html</link>
      <pubDate>Thu, 16 Apr 2026 14:38:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/10604.html</guid>
      <description>
        <![CDATA[<h1>VMware Workstation 虚拟网卡丢失 + VMware Tools 复制粘贴失效的完整排查与修复</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="问题背景">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e8%83%8c%e6%99%af"></a>
问题背景
</h2><p>宿主机 Windows（VMware Workstation 17.6.0），虚拟机 Windows 7 SP1 32位。遇到两个问题：</p>
<ol>
<li>宿主机无法连接虚拟机（ping 不通）</li>
<li>修复网络后，VMware Tools 的复制粘贴功能不工作</li>
</ol>
<p>以下是完整的排查过程。</p>
<h2 id="问题一宿主机无法连接虚拟机">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e4%b8%80%e5%ae%bf%e4%b8%bb%e6%9c%ba%e6%97%a0%e6%b3%95%e8%bf%9e%e6%8e%a5%e8%99%9a%e6%8b%9f%e6%9c%ba"></a>
问题一：宿主机无法连接虚拟机
</h2><h3 id="现象">
<a class="header-anchor" href="#%e7%8e%b0%e8%b1%a1"></a>
现象
</h3><p>虚拟机 IP 为 <code>192.168.191.129</code>（NAT 模式），从宿主机 ping 100% 丢包：</p>
<pre tabindex="0"><code>ping 192.168.191.129
请求超时。
请求超时。
数据包: 已发送 = 2，已接收 = 0，丢失 = 2 (100% 丢失)
</code></pre><h3 id="排查过程">
<a class="header-anchor" href="#%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b"></a>
排查过程
</h3><p>检查宿主机网卡状态：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-NetAdapter</span> <span class="p">|</span> <span class="nb">Format-Table</span> <span class="n">Name</span><span class="p">,</span> <span class="n">InterfaceDescription</span><span class="p">,</span> <span class="n">Status</span><span class="p">,</span> <span class="n">MacAddress</span> <span class="n">-AutoSize</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre tabindex="0"><code>Name                          InterfaceDescription                       Status      MacAddress
----                          --------------------                       ------      ----------
以太网                        Intel(R) Ethernet Connection (22) I219-LM  Up          F4-F1-9E-42-D8-DD
VMware Network Adapter VMnet1 VMware Virtual Ethernet Adapter for VMnet1 Not Present 00-50-56-C0-00-01
VMware Network Adapter VMnet8 VMware Virtual Ethernet Adapter for VMnet8 Not Present 00-50-56-C0-00-08
</code></pre><p>关键发现：VMnet1（Host-Only）和 VMnet8（NAT）状态都是 <code>Not Present</code>，<code>AdminStatus: Down</code>。</p>
<p>再看 IPv4 地址分配：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-NetIPAddress</span> <span class="n">-AddressFamily</span> <span class="n">IPv4</span> <span class="p">|</span> <span class="nb">Format-Table</span> <span class="n">InterfaceAlias</span><span class="p">,</span> <span class="n">IPAddress</span><span class="p">,</span> <span class="n">PrefixLength</span> <span class="n">-AutoSize</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre tabindex="0"><code>InterfaceAlias              IPAddress   PrefixLength
--------------              ---------   ------------
以太网                      10.30.17.50           24
Loopback Pseudo-Interface 1 127.0.0.1              8
</code></pre><p>宿主机只有物理网卡有 IP，VMware 虚拟网卡完全没有加载，自然没有到 <code>192.168.191.x</code> 网段的路由。</p>
<p>同时 VMware NAT Service 虽然在运行，但网卡驱动本身没有加载：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-Service</span> <span class="n">-Name</span> <span class="s1">&#39;VMware*&#39;</span> <span class="p">|</span> <span class="nb">Format-Table</span> <span class="n">Name</span><span class="p">,</span> <span class="n">DisplayName</span><span class="p">,</span> <span class="n">Status</span> <span class="n">-AutoSize</span>
</span></span></code></pre></td></tr></table>
</div>
</div><pre tabindex="0"><code>Name                   DisplayName          Status
----                   -----------          ------
VMware NAT Service     VMware NAT Service  Running
VmwareAutostartService VMware 自动启动服务  Stopped
</code></pre><h3 id="根因">
<a class="header-anchor" href="#%e6%a0%b9%e5%9b%a0"></a>
根因
</h3><p>VMware 虚拟网卡驱动未正确加载，网卡处于 <code>Not Present</code> 状态。NAT Service 虽然在跑，但没有对应的虚拟网卡承载流量。</p>
<h3 id="解决方法">
<a class="header-anchor" href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%b3%95"></a>
解决方法
</h3><p>打开 VMware Workstation → Edit → Virtual Network Editor → 点击 &ldquo;Restore Defaults&rdquo;（需要管理员权限）。这会重新创建 VMnet1/VMnet8 并重装虚拟网卡驱动。</p>
<p>如果不行，还可以：</p>
<ul>
<li>在设备管理器中检查是否有被禁用或带感叹号的 VMware 网卡，右键启用或更新驱动</li>
<li>修复安装 VMware Workstation（运行安装程序选 Repair）</li>
</ul>
<p>恢复后虚拟机 IP 变为 <code>192.168.78.128</code>，网络连通。</p>
<h2 id="问题二vmware-tools-服务启动失败">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e4%ba%8cvmware-tools-%e6%9c%8d%e5%8a%a1%e5%90%af%e5%8a%a8%e5%a4%b1%e8%b4%a5"></a>
问题二：VMware Tools 服务启动失败
</h2><h3 id="现象-1">
<a class="header-anchor" href="#%e7%8e%b0%e8%b1%a1-1"></a>
现象
</h3><p>网络恢复后，SSH 进入虚拟机发现 VMware Tools 没有正常工作。</p>
<h3 id="排查过程-1">
<a class="header-anchor" href="#%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b-1"></a>
排查过程
</h3><p>通过 SSH（paramiko）远程执行命令检查（注意：这台 VM 是 Windows 7，不是 Linux）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">sc query VMTools
</span></span></code></pre></td></tr></table>
</div>
</div><pre tabindex="0"><code>SERVICE_NAME: VMTools
        TYPE               : 10  WIN32_OWN_PROCESS
        STATE              : 1  STOPPED
        WIN32_EXIT_CODE    : 183 (0xB7)
</code></pre><p>VMTools 服务状态为 <code>STOPPED</code>，退出码 <code>183</code>（<code>ERROR_ALREADY_EXISTS</code>）。</p>
<p>同时检查进程：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl">tasklist <span class="p">|</span> findstr /i vmtoolsd
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现 <code>vmtoolsd.exe</code>（PID 1868）在用户会话（Console Session 1）里运行着——这是用户态的托盘进程，但系统服务层面的 VMTools 没有启动。</p>
<h3 id="根因-1">
<a class="header-anchor" href="#%e6%a0%b9%e5%9b%a0-1"></a>
根因
</h3><p>之前异常退出后残留了用户态 <code>vmtoolsd.exe</code> 进程，占用了资源，导致系统服务启动时报错 183（<code>ERROR_ALREADY_EXISTS</code>，资源冲突）。</p>
<h3 id="解决方法-1">
<a class="header-anchor" href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%b3%95-1"></a>
解决方法
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl"><span class="p">:</span><span class="c1">: 先杀掉残留的 vmtoolsd 进程</span>
</span></span><span class="line"><span class="cl">taskkill /f /im vmtoolsd.exe
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">:</span><span class="c1">: 然后重新启动服务</span>
</span></span><span class="line"><span class="cl">net start VMTools
</span></span></code></pre></td></tr></table>
</div>
</div><p>执行后服务恢复正常：</p>
<pre tabindex="0"><code>SERVICE_NAME: VMTools
        STATE              : 4  RUNNING
        WIN32_EXIT_CODE    : 0
</code></pre><h2 id="问题三复制粘贴仍然不工作">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e4%b8%89%e5%a4%8d%e5%88%b6%e7%b2%98%e8%b4%b4%e4%bb%8d%e7%84%b6%e4%b8%8d%e5%b7%a5%e4%bd%9c"></a>
问题三：复制粘贴仍然不工作
</h2><h3 id="现象-2">
<a class="header-anchor" href="#%e7%8e%b0%e8%b1%a1-2"></a>
现象
</h3><p>VMTools 服务正常运行后，宿主机和虚拟机之间的复制粘贴仍然不可用。</p>
<h3 id="排查过程-2">
<a class="header-anchor" href="#%e6%8e%92%e6%9f%a5%e8%bf%87%e7%a8%8b-2"></a>
排查过程
</h3><h4 id="第一步检查用户态进程">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e6%a3%80%e6%9f%a5%e7%94%a8%e6%88%b7%e6%80%81%e8%bf%9b%e7%a8%8b"></a>
第一步：检查用户态进程
</h4><p>复制粘贴功能依赖两个 <code>vmtoolsd.exe</code> 进程：</p>
<ul>
<li>系统服务进程（Session 0）：负责基础的 Guest-Host 通信</li>
<li>用户态进程 <code>vmtoolsd.exe -n vmusr</code>（桌面会话）：负责加载 <code>dndcp.dll</code> 插件处理剪贴板同步和拖拽</li>
</ul>
<p>检查发现只有系统服务进程在运行，用户态进程缺失。</p>
<p>确认插件文件存在：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl"><span class="k">dir</span> <span class="s2">&#34;C:\Program Files\VMware\VMware Tools\plugins\vmusr&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>dndcp.dll</code>（拖拽和复制粘贴插件）文件完好。</p>
<p>注册表中 VMware User Process 启动项也存在，但重启后用户态进程就是没有自动拉起。</p>
<h4 id="第二步尝试手动启动用户态进程">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e5%b0%9d%e8%af%95%e6%89%8b%e5%8a%a8%e5%90%af%e5%8a%a8%e7%94%a8%e6%88%b7%e6%80%81%e8%bf%9b%e7%a8%8b"></a>
第二步：尝试手动启动用户态进程
</h4><p>由于 SSH 会话处于 Session 0（服务会话），直接 <code>start</code> 无法在 Session 1 的桌面上创建进程。通过创建批处理文件 + 计划任务的方式在用户桌面会话中启动：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cmd" data-lang="cmd"><span class="line"><span class="cl"><span class="k">echo</span> start <span class="s2">&#34;&#34;</span> <span class="s2">&#34;C:/PROGRA~1/VMware/VMware Tools/vmtoolsd.exe&#34;</span> -n vmusr <span class="p">&gt;</span> C:/vmusr.bat
</span></span><span class="line"><span class="cl">schtasks /create /tn <span class="s2">&#34;StartVMusr&#34;</span> /tr <span class="s2">&#34;C:/vmusr.bat&#34;</span> /sc once /st 00:00 /f /rl highest
</span></span><span class="line"><span class="cl">schtasks /run /tn <span class="s2">&#34;StartVMusr&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>启动后确认两个进程都在运行：</p>
<ul>
<li>PID 1384 — Services 会话（系统服务）</li>
<li>PID 2772 — Console Session 1，ADMIN 用户（用户态）</li>
</ul>
<p>但复制粘贴仍然不工作，而且重启虚拟机后用户态进程又消失了。说明手动拉起只是临时方案，根本原因在别处。</p>
<h4 id="第三步检查-vmx-配置">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%89%e6%ad%a5%e6%a3%80%e6%9f%a5-vmx-%e9%85%8d%e7%bd%ae"></a>
第三步：检查 VMX 配置
</h4><p>检查虚拟机的 <code>.vmx</code> 配置文件（<code>D:\Windows 7\Windows 7.vmx</code>），发现只有：</p>
<pre tabindex="0"><code>isolation.tools.hgfs.disable = &#34;FALSE&#34;
</code></pre><p>缺少 copy/paste 相关的配置项。在 VMware Workstation 17 上，如果没有显式启用，默认可能是禁用的。</p>
<p>通过 rpctool 在 Guest 内确认 isolation 状态均为 <code>UNSET</code>，说明 VMX 层面没有显式配置。</p>
<h3 id="根因-2">
<a class="header-anchor" href="#%e6%a0%b9%e5%9b%a0-2"></a>
根因
</h3><p>两个原因叠加：</p>
<ol>
<li>VMX 配置文件中缺少 <code>isolation.tools.copy.disable = &quot;FALSE&quot;</code> 和 <code>isolation.tools.paste.disable = &quot;FALSE&quot;</code> 的显式配置，在 Workstation 17 上默认行为可能是禁用</li>
<li>由于 isolation 配置缺失，用户态 <code>vmtoolsd -n vmusr</code> 进程无法正常自动启动（负责剪贴板同步的进程缺失）</li>
</ol>
<p>也就是说，用户态进程不自动启动的根本原因就是 VMX 里缺少 isolation 配置。加上配置后，重启虚拟机用户态进程就能正常自动拉起了。</p>
<h3 id="解决方法-2">
<a class="header-anchor" href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%b3%95-2"></a>
解决方法
</h3><p>关闭虚拟机，在 <code>.vmx</code> 文件中添加以下三行：</p>
<pre tabindex="0"><code>isolation.tools.copy.disable = &#34;FALSE&#34;
isolation.tools.paste.disable = &#34;FALSE&#34;
isolation.tools.dnd.disable = &#34;FALSE&#34;
</code></pre><p>然后重新启动虚拟机。启动后验证：</p>
<ul>
<li>VMTools 服务正常运行（RUNNING）</li>
<li>用户态 <code>vmtoolsd -n vmusr</code>（Console Session 1）自动启动——之前一直无法自启的问题也一并解决</li>
<li>复制粘贴功能恢复正常</li>
</ul>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><table>
  <thead>
      <tr>
          <th>问题</th>
          <th>根因</th>
          <th>解决方法</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>宿主机 ping 不通虚拟机</td>
          <td>VMware 虚拟网卡驱动未加载（Not Present）</td>
          <td>Virtual Network Editor → Restore Defaults</td>
      </tr>
      <tr>
          <td>VMTools 服务启动失败（错误码 183）</td>
          <td>残留的用户态 vmtoolsd 进程占用资源</td>
          <td><code>taskkill /f /im vmtoolsd.exe</code> 后重启服务</td>
      </tr>
      <tr>
          <td>复制粘贴不工作 + 用户态 vmtoolsd 不自启</td>
          <td>VMX 缺少 isolation 配置，导致用户态进程无法自启</td>
          <td>在 vmx 中添加 copy/paste/dnd 的 disable=FALSE 配置后重启</td>
      </tr>
  </tbody>
</table>

        
        <hr><p>本文2026-04-16首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-04-16</p>]]>
      </description>
      
        <category>运维排错</category>
      
    </item>
    
    

    <item>
      <title>Ubuntu 24.04 安装 NVIDIA 驱动后 GNOME 远程桌面黑屏/灰屏的排错与解决</title>
      <link>https://csdn.fjh1997.top/posts/8009.html</link>
      <pubDate>Thu, 26 Mar 2026 17:40:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/8009.html</guid>
      <description>
        <![CDATA[<h1>Ubuntu 24.04 安装 NVIDIA 驱动后 GNOME 远程桌面黑屏/灰屏的排错与解决</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="问题描述">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98%e6%8f%8f%e8%bf%b0"></a>
问题描述
</h2><p>Ubuntu 24.04 LTS 工作站，安装 NVIDIA 闭源驱动（nvidia-driver-580）后，通过 Windows 远程桌面连接（mstsc）使用 GNOME 内置 RDP 服务连接时，出现灰屏或黑屏，无法正常显示桌面。</p>
<p>环境信息：</p>
<ul>
<li>系统：Ubuntu 24.04 LTS (Noble Numbat)</li>
<li>内核：6.17.0-19-generic</li>
<li>独显：NVIDIA GeForce RTX 4070</li>
<li>驱动：nvidia-driver-580 (580.126.09)</li>
<li>远程桌面服务：GNOME Remote Desktop (gnome-remote-desktop 46.2)</li>
<li>客户端：Windows 11 远程桌面连接 (mstsc)</li>
</ul>
<!-- more -->
<h2 id="根因分析">
<a class="header-anchor" href="#%e6%a0%b9%e5%9b%a0%e5%88%86%e6%9e%90"></a>
根因分析
</h2><p>GNOME Remote Desktop 的 RDP 连接链路如下：</p>
<pre tabindex="0"><code>Windows mstsc → GNOME Remote Desktop (系统级)
    → handover → 用户桌面会话
        → Mutter 合成器 → PipeWire 屏幕捕获
            → gnome-remote-desktop (用户级) → RDP 编码输出
</code></pre><p>问题的根本原因是 Ubuntu 24.04 默认安装的 <code>gnome-shell</code>（46.0-0ubuntu6~24.04.3）和 <code>gnome-remote-desktop</code>（46.2）版本过低，在 NVIDIA 闭源驱动环境下存在以下 bug：</p>
<ol>
<li>
<p><strong>gnome-shell 在 RDP handover 时 segfault</strong>：通过 RDP 登录触发用户会话创建时，gnome-shell 在 <code>libc.so.6</code> 中发生 general protection fault 崩溃，导致用户会话无法注册，GDM 报 <code>Session never registered, failing</code>。</p>
</li>
<li>
<p><strong>gnome-remote-desktop handover 超时</strong>：即使 gnome-shell 不崩溃，旧版 gnome-remote-desktop 在 NVIDIA + Wayland 环境下的 handover 流程也存在缺陷，日志表现为 <code>Failed to request remote desktop handover: Timeout was reached</code>。</p>
</li>
</ol>
<p>通过对比一台配置相似但 RDP 工作正常的机器（同样使用 NVIDIA 闭源驱动 580 + Wayland），发现其 <code>gnome-shell</code> 版本为 46.0-0ubuntu6~24.04.13，<code>gnome-remote-desktop</code> 版本为 46.3-0ubuntu1.2，均高于出问题的机器。升级后问题解决。</p>
<h2 id="解决方案">
<a class="header-anchor" href="#%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88"></a>
解决方案
</h2><p>一条命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update <span class="o">&amp;&amp;</span> sudo apt install -y gnome-shell gnome-remote-desktop mutter
</span></span></code></pre></td></tr></table>
</div>
</div><p>升级后重启：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo reboot
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="验证">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81"></a>
验证
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 确认版本</span>
</span></span><span class="line"><span class="cl">dpkg -l <span class="p">|</span> grep -E <span class="s1">&#39;gnome-shell |gnome-remote-desktop &#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># gnome-shell         46.0-0ubuntu6~24.04.13</span>
</span></span><span class="line"><span class="cl"><span class="c1"># gnome-remote-desktop 46.3-0ubuntu1.2</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 确认远程桌面服务正常</span>
</span></span><span class="line"><span class="cl">journalctl --user -u gnome-remote-desktop --since <span class="s1">&#39;1 min ago&#39;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 应显示 &#34;RDP server started&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c1"># CUDA 初始化成功：[RDP] Initialization of CUDA was successful</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>使用 Windows 远程桌面连接，输入 IP、用户名和密码，即可正常看到桌面。NVIDIA GPU 的 CUDA 计算能力不受影响。</p>
<h2 id="版本对比">
<a class="header-anchor" href="#%e7%89%88%e6%9c%ac%e5%af%b9%e6%af%94"></a>
版本对比
</h2><table>
  <thead>
      <tr>
          <th>包</th>
          <th>修复前（黑屏）</th>
          <th>修复后（正常）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>gnome-shell</td>
          <td>46.0-0ubuntu6~24.04.<strong>3</strong></td>
          <td>46.0-0ubuntu6~24.04.<strong>13</strong></td>
      </tr>
      <tr>
          <td>gnome-remote-desktop</td>
          <td><strong>46.2</strong>-1~ubuntu24.04.2</td>
          <td><strong>46.3</strong>-0ubuntu1.2</td>
      </tr>
      <tr>
          <td>mutter</td>
          <td>旧版</td>
          <td>46.2-1ubuntu0.24.04.14</td>
      </tr>
  </tbody>
</table>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>这个问题不是 NVIDIA 驱动本身的兼容性问题，而是 Ubuntu 24.04 早期版本的 gnome-shell 和 gnome-remote-desktop 在 NVIDIA 驱动环境下存在 bug。升级到最新的补丁版本即可修复，无需切换核显、修改 prime-select 或更换远程桌面工具。</p>

        
        <hr><p>本文2026-03-26首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-26</p>]]>
      </description>
      
        <category>Linux运维</category>
      
    </item>
    
    

    <item>
      <title>彻底解决移动光猫（ZN-M180G）IPv6 频繁掉线：禁用高负载 Java/OSGi 插件实录</title>
      <link>https://csdn.fjh1997.top/posts/17175.html</link>
      <pubDate>Thu, 19 Mar 2026 19:30:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/17175.html</guid>
      <description>
        <![CDATA[<h1>彻底解决移动光猫（ZN-M180G）IPv6 频繁掉线：禁用高负载 Java/OSGi 插件实录</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h1 id="彻底解决移动光猫zn-m180gipv6-频繁掉线">
<a class="header-anchor" href="#%e5%bd%bb%e5%ba%95%e8%a7%a3%e5%86%b3%e7%a7%bb%e5%8a%a8%e5%85%89%e7%8c%abzn-m180gipv6-%e9%a2%91%e7%b9%81%e6%8e%89%e7%ba%bf"></a>
彻底解决移动光猫（ZN-M180G）IPv6 频繁掉线
</h1><h2 id="0-参考文献与前置准备">
<a class="header-anchor" href="#0-%e5%8f%82%e8%80%83%e6%96%87%e7%8c%ae%e4%b8%8e%e5%89%8d%e7%bd%ae%e5%87%86%e5%a4%87"></a>
0. 参考文献与前置准备
</h2><p>在进行任何底层操作前，请务必参考以下社区讨论，确保您拥有光猫的超级管理权限。</p>
<ul>
<li><strong>参考文献</strong>：<a href="https://www.right.com.cn/forum/thread-7362164-1-1.html" target="_blank" rel="noopener noreferrer nofollow">恩山无线论坛 - 移动光猫 ZN-M180G/ZTE 系维护指南</a>
</li>
<li><strong>开启 Telnet 方法</strong>：
在浏览器地址栏直接输入以下地址并回车，显示 <code>TelnetSet Success</code> 即表示开启成功：
<code>http://192.168.1.1/usr=CMCCAdmin&amp;psw=aDm8H%25MdA&amp;cmd=1&amp;telnet.gch</code>
<em>(注：默认超级账号为 <code>CMCCAdmin</code>，密码通常为 <code>aDm8H%MdA</code>)</em></li>
</ul>
<hr>
<h2 id="1-问题现象">
<a class="header-anchor" href="#1-%e9%97%ae%e9%a2%98%e7%8e%b0%e8%b1%a1"></a>
1. 问题现象
</h2><p>家中的移动光猫（ZN-M180G）IPv6 连接极度不稳定。表现为：电脑刚开机时有 IPv6 且通畅，但过一段时间（几十分钟到几小时）后，IPv6 地址会突然消失，或者虽然有地址但无法 Ping 通。必须手动去路由器后台重开关 RA/DHCPv6 才能暂时恢复。</p>
<p>与此形成鲜明对比的是，IPv4 却始终稳如泰山。</p>
<h2 id="2-深度排查为什么-ipv6-会掉">
<a class="header-anchor" href="#2-%e6%b7%b1%e5%ba%a6%e6%8e%92%e6%9f%a5%e4%b8%ba%e4%bb%80%e4%b9%88-ipv6-%e4%bc%9a%e6%8e%89"></a>
2. 深度排查：为什么 IPv6 会掉？
</h2><h3 id="21-性能分析load-average-13-的惊悚现场">
<a class="header-anchor" href="#21-%e6%80%a7%e8%83%bd%e5%88%86%e6%9e%90load-average-13-%e7%9a%84%e6%83%8a%e6%82%9a%e7%8e%b0%e5%9c%ba"></a>
2.1 性能分析：Load Average 13 的惊悚现场
</h3><p>通过 Telnet 登录光猫后台，执行 <code>uptime</code> 和 <code>top</code> 命令，发现了令人震惊的一幕：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">~ $ uptime
</span></span><span class="line"><span class="cl">Load average: 13.35 12.43 11.99
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>诊断</strong>：对于这类嵌入式网关，Load Average 超过 1 即为满载。13 意味着系统的处理压力是其极限能力的 <strong>10 倍以上</strong>！</p>
<h3 id="22-罪魁祸首osgi-与-java-插件">
<a class="header-anchor" href="#22-%e7%bd%aa%e9%ad%81%e7%a5%b8%e9%a6%96osgi-%e4%b8%8e-java-%e6%8f%92%e4%bb%b6"></a>
2.2 罪魁祸首：OSGi 与 Java 插件
</h3><p>在进程列表（<code>ps</code>）中，我们发现了一个占用超过 <strong>239MB 内存</strong> 的 Java 进程：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="m">1420</span>  <span class="m">1</span>  java  S  239m 50.1  <span class="m">0</span>  0.0 java -noverify -Dfile.encoding<span class="o">=</span>UTF-8 ...
</span></span></code></pre></td></tr></table>
</div>
</div><p>这就是移动光猫预装的 <strong>OSGi (Open Service Gateway Initiative)</strong> 智能插件环境（如 AndLink/和家亲插件）。它极其吃资源，抢占了内核处理 IPv6 报文的信号量。</p>
<h3 id="23-根源分析ipv6-的心跳机制">
<a class="header-anchor" href="#23-%e6%a0%b9%e6%ba%90%e5%88%86%e6%9e%90ipv6-%e7%9a%84%e5%bf%83%e8%b7%b3%e6%9c%ba%e5%88%b6"></a>
2.3 根源分析：IPv6 的“心跳机制”
</h3><p>IPv6 依赖路由器周期性发送 <strong>RA (Router Advertisement)</strong> 通告。当光猫 CPU 被 Java 插件占满时，RA 发送进程会被卡死。电脑听不到“心跳”通告，就会认为 IPv6 已失效，从而删除地址。而 IPv4 是基于租约制的“合同”，对 CPU 实时性要求较低，所以 IPv4 没问题。</p>
<hr>
<h2 id="3-终极解决方案三维打击">
<a class="header-anchor" href="#3-%e7%bb%88%e6%9e%81%e8%a7%a3%e5%86%b3%e6%96%b9%e6%a1%88%e4%b8%89%e7%bb%b4%e6%89%93%e5%87%bb"></a>
3. 终极解决方案：三维打击
</h2><p>由于网页端（Web）往往隐藏了插件开关，且简单的 <code>kill</code> 命令无法阻止插件自动重启，我们采取以下三种深度修复手段：</p>
<h3 id="31-文件层重命名-java-二进制断其生路">
<a class="header-anchor" href="#31-%e6%96%87%e4%bb%b6%e5%b1%82%e9%87%8d%e5%91%bd%e5%90%8d-java-%e4%ba%8c%e8%bf%9b%e5%88%b6%e6%96%ad%e5%85%b6%e7%94%9f%e8%b7%af"></a>
3.1 文件层：重命名 Java 二进制（断其生路）
</h3><p>通过 Telnet 将 Java 的执行文件改名，这样即便启动脚本尝试调用，也会因找不到文件而失败。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># Telnet 登录后执行</span>
</span></span><span class="line"><span class="cl"><span class="nb">mv </span><span class="p">/</span><span class="n">usr</span><span class="p">/</span><span class="n">local</span><span class="p">/</span><span class="n">osgi</span><span class="p">/</span><span class="n">local</span><span class="p">/</span><span class="n">j2re</span><span class="p">/</span><span class="n">bin</span><span class="p">/</span><span class="n">java</span> <span class="p">/</span><span class="n">usr</span><span class="p">/</span><span class="n">local</span><span class="p">/</span><span class="n">osgi</span><span class="p">/</span><span class="n">local</span><span class="p">/</span><span class="n">j2re</span><span class="p">/</span><span class="n">bin</span><span class="p">/</span><span class="n">java_bak</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="32-配置层sidbg-数据库修改锁其开关">
<a class="header-anchor" href="#32-%e9%85%8d%e7%bd%ae%e5%b1%82sidbg-%e6%95%b0%e6%8d%ae%e5%ba%93%e4%bf%ae%e6%94%b9%e9%94%81%e5%85%b6%e5%bc%80%e5%85%b3"></a>
3.2 配置层：sidbg 数据库修改（锁其开关）
</h3><p>利用中兴系底层的 <code>sidbg</code> 工具，从数据库层面彻底关闭 OSGi 启动项。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 禁用 OSGi 服务</span>
</span></span><span class="line"><span class="cl">sidbg <span class="m">1</span> DB <span class="nb">set</span> OBJ_OSGI_ID <span class="m">0</span> Enable <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 禁用 AndLink 服务</span>
</span></span><span class="line"><span class="cl">sidbg <span class="m">1</span> DB <span class="nb">set</span> OBJ_ANDLINK_ID <span class="m">0</span> Enable <span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 保存配置并重启</span>
</span></span><span class="line"><span class="cl">sidbg <span class="m">1</span> DB save
</span></span><span class="line"><span class="cl">reboot
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="33-客户端层windows-协议栈重置清理残留">
<a class="header-anchor" href="#33-%e5%ae%a2%e6%88%b7%e7%ab%af%e5%b1%82windows-%e5%8d%8f%e8%ae%ae%e6%a0%88%e9%87%8d%e7%bd%ae%e6%b8%85%e7%90%86%e6%ae%8b%e7%95%99"></a>
3.3 客户端层：Windows 协议栈重置（清理残留）
</h3><p>光猫重启后，由于前缀可能变化，电脑会残留过期的 IPv6 租约。需在电脑端以管理员权限运行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 重置 IPv6 协议栈并重启网卡</span>
</span></span><span class="line"><span class="cl"><span class="n">netsh</span> <span class="n">int</span> <span class="n">ipv6</span> <span class="n">reset</span>
</span></span><span class="line"><span class="cl"><span class="nb">Disable-NetAdapter</span> <span class="n">-Name</span> <span class="s2">&#34;以太网&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">Enable-NetAdapter</span> <span class="n">-Name</span> <span class="s2">&#34;以太网&#34;</span>
</span></span><span class="line"><span class="cl"><span class="c"># 重新请求地址</span>
</span></span><span class="line"><span class="cl"><span class="n">ipconfig</span> <span class="p">/</span><span class="n">renew6</span>
</span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="4-修复结果对比">
<a class="header-anchor" href="#4-%e4%bf%ae%e5%a4%8d%e7%bb%93%e6%9e%9c%e5%af%b9%e6%af%94"></a>
4. 修复结果对比
</h2><ul>
<li><strong>修复前</strong>：Load Average &gt; 11，Java 进程常驻，IPv6 每小时掉线一次。</li>
<li><strong>修复后</strong>：Load Average &lt; 1.0，CPU 占用率跌至 10% 以下，内存释放 200MB+，IPv6 永久在线且延迟极低。</li>
</ul>
<h2 id="5-总结">
<a class="header-anchor" href="#5-%e6%80%bb%e7%bb%93"></a>
5. 总结
</h2><p>移动定制路由器的 IPv6 不稳定，90% 的原因都是因为预装的 Java 插件抢占了系统资源。通过 <strong>“改名 + 数据库禁用”</strong> 的方案，不仅能解决 IPv6 掉线问题，还能显著提升光猫的转发性能和网页后台响应速度。</p>
<hr>
<p><em>本文由 Gemini CLI 协作排查整理而成。</em></p>

        
        <hr><p>本文2026-03-19首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-19</p>]]>
      </description>
      
        <category>网络技术</category>
      
    </item>
    
    

    <item>
      <title>甲骨文云保留ip重置云主机ssh密钥</title>
      <link>https://csdn.fjh1997.top/posts/29735.html</link>
      <pubDate>Thu, 19 Mar 2026 09:26:12 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/29735.html</guid>
      <description>
        <![CDATA[<h1>甲骨文云保留ip重置云主机ssh密钥</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>想重置密钥，一般可以通过保留引导卷删除实例，然后用新实例套上老引导卷来重置密钥，但这样会丢失ip，想保留ip就只能另想办法，折腾一上午搞定了:<br>
在控制台里面启动cloud shell连接
<img src="/images/2026-03-19-09-27-19.png" alt="2026-03-19-09-27-19"></p>
<p><img src="/images/2026-03-19-09-27-37.png" alt="2026-03-19-09-27-37"></p>
<p>之后重启实例，重新引导
<img src="/images/2026-03-19-09-29-14.png" alt="2026-03-19-09-29-14">
等一段时间进入bios
<img src="/images/2026-03-19-09-26-27.png" alt="2026-03-19-09-26-27">
在启动项里面选择ubuntu然后使劲不停按esc，手速要快进入grub shell
<img src="/images/2026-03-19-09-30-52.png" alt="2026-03-19-09-30-52">
使用以下命令查看grub引导配置文件</p>
<pre tabindex="0"><code>cat (hd0,gpt16)/grub/grub.cfg
</code></pre><p><img src="/images/2026-03-19-10-02-25.png" alt="2026-03-19-10-02-25"></p>
<p><img src="/images/2026-03-19-11-11-21.png" alt="2026-03-19-11-11-21"></p>
<p>根据配置里面的uuid编写以下重启命令,输入，建议一行行粘贴，以免串口出现问题</p>
<pre tabindex="0"><code>
set root=&#39;hd0,gpt16&#39;

linux /vmlinuz-6.17.0-1009-oracle root=UUID=e0f59922-b350-40cc-b9a1-02d3da04fd65 rw console=tty1 console=ttyS0 nvme.shutdown_timeout=10 libiscsi.debug_libiscsi_eh=1 crash_kexec_post_notifiers init=/bin/bash

initrd /initrd.img-6.17.0-1009-oracle
</code></pre><p>确保输入正确之后</p>
<pre tabindex="0"><code>boot
</code></pre><p>进入shell，就能修改密码了
<img src="/images/2026-03-19-11-16-19.png" alt="2026-03-19-11-16-19">
之后使用reboot -f 进行重启，不能用exit。不然会卡住</p>
<p>参考：https://www.banzhuti.com/7340.html</p>

        
        <hr><p>本文2026-03-19首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-19</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>通过配置 Edge 浏览器 DoH 和 ECH 实现特定网站如linuxdo裸连访问</title>
      <link>https://csdn.fjh1997.top/posts/20260316.html</link>
      <pubDate>Mon, 16 Mar 2026 12:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/20260316.html</guid>
      <description>
        <![CDATA[<h1>通过配置 Edge 浏览器 DoH 和 ECH 实现特定网站如linuxdo裸连访问</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="前言">
<a class="header-anchor" href="#%e5%89%8d%e8%a8%80"></a>
前言
</h2><p>有些网站虽然没有被 DNS 污染，但由于 SNI（Server Name Indication）明文暴露了域名，导致连接在 TLS 握手阶段被中间设备识别并重置。典型表现是 DNS 能正常解析出 IP，<code>ping</code> 也通，但浏览器就是打不开页面。</p>
<p>解决思路很简单：<strong>DoH（DNS over HTTPS）</strong> 加密 DNS 查询过程，防止 DNS 劫持和污染；<strong>ECH（Encrypted Client Hello）</strong> 加密 TLS 握手中的 SNI 字段，让中间设备无法识别你访问的具体域名。两者配合就可以实现某些被 SNI 阻断的网站的裸连访问。</p>
<p>本文以 Windows + Edge 浏览器为例，记录完整的配置过程。</p>
<h2 id="原理简述">
<a class="header-anchor" href="#%e5%8e%9f%e7%90%86%e7%ae%80%e8%bf%b0"></a>
原理简述
</h2><h3 id="dohdns-over-https">
<a class="header-anchor" href="#dohdns-over-https"></a>
DoH（DNS over HTTPS）
</h3><p>传统 DNS 查询是明文 UDP 协议，任何中间人都能看到和篡改。DoH 将 DNS 查询封装在 HTTPS 请求中，让 DNS 解析过程完全加密。</p>
<h3 id="echencrypted-client-hello">
<a class="header-anchor" href="#echencrypted-client-hello"></a>
ECH（Encrypted Client Hello）
</h3><p>TLS 1.3 握手时，客户端会在 Client Hello 中以<strong>明文</strong>发送 SNI（要访问的域名）。ECH 利用事先通过 DNS HTTPS 记录获取的公钥，对整个 Client Hello 进行加密，让中间设备无法窥探目标域名。</p>
<h3 id="两者的关系">
<a class="header-anchor" href="#%e4%b8%a4%e8%80%85%e7%9a%84%e5%85%b3%e7%b3%bb"></a>
两者的关系
</h3><p>ECH 的密钥是通过 DNS 的 <code>HTTPS</code> 类型记录（TYPE65）分发的。如果 DNS 查询本身不加密（被劫持或污染），ECH 密钥就拿不到，ECH 自然也无法工作。所以 <strong>DoH 是 ECH 的前置条件</strong>。</p>
<pre tabindex="0"><code>┌─────────────────────┐
│   DoH DNS 服务器     │
│  (加密 DNS 查询)     │
└────────┬────────────┘
     │
① 通过 HTTPS 加密查询 DNS
② 获取目标站点的 ECH 公钥
     │
┌────▼──────┐                ┌────────────┐              ┌──────────────┐
│  浏览器   │───③ 加密的───→│  中间设备    │────────────→│  目标服务器   │
│          │   Client Hello│ (看不到 SNI) │              │              │
└──────────┘                └─────────────┘              └──────────────┘
</code></pre><h2 id="配置步骤">
<a class="header-anchor" href="#%e9%85%8d%e7%bd%ae%e6%ad%a5%e9%aa%a4"></a>
配置步骤
</h2><h3 id="第一步配置-edge-的-doh-策略">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e9%85%8d%e7%bd%ae-edge-%e7%9a%84-doh-%e7%ad%96%e7%95%a5"></a>
第一步：配置 Edge 的 DoH 策略
</h3><p>Edge 浏览器的 DoH 可以通过 Windows 注册表（组策略）来配置。以<strong>管理员权限</strong>打开 PowerShell，执行以下命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 启用 Edge 内置 DNS 客户端</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">add</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">BuiltInDnsClientEnabled</span> <span class="p">/</span><span class="n">t</span> <span class="n">REG_DWORD</span> <span class="p">/</span><span class="n">d</span> <span class="mf">1</span> <span class="p">/</span><span class="n">f</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 设置 DoH 模式为 automatic（优先 DoH，失败回退普通 DNS）</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">add</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">DnsOverHttpsMode</span> <span class="p">/</span><span class="n">t</span> <span class="n">REG_SZ</span> <span class="p">/</span><span class="n">d</span> <span class="s2">&#34;automatic&#34;</span> <span class="p">/</span><span class="n">f</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 设置 DoH 服务器模板（替换为你可用的 DoH 服务器地址）</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">add</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">DnsOverHttpsTemplates</span> <span class="p">/</span><span class="n">t</span> <span class="n">REG_SZ</span> <span class="p">/</span><span class="n">d</span> <span class="s2">&#34;https://your-doh-server.example.com/dns-query&#34;</span> <span class="p">/</span><span class="n">f</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>DnsOverHttpsMode 的三种模式：</strong></p>
<table>
  <thead>
      <tr>
          <th>模式</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>off</code></td>
          <td>完全关闭 DoH</td>
      </tr>
      <tr>
          <td><code>automatic</code></td>
          <td>优先 DoH，失败自动回退普通 DNS（<strong>推荐</strong>）</td>
      </tr>
      <tr>
          <td><code>secure</code></td>
          <td>强制 DoH，失败则无法解析（⚠️ 如果 DoH 服务器不可用会导致所有网站打不开）</td>
      </tr>
  </tbody>
</table>
<blockquote>
<p><strong>⚠️ 注意</strong>：<code>secure</code> 模式虽然安全性最高，但如果你的 DoH 服务器在当前网络不可达（比如国内直连 Cloudflare 的 <code>1.1.1.1</code>），会导致<strong>所有网站都无法访问</strong>。建议使用 <code>automatic</code> 模式。</p>
</blockquote>
<p><strong>关于 DoH 服务器的选择：</strong></p>
<ul>
<li>Cloudflare 的 <code>https://cloudflare-dns.com/dns-query</code>（<code>1.1.1.1</code>）是最常见的支持 ECH 密钥分发的 DoH 服务器，但在国内网络可能不可直连。</li>
<li><strong>推荐：使用 Cloudflare Gateway (Zero Trust) 创建私人 DoH 节点</strong>。只需要注册一个免费的 Cloudflare 账号，开通 Zero Trust，在 <code>Gateway -&gt; DNS Locations</code> 中添加一个 Location，它就会自动为你生成一个私有专属的 DoH 地址（例如 <code>https://&lt;一串随机字符&gt;.cloudflare-gateway.com/dns-query</code>）。这种方式目前在国内直连的成功率非常高，而且完全支持 ECH。</li>
<li>阿里 DNS 的 <code>https://dns.alidns.com/dns-query</code> 在国内虽然可用，但它不一定支持返回 HTTPS 类型 DNS 记录（ECH 所需），所以不推荐用作 ECH 方案。</li>
<li>如果你有自建的 DoH 代理或中转服务器，使用你自己的 DoH 地址效果最好，如 linux.do 站长秦始皇提供的 DoH 地址是：<code>https://xxx.ddd.oaifree.com/query-dns</code>（其中 xxx 可以随便换成你喜欢的字符）。</li>
</ul>
<p><strong>验证配置：</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">DnsOverHttpsMode</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">DnsOverHttpsTemplates</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">BuiltInDnsClientEnabled</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="第二步启用-edge-的-ech-功能">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e5%90%af%e7%94%a8-edge-%e7%9a%84-ech-%e5%8a%9f%e8%83%bd"></a>
第二步：启用 Edge 的 ECH 功能
</h3><p>ECH 同样可以通过注册表策略来启用。以<strong>管理员权限</strong>执行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 启用 Encrypted Client Hello</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">add</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">EncryptedClientHelloEnabled</span> <span class="p">/</span><span class="n">t</span> <span class="n">REG_DWORD</span> <span class="p">/</span><span class="n">d</span> <span class="mf">1</span> <span class="p">/</span><span class="n">f</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>验证：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">EncryptedClientHelloEnabled</span>
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p><strong>💡 说明</strong>：较早版本的 Edge 可以在 <code>edge://flags/#encrypted-client-hello</code> 中手动启用 ECH，但新版 Edge（146+）已移除该 flag，需要通过注册表策略 <code>EncryptedClientHelloEnabled</code> 来控制。</p>
</blockquote>
<h3 id="第三步可选配置系统级-dns-加密">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%89%e6%ad%a5%e5%8f%af%e9%80%89%e9%85%8d%e7%bd%ae%e7%b3%bb%e7%bb%9f%e7%ba%a7-dns-%e5%8a%a0%e5%af%86"></a>
第三步：（可选）配置系统级 DNS 加密
</h3><p>除了 Edge 内部的 DoH 之外，还可以在 Windows 系统层面配置 DNS 加密，让系统的 DNS 查询也走加密通道：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 以管理员权限运行</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 1. 将以太网适配器的 DNS 设置为 1.1.1.1 和 1.0.0.1</span>
</span></span><span class="line"><span class="cl"><span class="c">#    先用 Get-NetAdapter 查看你的网络适配器名称和 InterfaceIndex</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-NetAdapter</span> <span class="p">|</span> <span class="nb">Where-Object</span> <span class="n">Status</span> <span class="o">-eq</span> <span class="s1">&#39;Up&#39;</span> <span class="p">|</span> <span class="nb">Select-Object</span> <span class="n">Name</span><span class="p">,</span> <span class="n">InterfaceIndex</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 2. 设置 DNS 服务器（将 13 替换为你的适配器 InterfaceIndex）</span>
</span></span><span class="line"><span class="cl"><span class="nb">Set-DnsClientServerAddress</span> <span class="n">-InterfaceIndex</span> <span class="mf">13</span> <span class="n">-ServerAddresses</span> <span class="s2">&#34;1.1.1.1&#34;</span><span class="p">,</span><span class="s2">&#34;1.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 3. 启用 DoH 自动升级</span>
</span></span><span class="line"><span class="cl"><span class="nb">Set-DnsClientDohServerAddress</span> <span class="n">-ServerAddress</span> <span class="s2">&#34;1.1.1.1&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">    <span class="n">-DohTemplate</span> <span class="s2">&#34;https://cloudflare-dns.com/dns-query&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">    <span class="n">-AllowFallbackToUdp</span> <span class="vm">$true</span> <span class="n">-AutoUpgrade</span> <span class="vm">$true</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">Set-DnsClientDohServerAddress</span> <span class="n">-ServerAddress</span> <span class="s2">&#34;1.0.0.1&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">    <span class="n">-DohTemplate</span> <span class="s2">&#34;https://cloudflare-dns.com/dns-query&#34;</span> <span class="p">`</span>
</span></span><span class="line"><span class="cl">    <span class="n">-AllowFallbackToUdp</span> <span class="vm">$true</span> <span class="n">-AutoUpgrade</span> <span class="vm">$true</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>参数说明：</p>
<ul>
<li><strong>AutoUpgrade = $true</strong>：Windows 会自动将发往该 IP 的 DNS 查询升级为 DoH 加密请求</li>
<li><strong>AllowFallbackToUdp = $true</strong>：DoH 连接失败时回退到普通 UDP DNS，避免断网</li>
</ul>
<h2 id="验证配置">
<a class="header-anchor" href="#%e9%aa%8c%e8%af%81%e9%85%8d%e7%bd%ae"></a>
验证配置
</h2><h3 id="在线测试">
<a class="header-anchor" href="#%e5%9c%a8%e7%ba%bf%e6%b5%8b%e8%af%95"></a>
在线测试
</h3><p>访问 Cloudflare 的浏览器安全检测页面：<a href="https://www.cloudflare-cn.com/ssl/encrypted-sni/" target="_blank" rel="noopener noreferrer nofollow">https://www.cloudflare-cn.com/ssl/encrypted-sni/</a>
</p>
<p>点击 <strong>&ldquo;检查我的浏览器&rdquo;</strong> 按钮，期望结果：</p>
<table>
  <thead>
      <tr>
          <th>项目</th>
          <th>期望状态</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>安全的 DNS (DoH)</td>
          <td>✅ 通过</td>
      </tr>
      <tr>
          <td>DNSSEC</td>
          <td>✅ 通过</td>
      </tr>
      <tr>
          <td>TLS 1.3</td>
          <td>✅ 通过</td>
      </tr>
      <tr>
          <td>安全 SNI (ECH)</td>
          <td>✅ 通过</td>
      </tr>
  </tbody>
</table>
<p>也可以用这个网站测试ech和doh情况：https://doh-ech.zhoulirui.ggff.net/</p>
<h3 id="命令行测试">
<a class="header-anchor" href="#%e5%91%bd%e4%bb%a4%e8%a1%8c%e6%b5%8b%e8%af%95"></a>
命令行测试
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 验证 Edge DoH 和 ECH 策略</span>
</span></span><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c"># 验证系统 DNS 配置</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-DnsClientServerAddress</span> <span class="n">-InterfaceIndex</span> <span class="mf">13</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-DnsClientDohServerAddress</span> <span class="n">-ServerAddress</span> <span class="s2">&#34;1.1.1.1&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="排错指南">
<a class="header-anchor" href="#%e6%8e%92%e9%94%99%e6%8c%87%e5%8d%97"></a>
排错指南
</h2><h3 id="所有网站都打不开">
<a class="header-anchor" href="#%e6%89%80%e6%9c%89%e7%bd%91%e7%ab%99%e9%83%bd%e6%89%93%e4%b8%8d%e5%bc%80"></a>
所有网站都打不开
</h3><ul>
<li>可能是 <code>DnsOverHttpsMode</code> 设置为 <code>secure</code> 但 DoH 服务器不可达</li>
<li>解决：改回 <code>automatic</code> 模式
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">add</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">DnsOverHttpsMode</span> <span class="p">/</span><span class="n">t</span> <span class="n">REG_SZ</span> <span class="p">/</span><span class="n">d</span> <span class="s2">&#34;automatic&#34;</span> <span class="p">/</span><span class="n">f</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="doh-测试未通过">
<a class="header-anchor" href="#doh-%e6%b5%8b%e8%af%95%e6%9c%aa%e9%80%9a%e8%bf%87"></a>
DoH 测试未通过
</h3><ul>
<li>DoH 服务器在当前网络不可达（如国内直连 Cloudflare）</li>
<li>解决：使用国内可达的 DoH 服务器，或者配置代理</li>
</ul>
<h3 id="ech-测试未通过">
<a class="header-anchor" href="#ech-%e6%b5%8b%e8%af%95%e6%9c%aa%e9%80%9a%e8%bf%87"></a>
ECH 测试未通过
</h3><p>ECH 不通过最常见的原因：</p>
<ol>
<li><strong>DoH 服务器不支持返回 HTTPS 类型 DNS 记录</strong>：ECH 密钥通过 DNS HTTPS 记录（TYPE65）分发，不是所有 DoH 服务器都会返回这种记录</li>
<li><strong>目标网站不支持 ECH</strong>：ECH 需要服务端也支持。目前主要是 Cloudflare 托管的网站支持 ECH</li>
<li><strong>ECH 策略未启用</strong>：确认注册表中 <code>EncryptedClientHelloEnabled</code> 值为 <code>1</code>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">reg</span> <span class="n">query</span> <span class="s2">&#34;HKLM\SOFTWARE\Policies\Microsoft\Edge&#34;</span> <span class="p">/</span><span class="n">v</span> <span class="n">EncryptedClientHelloEnabled</span>
</span></span></code></pre></td></tr></table>
</div>
</div></li>
</ol>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>通过配置 DoH + ECH，可以实现对部分被 SNI 阻断的网站的裸连访问（无需代理）。核心配置只有三步：</p>
<ol>
<li><strong>Edge DoH 策略</strong>：通过注册表设置 DoH 模式和 DoH 服务器地址</li>
<li><strong>Edge ECH 策略</strong>：通过注册表设置 <code>EncryptedClientHelloEnabled</code> 启用 ECH</li>
<li><strong>（可选）系统 DNS</strong>：在 Windows 系统层面启用 DNS 加密</li>
</ol>
<p>需要注意的是，这种方案的效果取决于你的网络环境和 DoH 服务器的可达性。最关键的一环是<strong>找到一个在你的网络下可正常使用且支持 HTTPS DNS 记录的 DoH 服务器</strong>。</p>

        
        <hr><p>本文2026-03-16首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-16</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>通过读取微信进程内存提取公众号信息流广告视频下载地址</title>
      <link>https://csdn.fjh1997.top/posts/58321.html</link>
      <pubDate>Sun, 15 Mar 2026 17:31:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/58321.html</guid>
      <description>
        <![CDATA[<h1>通过读取微信进程内存提取公众号信息流广告视频下载地址</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="背景">
<a class="header-anchor" href="#%e8%83%8c%e6%99%af"></a>
背景
</h2><p><img src="/images/2026-03-15-18-47-23.png" alt="2026-03-15-18-47-23">
在PC端微信的公众号列表中，经常会看到信息流广告视频，比如游戏广告。这些广告视频有时候挺有意思，想下载下来，但微信并没有提供下载按钮。比如看到这个广告视频的妹妹很好看🤪，那么应该怎么下载呢？本文以这个&quot;三国冰河时代&quot;游戏广告为例，介绍如何通过读取微信进程内存来提取广告视频的下载地址。</p>
<h2 id="尝试一寻找本地缓存文件失败">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%b8%80%e5%af%bb%e6%89%be%e6%9c%ac%e5%9c%b0%e7%bc%93%e5%ad%98%e6%96%87%e4%bb%b6%e5%a4%b1%e8%b4%a5"></a>
尝试一：寻找本地缓存文件（失败）
</h2><p>首先想到的思路是微信可能把视频缓存到了本地磁盘。微信PC端的数据目录一般在：</p>
<pre tabindex="0"><code>C:\Users\{用户名}\Documents\WeChat Files\{微信ID}\FileStorage\
</code></pre><p>该目录下有这些子目录：</p>
<pre tabindex="0"><code>Cache、Video、Image、Temp、Sns、MsgAttach ...
</code></pre><p>其中 <code>Video</code> 目录按月份分文件夹存放：</p>
<pre tabindex="0"><code>2024-04、2024-05、... 2025-08
</code></pre><p>但逐个检查后发现这些目录要么为空，要么只有聊天中收发的视频。<strong>公众号信息流广告的视频并不会被缓存到这里。</strong></p>
<p>同样检查了 <code>AppData</code> 下的微信目录：</p>
<pre tabindex="0"><code>C:\Users\{用户名}\AppData\Roaming\Tencent\WeChat\
C:\Users\{用户名}\AppData\Roaming\Tencent\xwechat\
</code></pre><p>新版微信（xwechat）使用了 Chromium 内核（RadiumWMPF），有类似浏览器的缓存结构：</p>
<pre tabindex="0"><code>xwechat\radium\web\profiles\webview_{用户hash}\
xwechat\radium\web\profiles\multitab_{用户hash}\
</code></pre><p>里面有 <code>Code Cache</code>、<code>IndexedDB</code>、<code>GPUCache</code> 等 Chromium 标准缓存目录，但也没找到视频文件。</p>
<p><strong>结论：公众号信息流广告视频是流式加载的，不会完整缓存到本地磁盘。</strong></p>
<h2 id="尝试二通过开发者工具远程调试失败">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%ba%8c%e9%80%9a%e8%bf%87%e5%bc%80%e5%8f%91%e8%80%85%e5%b7%a5%e5%85%b7%e8%bf%9c%e7%a8%8b%e8%b0%83%e8%af%95%e5%a4%b1%e8%b4%a5"></a>
尝试二：通过开发者工具/远程调试（失败）
</h2><p>既然新版微信使用 Chromium 内核，理论上可以通过 <code>--remote-debugging-port</code> 参数连接 DevTools 来抓取网络请求。</p>
<p>查看微信进程的命令行参数：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-CimInstance</span> <span class="n">Win32_Process</span> <span class="n">-Filter</span> <span class="s2">&#34;Name=&#39;WeChatAppEx.exe&#39;&#34;</span> <span class="p">|</span> <span class="nb">Select-Object</span> <span class="n">ProcessId</span><span class="p">,</span> <span class="n">CommandLine</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现主进程的启动参数中并没有 <code>--remote-debugging-port</code>，说明远程调试未开启，这条路也走不通。</p>
<h2 id="尝试三进程内存扫描成功">
<a class="header-anchor" href="#%e5%b0%9d%e8%af%95%e4%b8%89%e8%bf%9b%e7%a8%8b%e5%86%85%e5%ad%98%e6%89%ab%e6%8f%8f%e6%88%90%e5%8a%9f"></a>
尝试三：进程内存扫描（成功）
</h2><p>既然视频是流式加载的，那视频的URL一定在微信进程的内存中。思路是：<strong>直接读取微信进程内存，搜索视频URL模式。</strong></p>
<h3 id="第一步定位微信进程">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%80%e6%ad%a5%e5%ae%9a%e4%bd%8d%e5%be%ae%e4%bf%a1%e8%bf%9b%e7%a8%8b"></a>
第一步：定位微信进程
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Get-Process</span> <span class="p">|</span> <span class="nb">Where-Object</span> <span class="p">{</span> <span class="nv">$_</span><span class="p">.</span><span class="py">ProcessName</span> <span class="o">-match</span> <span class="s1">&#39;wechat&#39;</span> <span class="p">}</span> <span class="p">|</span>
</span></span><span class="line"><span class="cl">    <span class="nb">Select-Object</span> <span class="n">Id</span><span class="p">,</span> <span class="n">ProcessName</span><span class="p">,</span> <span class="n">Path</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现微信运行了多个 <code>WeChatAppEx.exe</code> 进程，这是典型的 Chromium 多进程架构：</p>
<table>
  <thead>
      <tr>
          <th>进程类型</th>
          <th>说明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>主进程（无 &ndash;type 参数）</td>
          <td>浏览器主进程，包含页面数据</td>
      </tr>
      <tr>
          <td>&ndash;type=gpu-process</td>
          <td>GPU渲染进程</td>
      </tr>
      <tr>
          <td>&ndash;type=renderer</td>
          <td>页面渲染进程</td>
      </tr>
      <tr>
          <td>&ndash;type=utility &ndash;utility-sub-type=network</td>
          <td>网络服务进程</td>
      </tr>
  </tbody>
</table>
<p>我们要扫描的是<strong>主进程</strong>（没有 <code>--type</code> 参数的那个）。</p>
<h3 id="第二步编写内存扫描脚本">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%8c%e6%ad%a5%e7%bc%96%e5%86%99%e5%86%85%e5%ad%98%e6%89%ab%e6%8f%8f%e8%84%9a%e6%9c%ac"></a>
第二步：编写内存扫描脚本
</h3><p>通过 PowerShell 调用 Windows API 来读取进程内存：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Add-Type</span> <span class="n">-TypeDefinition</span> <span class="sh">@&#39;
</span></span></span><span class="line"><span class="cl"><span class="sh">using System;
</span></span></span><span class="line"><span class="cl"><span class="sh">using System.Runtime.InteropServices;
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">public class MemoryReader {
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern IntPtr OpenProcess(
</span></span></span><span class="line"><span class="cl"><span class="sh">        int dwDesiredAccess, bool bInheritHandle, int dwProcessId);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern bool ReadProcessMemory(
</span></span></span><span class="line"><span class="cl"><span class="sh">        IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer,
</span></span></span><span class="line"><span class="cl"><span class="sh">        int dwSize, ref int lpNumberOfBytesRead);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern int VirtualQueryEx(
</span></span></span><span class="line"><span class="cl"><span class="sh">        IntPtr hProcess, IntPtr lpAddress,
</span></span></span><span class="line"><span class="cl"><span class="sh">        out MEMORY_BASIC_INFORMATION lpBuffer, uint dwLength);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [DllImport(&#34;kernel32.dll&#34;)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public static extern bool CloseHandle(IntPtr hObject);
</span></span></span><span class="line"><span class="cl"><span class="sh">
</span></span></span><span class="line"><span class="cl"><span class="sh">    [StructLayout(LayoutKind.Sequential)]
</span></span></span><span class="line"><span class="cl"><span class="sh">    public struct MEMORY_BASIC_INFORMATION {
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr BaseAddress;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr AllocationBase;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint AllocationProtect;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public IntPtr RegionSize;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint State;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint Protect;
</span></span></span><span class="line"><span class="cl"><span class="sh">        public uint Type;
</span></span></span><span class="line"><span class="cl"><span class="sh">    }
</span></span></span><span class="line"><span class="cl"><span class="sh">}
</span></span></span><span class="line"><span class="cl"><span class="sh">&#39;@</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>核心逻辑是遍历进程的所有已提交内存区域（<code>MEM_COMMIT = 0x1000</code>），读取内容后用正则匹配视频URL：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nv">$targetPid</span> <span class="p">=</span> <span class="mf">42172</span>  <span class="c"># 微信主进程PID</span>
</span></span><span class="line"><span class="cl"><span class="nv">$handle</span> <span class="p">=</span> <span class="p">[</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">OpenProcess</span><span class="p">(</span><span class="n">0x0410</span><span class="p">,</span> <span class="vm">$false</span><span class="p">,</span> <span class="nv">$targetPid</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c"># 0x0410 = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nv">$address</span> <span class="p">=</span> <span class="p">[</span><span class="no">IntPtr</span><span class="p">]::</span><span class="n">Zero</span>
</span></span><span class="line"><span class="cl"><span class="nv">$mbi</span> <span class="p">=</span> <span class="nb">New-Object</span> <span class="n">MemoryReader</span><span class="p">+</span><span class="n">MEMORY_BASIC_INFORMATION</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">while</span> <span class="p">([</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">VirtualQueryEx</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="nv">$handle</span><span class="p">,</span> <span class="nv">$address</span><span class="p">,</span> <span class="p">[</span><span class="no">ref</span><span class="p">]</span><span class="nv">$mbi</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="p">[</span><span class="no">uint32][Runtime.InteropServices.Marshal</span><span class="p">]::</span><span class="n">SizeOf</span><span class="p">(</span><span class="nv">$mbi</span><span class="p">))</span> <span class="o">-ne</span> <span class="mf">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c"># 只扫描已提交的、大小合理的内存区域</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nv">$mbi</span><span class="p">.</span><span class="py">State</span> <span class="o">-eq</span> <span class="n">0x1000</span> <span class="o">-and</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-lt</span> <span class="mf">10</span><span class="p">MB</span> <span class="o">-and</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-gt</span> <span class="mf">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$buffer</span> <span class="p">=</span> <span class="nb">New-Object</span> <span class="n">byte</span><span class="p">[]</span> <span class="p">(</span><span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$bytesRead</span> <span class="p">=</span> <span class="mf">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">([</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">ReadProcessMemory</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$handle</span><span class="p">,</span> <span class="nv">$mbi</span><span class="p">.</span><span class="n">BaseAddress</span><span class="p">,</span> <span class="nv">$buffer</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$buffer</span><span class="p">.</span><span class="n">Length</span><span class="p">,</span> <span class="p">[</span><span class="no">ref</span><span class="p">]</span><span class="nv">$bytesRead</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$text</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">UTF8</span><span class="p">.</span><span class="py">GetString</span><span class="p">(</span><span class="nv">$buffer</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="c"># 匹配广告视频URL模式</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$regex</span> <span class="p">=</span> <span class="s1">&#39;https?://[^\x00\s&#34;&lt;&gt;]{10,500}&#39;</span> <span class="p">+</span>
</span></span><span class="line"><span class="cl">                     <span class="s1">&#39;(?:\.mp4|mpvideo|finder.*video|wxv_|video\.qq|findermp)&#39;</span> <span class="p">+</span>
</span></span><span class="line"><span class="cl">                     <span class="s1">&#39;[^\x00\s&#34;&lt;&gt;]{0,200}&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="nv">$matches</span> <span class="p">=</span> <span class="p">[</span><span class="no">regex</span><span class="p">]::</span><span class="n">Matches</span><span class="p">(</span><span class="nv">$text</span><span class="p">,</span> <span class="nv">$regex</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">foreach</span> <span class="p">(</span><span class="nv">$m</span> <span class="k">in</span> <span class="nv">$matches</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="nv">$url</span> <span class="p">=</span> <span class="nv">$m</span><span class="p">.</span><span class="py">Value</span> <span class="o">-replace</span> <span class="s1">&#39;[\x00-\x1f]&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="p">(</span><span class="nv">$url</span><span class="p">.</span><span class="py">Length</span> <span class="o">-gt</span> <span class="mf">20</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="nb">Write-Host</span> <span class="nv">$url</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nv">$address</span> <span class="p">=</span> <span class="p">[</span><span class="no">IntPtr</span><span class="p">](</span>
</span></span><span class="line"><span class="cl">        <span class="nv">$mbi</span><span class="p">.</span><span class="py">BaseAddress</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="p">+</span> <span class="nv">$mbi</span><span class="p">.</span><span class="py">RegionSize</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nv">$address</span><span class="p">.</span><span class="py">ToInt64</span><span class="p">()</span> <span class="o">-lt</span> <span class="mf">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">break</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="no">MemoryReader</span><span class="p">]::</span><span class="n">CloseHandle</span><span class="p">(</span><span class="nv">$handle</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="第三步扫描结果">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%89%e6%ad%a5%e6%89%ab%e6%8f%8f%e7%bb%93%e6%9e%9c"></a>
第三步：扫描结果
</h3><p>扫描了 2357 个内存区域，找到了 <strong>115 个视频URL</strong>，去重后主要是以下几个广告视频（来自 <code>wxsmw.wxs.qq.com</code> 域名）：</p>
<pre tabindex="0"><code>http://wxsmw.wxs.qq.com/.../ads_svp_video__0bc3qyabeaaacyapvlro4zurvbqeckdaaesa.f142000.mp4?dis_k=...&amp;dis_t=1764683224&amp;...
http://wxsmw.wxs.qq.com/.../ads_svp_video__0b53xabuuaad6aap6xr4u5ubtoaejk4agssa.f142000.mp4?dis_k=...&amp;dis_t=1749005722&amp;...
http://wxsmw.wxs.qq.com/.../ads_svp_video__0b53qiaowaaapmaabparcrubvaqe5obab22a.f142000.mp4?dis_k=...&amp;dis_t=1746007401&amp;...
</code></pre><p>URL的规律：</p>
<ul>
<li>域名：<code>wxsmw.wxs.qq.com</code> 或 <code>wxsnsdy.wxs.qq.com</code>（腾讯视频CDN）</li>
<li>路径包含 <code>ads_svp_video</code> 标识这是广告视频</li>
<li>参数 <code>dis_t</code> 是时间戳，可以用来判断哪个是最近的广告</li>
<li>参数 <code>dis_k</code> 和 <code>sha256</code> 用于鉴权</li>
</ul>
<h3 id="第四步确认目标视频">
<a class="header-anchor" href="#%e7%ac%ac%e5%9b%9b%e6%ad%a5%e7%a1%ae%e8%ae%a4%e7%9b%ae%e6%a0%87%e8%a7%86%e9%a2%91"></a>
第四步：确认目标视频
</h3><p>有多个广告视频URL，需要确认哪个是&quot;三国冰河时代&quot;。用同样的内存扫描方法，搜索中文关键词&quot;三国&quot;（注意要同时搜索 UTF-8 和 UTF-16LE 两种编码，因为 Windows 进程内存中两种编码都可能存在）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># UTF-8 编码的&#34;三国&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$searchUtf8</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">UTF8</span><span class="p">.</span><span class="py">GetBytes</span><span class="p">(</span><span class="s1">&#39;三国&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="c"># UTF-16LE 编码的&#34;三国&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$searchUtf16</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">Unicode</span><span class="p">.</span><span class="py">GetBytes</span><span class="p">(</span><span class="s1">&#39;三国&#39;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在内存中确实找到了多处&quot;三国冰河时代&quot;的引用，包括：</p>
<ul>
<li>公众号文章元数据：<code>&quot;三国冰河时代挥师定山河活动解析&quot;</code></li>
<li>搜索记录：<code>&quot;query&quot;: &quot;三国 冰河时代&quot;</code></li>
<li>视频播放记录：<code>kVideoTracks...三国 冰河时代 - 搜一搜</code>，编码格式 <code>h264 high</code></li>
</ul>
<p>通过 <code>dis_t</code> 时间戳判断，最新的广告视频URL就是目标视频。</p>
<h3 id="第五步下载视频">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%94%e6%ad%a5%e4%b8%8b%e8%bd%bd%e8%a7%86%e9%a2%91"></a>
第五步：下载视频
</h3><p>直接用 curl 下载：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -o <span class="s2">&#34;三国冰河时代_广告视频.mp4&#34;</span> <span class="s2">&#34;http://wxsmw.wxs.qq.com/131/20210/snssvpdownload/SH/reserved/ads_svp_video__0bc3qyabeaaacyapvlro4zurvbqeckdaaesa.f142000.mp4?dis_k=...&amp;dis_t=...&amp;sha256=...&amp;m=...&amp;posid=...&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>返回 HTTP 200，文件大小约 7MB，<code>Content-Type: video/mp4</code>，下载成功。</p>
<h2 id="原理总结">
<a class="header-anchor" href="#%e5%8e%9f%e7%90%86%e6%80%bb%e7%bb%93"></a>
原理总结
</h2><pre tabindex="0"><code>微信公众号信息流
    ↓ 加载广告
腾讯CDN（wxsmw.wxs.qq.com）
    ↓ 流式传输视频
WeChatAppEx.exe 进程内存
    ↓ ReadProcessMemory
提取视频URL → curl下载
</code></pre><p>整个过程的关键点：</p>
<ol>
<li><strong>公众号信息流广告视频不缓存到本地磁盘</strong>，只在进程内存中存在</li>
<li>新版微信（xwechat）基于 Chromium 内核（RadiumWMPF），视频URL以明文形式保存在进程内存中</li>
<li>使用 Windows API <code>OpenProcess</code> + <code>VirtualQueryEx</code> + <code>ReadProcessMemory</code> 可以遍历读取目标进程的内存</li>
<li>广告视频URL的特征是域名为 <code>wxsmw.wxs.qq.com</code>，路径包含 <code>ads_svp_video</code></li>
<li>URL中的鉴权参数（<code>dis_k</code>、<code>sha256</code>、<code>m</code>）有时效性，需要在有效期内下载</li>
</ol>
<h2 id="注意事项">
<a class="header-anchor" href="#%e6%b3%a8%e6%84%8f%e4%ba%8b%e9%a1%b9"></a>
注意事项
</h2><ul>
<li>需要以当前用户权限运行，不需要管理员权限（因为微信也是当前用户启动的）</li>
<li>视频URL中的鉴权token有时效性，过期后需要重新扫描</li>
<li>扫描过程中微信需要保持运行，且目标广告页面需要已加载过</li>
<li>此方法同样适用于提取微信中其他流式加载的媒体内容的URL</li>
</ul>

        
        <hr><p>本文2026-03-15首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-15</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Python DrissionPage 绕过Cloudflare验证下载图片</title>
      <link>https://csdn.fjh1997.top/posts/24102.html</link>
      <pubDate>Mon, 09 Mar 2026 15:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/24102.html</guid>
      <description>
        <![CDATA[<h1>Python DrissionPage 绕过Cloudflare验证下载图片</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>有些网站（如 linux.do）的图片资源受 Cloudflare 保护，直接用 requests 请求会被拦截。本文介绍如何用 DrissionPage 控制真实浏览器通过验证，提取 cookie 后用 urllib 批量下载图片。</p>
<h2 id="思路">
<a class="header-anchor" href="#%e6%80%9d%e8%b7%af"></a>
思路
</h2><ol>
<li>用 DrissionPage 启动 Chromium 浏览器访问目标页面</li>
<li>等待 Cloudflare &ldquo;Just a moment&rdquo; 验证页面自动通过</li>
<li>通过 CDP 协议提取浏览器中的 cookie</li>
<li>用提取到的 cookie 构造请求头，用 urllib 下载图片</li>
</ol>
<h2 id="关键代码">
<a class="header-anchor" href="#%e5%85%b3%e9%94%ae%e4%bb%a3%e7%a0%81"></a>
关键代码
</h2><h3 id="1-配置浏览器选项">
<a class="header-anchor" href="#1-%e9%85%8d%e7%bd%ae%e6%b5%8f%e8%a7%88%e5%99%a8%e9%80%89%e9%a1%b9"></a>
1. 配置浏览器选项
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">DrissionPage</span> <span class="kn">import</span> <span class="n">Chromium</span><span class="p">,</span> <span class="n">ChromiumOptions</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">build_browser_options</span><span class="p">(</span><span class="n">proxy_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ChromiumOptions</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span> <span class="o">=</span> <span class="n">ChromiumOptions</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span><span class="o">.</span><span class="n">set_argument</span><span class="p">(</span><span class="s2">&#34;--no-first-run&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span><span class="o">.</span><span class="n">set_argument</span><span class="p">(</span><span class="s2">&#34;--disable-features=Translate&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">proxy_url</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">options</span><span class="o">.</span><span class="n">set_argument</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;--proxy-server=</span><span class="si">{</span><span class="n">proxy_url</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span><span class="o">.</span><span class="n">auto_port</span><span class="p">()</span>  <span class="c1"># 自动分配调试端口，避免冲突</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">options</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>auto_port()</code> 让每次启动使用不同端口，可以多实例并行。</p>
<h3 id="2-等待-cloudflare-验证通过">
<a class="header-anchor" href="#2-%e7%ad%89%e5%be%85-cloudflare-%e9%aa%8c%e8%af%81%e9%80%9a%e8%bf%87"></a>
2. 等待 Cloudflare 验证通过
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">PAGE_WAIT_SECONDS</span> <span class="o">=</span> <span class="mi">20</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">wait_for_page</span><span class="p">(</span><span class="n">tab</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">wait_rounds</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">PAGE_WAIT_SECONDS</span> <span class="o">//</span> <span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">wait_rounds</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">        <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">title</span> <span class="o">=</span> <span class="p">(</span><span class="n">tab</span><span class="o">.</span><span class="n">title</span> <span class="ow">or</span> <span class="s2">&#34;&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">lowered</span> <span class="o">=</span> <span class="n">title</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="c1"># Cloudflare 验证页的标题包含这些关键词</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">title</span> <span class="ow">and</span> <span class="s2">&#34;just a moment&#34;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lowered</span> <span class="ow">and</span> <span class="s2">&#34;checking your browser&#34;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lowered</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span>
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">pass</span>
</span></span><span class="line"><span class="cl">    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>原理很简单：Cloudflare 验证页的 <code>&lt;title&gt;</code> 通常是 &ldquo;Just a moment&hellip;&rdquo; 或 &ldquo;Checking your browser&hellip;&quot;，只要轮询到标题变成正常内容，就说明验证通过了。</p>
<h3 id="3-通过-cdp-提取-cookie">
<a class="header-anchor" href="#3-%e9%80%9a%e8%bf%87-cdp-%e6%8f%90%e5%8f%96-cookie"></a>
3. 通过 CDP 提取 Cookie
</h3><p>这是最核心的部分——用 Chrome DevTools Protocol 的 <code>Network.getAllCookies</code> 拿到浏览器里的所有 cookie：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">domain_matches</span><span class="p">(</span><span class="n">host</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">domain</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;判断 host 是否匹配 cookie 的 domain 字段&#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">normalized</span> <span class="o">=</span> <span class="n">domain</span><span class="o">.</span><span class="n">lstrip</span><span class="p">(</span><span class="s2">&#34;.&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">normalized</span><span class="p">)</span> <span class="ow">and</span> <span class="p">(</span><span class="n">host</span> <span class="o">==</span> <span class="n">normalized</span> <span class="ow">or</span> <span class="n">host</span><span class="o">.</span><span class="n">endswith</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;.</span><span class="si">{</span><span class="n">normalized</span><span class="si">}</span><span class="s2">&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">extract_cookie_header</span><span class="p">(</span><span class="n">browser</span><span class="p">:</span> <span class="n">Chromium</span><span class="p">,</span> <span class="n">tab</span><span class="p">,</span> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">cookies</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 方法1: 通过 CDP 协议获取所有 cookie（包括 HttpOnly 的）</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">cookies</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">tab</span><span class="o">.</span><span class="n">run_cdp</span><span class="p">(</span><span class="s2">&#34;Network.getAllCookies&#34;</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;cookies&#34;</span><span class="p">,</span> <span class="p">[]))</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 方法2: 通过 DrissionPage API 获取</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">cookies</span><span class="o">.</span><span class="n">extend</span><span class="p">(</span><span class="n">browser</span><span class="o">.</span><span class="n">cookies</span><span class="p">(</span><span class="n">all_info</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 去重，只保留目标域名的 cookie</span>
</span></span><span class="line"><span class="cl">    <span class="n">seen</span><span class="p">:</span> <span class="nb">set</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">set</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">host_cookies</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">dict</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">cookie</span> <span class="ow">in</span> <span class="n">cookies</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">domain</span> <span class="o">=</span> <span class="n">cookie</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;domain&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="ow">not</span> <span class="n">domain_matches</span><span class="p">(</span><span class="n">host</span><span class="p">,</span> <span class="n">domain</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">        <span class="n">key</span> <span class="o">=</span> <span class="p">(</span><span class="n">cookie</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;name&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">),</span> <span class="n">domain</span><span class="p">,</span> <span class="n">cookie</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;path&#34;</span><span class="p">,</span> <span class="s2">&#34;/&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">seen</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="k">continue</span>
</span></span><span class="line"><span class="cl">        <span class="n">seen</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">host_cookies</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">cookie</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1"># 拼接成 HTTP Cookie 头格式</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;; &#34;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">        <span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">cookie</span><span class="p">[</span><span class="s1">&#39;name&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">=</span><span class="si">{</span><span class="n">cookie</span><span class="p">[</span><span class="s1">&#39;value&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="n">cookie</span> <span class="ow">in</span> <span class="n">host_cookies</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">cookie</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;name&#34;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">cookie</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;value&#34;</span><span class="p">)</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>两种方式互补取 cookie：CDP 的 <code>Network.getAllCookies</code> 能拿到 <code>HttpOnly</code> 标记的 cookie（Cloudflare 的 <code>cf_clearance</code> 就是 HttpOnly 的），DrissionPage 自带的 API 作为兜底。</p>
<h3 id="4-收集会话信息完整流程">
<a class="header-anchor" href="#4-%e6%94%b6%e9%9b%86%e4%bc%9a%e8%af%9d%e4%bf%a1%e6%81%af%e5%ae%8c%e6%95%b4%e6%b5%81%e7%a8%8b"></a>
4. 收集会话信息（完整流程）
</h3><p>把上面的步骤串起来，打开浏览器 → 等验证 → 轮询提取 cookie → 验证 cookie 有效性：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">COOKIE_WAIT_SECONDS</span> <span class="o">=</span> <span class="mi">180</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">collect_site_session</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">site_url</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">proxy_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">validation_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl">    <span class="n">host</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">site_url</span><span class="p">)</span><span class="o">.</span><span class="n">hostname</span> <span class="ow">or</span> <span class="s2">&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">options</span> <span class="o">=</span> <span class="n">build_browser_options</span><span class="p">(</span><span class="n">proxy_url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">browser</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">browser</span> <span class="o">=</span> <span class="n">Chromium</span><span class="p">(</span><span class="n">options</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">tab</span> <span class="o">=</span> <span class="n">browser</span><span class="o">.</span><span class="n">latest_tab</span>
</span></span><span class="line"><span class="cl">        <span class="n">tab</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">site_url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">wait_for_page</span><span class="p">(</span><span class="n">tab</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">deadline</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">+</span> <span class="n">COOKIE_WAIT_SECONDS</span>
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">&lt;</span> <span class="n">deadline</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">cookie_header</span> <span class="o">=</span> <span class="n">extract_cookie_header</span><span class="p">(</span><span class="n">browser</span><span class="p">,</span> <span class="n">tab</span><span class="p">,</span> <span class="n">host</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="ow">not</span> <span class="n">cookie_header</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="c1"># 从浏览器获取真实 User-Agent</span>
</span></span><span class="line"><span class="cl">            <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">user_agent</span> <span class="o">=</span> <span class="n">tab</span><span class="o">.</span><span class="n">run_js</span><span class="p">(</span><span class="s2">&#34;return navigator.userAgent&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">user_agent</span> <span class="o">=</span> <span class="s2">&#34;Mozilla/5.0 ...&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="c1"># 如果提供了验证 URL，先试下载一张图验证 cookie 是否可用</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="n">validation_url</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">ok</span><span class="p">,</span> <span class="n">reason</span> <span class="o">=</span> <span class="n">probe_session</span><span class="p">(</span><span class="n">opener</span><span class="p">,</span> <span class="n">validation_url</span><span class="p">,</span> <span class="n">cookie_header</span><span class="p">,</span> <span class="n">user_agent</span><span class="p">,</span> <span class="n">site_url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="n">ok</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                    <span class="k">return</span> <span class="n">cookie_header</span><span class="p">,</span> <span class="n">user_agent</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">return</span> <span class="n">cookie_header</span><span class="p">,</span> <span class="n">user_agent</span>
</span></span><span class="line"><span class="cl">    <span class="k">finally</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="n">browser</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">browser</span><span class="o">.</span><span class="n">quit</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="s2">&#34;&#34;</span><span class="p">,</span> <span class="s2">&#34;Mozilla/5.0 ...&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>关键点：</p>
<ul>
<li>设 180 秒超时，留足人工点击验证码的时间</li>
<li>每 3 秒轮询一次 cookie，拿到后立即用 <code>probe_session</code> 试下载一张图片验证 cookie 是否有效</li>
<li>用 <code>tab.run_js(&quot;return navigator.userAgent&quot;)</code> 获取浏览器真实 UA，保证后续请求的 UA 和获取 cookie 时一致</li>
</ul>
<h3 id="5-带-cookie-下载图片">
<a class="header-anchor" href="#5-%e5%b8%a6-cookie-%e4%b8%8b%e8%bd%bd%e5%9b%be%e7%89%87"></a>
5. 带 Cookie 下载图片
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">ssl</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">urllib.request</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">build_opener</span><span class="p">(</span><span class="n">proxy_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">OpenerDirector</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">ssl_context</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">create_default_context</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">ssl_context</span><span class="o">.</span><span class="n">check_hostname</span> <span class="o">=</span> <span class="kc">False</span>
</span></span><span class="line"><span class="cl">    <span class="n">ssl_context</span><span class="o">.</span><span class="n">verify_mode</span> <span class="o">=</span> <span class="n">ssl</span><span class="o">.</span><span class="n">CERT_NONE</span>  <span class="c1"># 跳过 SSL 验证</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">handlers</span> <span class="o">=</span> <span class="p">[</span><span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">HTTPSHandler</span><span class="p">(</span><span class="n">context</span><span class="o">=</span><span class="n">ssl_context</span><span class="p">)]</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="n">proxy_url</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">handlers</span><span class="o">.</span><span class="n">insert</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">ProxyHandler</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;http&#34;</span><span class="p">:</span> <span class="n">proxy_url</span><span class="p">,</span> <span class="s2">&#34;https&#34;</span><span class="p">:</span> <span class="n">proxy_url</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="p">}))</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">build_opener</span><span class="p">(</span><span class="o">*</span><span class="n">handlers</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">download_image</span><span class="p">(</span><span class="n">opener</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">output_path</span><span class="p">,</span> <span class="n">cookie_header</span><span class="p">,</span> <span class="n">user_agent</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">request</span> <span class="o">=</span> <span class="n">urllib</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">request</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="s2">&#34;User-Agent&#34;</span><span class="p">,</span> <span class="n">user_agent</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">request</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="s2">&#34;Accept&#34;</span><span class="p">,</span> <span class="s2">&#34;image/webp,image/apng,image/*,*/*;q=0.8&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">request</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="s2">&#34;Referer&#34;</span><span class="p">,</span> <span class="sa">f</span><span class="s2">&#34;</span><span class="si">{</span><span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">scheme</span><span class="si">}</span><span class="s2">://</span><span class="si">{</span><span class="n">urllib</span><span class="o">.</span><span class="n">parse</span><span class="o">.</span><span class="n">urlparse</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">netloc</span><span class="si">}</span><span class="s2">/&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">request</span><span class="o">.</span><span class="n">add_header</span><span class="p">(</span><span class="s2">&#34;Cookie&#34;</span><span class="p">,</span> <span class="n">cookie_header</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="n">opener</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="mi">30</span><span class="p">)</span> <span class="k">as</span> <span class="n">response</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">data</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">read</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">        <span class="n">content_type</span> <span class="o">=</span> <span class="n">response</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&#34;Content-Type&#34;</span><span class="p">,</span> <span class="s2">&#34;&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="ow">not</span> <span class="n">data</span> <span class="ow">or</span> <span class="s2">&#34;text/html&#34;</span> <span class="ow">in</span> <span class="n">content_type</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span>
</span></span><span class="line"><span class="cl">        <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="sa">f</span><span class="s2">&#34;下载失败, content-type=</span><span class="si">{</span><span class="n">content_type</span><span class="si">!r}</span><span class="s2">&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">output_path</span><span class="o">.</span><span class="n">write_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">True</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意设置 <code>Referer</code> 头，有些 CDN 会校验来源。下载后检查 <code>Content-Type</code>，如果返回的是 HTML 而不是图片，说明 cookie 已失效或被拦截了。</p>
<h2 id="安装依赖">
<a class="header-anchor" href="#%e5%ae%89%e8%a3%85%e4%be%9d%e8%b5%96"></a>
安装依赖
</h2><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">pip install DrissionPage
</span></span></code></pre></td></tr></table>
</div>
</div><p>DrissionPage 会自动查找系统中已安装的 Chromium 内核浏览器（Chrome、Edge 等），无需额外安装 chromedriver。</p>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>整个方案的核心就一句话：<strong>用真实浏览器过 Cloudflare 验证，通过 CDP 协议偷 cookie，再把 cookie 塞到 urllib 请求里下载资源</strong>。相比 undetected-chromedriver 等方案，DrissionPage 的优势是 API 简洁，且内置了 CDP 操作支持。</p>

        
        <hr><p>本文2026-03-09首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-09</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>0元领养专属&#34;小龙虾&#34;OpenClaw，2核16GB配置/无痛部署/开箱即用并配置内网穿透接入飞书</title>
      <link>https://csdn.fjh1997.top/posts/33854.html</link>
      <pubDate>Mon, 09 Mar 2026 00:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/33854.html</guid>
      <description>
        <![CDATA[<h1>0元领养专属"小龙虾"OpenClaw，2核16GB配置/无痛部署/开箱即用并配置内网穿透接入飞书</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>参考来源：<a href="https://linux.do/t/topic/1702573" target="_blank" rel="noopener noreferrer nofollow">https://linux.do/t/topic/1702573</a>
</p>
<h2 id="1-打开-modelscope-官网登录账户">
<a class="header-anchor" href="#1-%e6%89%93%e5%bc%80-modelscope-%e5%ae%98%e7%bd%91%e7%99%bb%e5%bd%95%e8%b4%a6%e6%88%b7"></a>
1. 打开 ModelScope 官网，登录账户
</h2><p>官网地址：<a href="https://www.modelscope.cn/home" target="_blank" rel="noopener noreferrer nofollow">https://www.modelscope.cn/home</a>
</p>
<p><img src="/images/openclaw-01.webp" alt="1"></p>
<h2 id="2-授权绑定阿里云账号完成实名认证">
<a class="header-anchor" href="#2-%e6%8e%88%e6%9d%83%e7%bb%91%e5%ae%9a%e9%98%bf%e9%87%8c%e4%ba%91%e8%b4%a6%e5%8f%b7%e5%ae%8c%e6%88%90%e5%ae%9e%e5%90%8d%e8%ae%a4%e8%af%81"></a>
2. 授权绑定阿里云账号，完成实名认证
</h2><p><img src="/images/openclaw-02.webp" alt="2"></p>
<p><img src="/images/openclaw-03.webp" alt="3"></p>
<p><img src="/images/openclaw-04.webp" alt="4"></p>
<p><img src="/images/openclaw-05.webp" alt="5"></p>
<p><img src="/images/openclaw-06.webp" alt="6"></p>
<h2 id="3-获取-modelscope-访问令牌">
<a class="header-anchor" href="#3-%e8%8e%b7%e5%8f%96-modelscope-%e8%ae%bf%e9%97%ae%e4%bb%a4%e7%89%8c"></a>
3. 获取 ModelScope 访问令牌
</h2><p>回到 ModelScope 网站，点击右上角头像，选择&quot;账号设置&quot;，然后点击左侧的&quot;访问控制&quot;，最后点击&quot;新建访问令牌&quot;并复制此令牌。</p>
<p><img src="/images/openclaw-07.webp" alt="7"></p>
<p><img src="/images/openclaw-08.webp" alt="8"></p>
<p><img src="/images/openclaw-09.webp" alt="9"></p>
<h2 id="4-搜索-openclaw-创空间">
<a class="header-anchor" href="#4-%e6%90%9c%e7%b4%a2-openclaw-%e5%88%9b%e7%a9%ba%e9%97%b4"></a>
4. 搜索 OpenClaw 创空间
</h2><p>在网站右上角搜索框输入 <code>BrianZhou/openclaw_computer</code>，按回车键确认，随后点击搜索结果中展示的创空间。</p>
<p><img src="/images/openclaw-10.webp" alt="10"></p>
<p><img src="/images/openclaw-11.webp" alt="11"></p>
<h2 id="5-复制空间并设置参数">
<a class="header-anchor" href="#5-%e5%a4%8d%e5%88%b6%e7%a9%ba%e9%97%b4%e5%b9%b6%e8%ae%be%e7%bd%ae%e5%8f%82%e6%95%b0"></a>
5. 复制空间并设置参数
</h2><p>复制该空间，并设置相关参数：</p>
<ul>
<li>
<p><strong>是否公开</strong>：选择&quot;非公开&quot;</p>
</li>
<li>
<p><strong>ROOT_PASSWD</strong>：你可以设置任意值，这是云电脑的密码，电脑待机锁屏时需要该密码解锁，请勿忘记</p>
</li>
<li>
<p><strong>MODELSCOPE_API_KEY</strong>：粘贴你刚刚复制的令牌（即本教程第 3 步操作里复制的令牌）</p>
</li>
</ul>
<p>最后点击&quot;复制创空间&quot;。</p>
<p><img src="/images/openclaw-12.webp" alt="12"></p>
<p><img src="/images/openclaw-13.webp" alt="13"></p>
<p><img src="/images/openclaw-14.webp" alt="14"></p>
<h2 id="6-等待云电脑部署完成">
<a class="header-anchor" href="#6-%e7%ad%89%e5%be%85%e4%ba%91%e7%94%b5%e8%84%91%e9%83%a8%e7%bd%b2%e5%ae%8c%e6%88%90"></a>
6. 等待云电脑部署完成
</h2><p><img src="/images/openclaw-15.webp" alt="15"></p>
<h2 id="7-进入全屏模式部署完成">
<a class="header-anchor" href="#7-%e8%bf%9b%e5%85%a5%e5%85%a8%e5%b1%8f%e6%a8%a1%e5%bc%8f%e9%83%a8%e7%bd%b2%e5%ae%8c%e6%88%90"></a>
7. 进入全屏模式，部署完成
</h2><p>云电脑部署上线后，按照下图操作进入全屏模式。至此，部署完成。</p>
<p><img src="/images/openclaw-16.webp" alt="16"></p>
<p><img src="/images/openclaw-17.webp" alt="17"></p>
<hr>
<p>接下来需要注册内网穿透服务</p>
<h2 id="8配置ssh服务">
<a class="header-anchor" href="#8%e9%85%8d%e7%bd%aessh%e6%9c%8d%e5%8a%a1"></a>
8.配置ssh服务
</h2><p><img src="/images/2026-03-12-15-21-21.png" alt="2026-03-12-15-21-21"></p>
<p>在终端中输入以下命令开启ssh服务：</p>
<pre tabindex="0"><code>service ssh start
</code></pre><p><img src="/images/2026-03-12-15-35-33.png" alt="2026-03-12-15-35-33"></p>
<p>同样方法输入下列命令配置ssh自启动服务:</p>
<pre tabindex="0"><code>echo &#34;service ssh start&#34; &gt;&gt; /root/bz-startup/main.sh
</code></pre><h2 id="选项一9使用ngrok进行穿透">
<a class="header-anchor" href="#%e9%80%89%e9%a1%b9%e4%b8%809%e4%bd%bf%e7%94%a8ngrok%e8%bf%9b%e8%a1%8c%e7%a9%bf%e9%80%8f"></a>
（选项一）9.使用ngrok进行穿透
</h2><p>先去<a href="https://dashboard.ngrok.com/signup" target="_blank" rel="noopener noreferrer nofollow">ngrok - Online in One Line注册账户，使用github进行登录</a>
</p>
<p>如果github上不去，可以使用watts tool进行加速：
<img src="/images/2026-03-12-15-28-04.png" alt="2026-03-12-15-28-04">
<img src="/images/2026-03-12-15-32-37.png" alt="2026-03-12-15-32-37"></p>
<p><img src="/images/QQ_1773127611000.png" alt=""></p>
<p>如果没有github账号，可以注册一个</p>
<p><img src="/images/2.png" alt=""></p>
<p><img src="/images/3.png" alt=""></p>
<p>注册好后用github账号登录grok</p>
<p><img src="/images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-10%20153708.png" alt=""></p>
<p>会提示你启用2fa，如果你想启用，可以下一个微软的authencitator绑定，如不需要可以跳过</p>
<p><img src="/images/QQ_1773133104523.png" alt=""></p>
<p><img src="/images/auth.jpg" alt=""></p>
<p>登录之后看到自己的token，把它复制下来</p>
<p><img src="/images/QQ_1773128320722.png" alt=""></p>
<p>之后把token粘贴进剪切板，并让小龙虾帮你配置内网穿透</p>
<p><img src="/images/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-03-10%20154533.png" alt=""></p>
<p><img src="/images/QQ_1773128939192.png" alt=""></p>
<p>之后使用windterm进行连接</p>
<p><img src="/images/999.png" alt=""></p>
<h2 id="选项二9-使用-sakura-frp-进行穿透">
<a class="header-anchor" href="#%e9%80%89%e9%a1%b9%e4%ba%8c9-%e4%bd%bf%e7%94%a8-sakura-frp-%e8%bf%9b%e8%a1%8c%e7%a9%bf%e9%80%8f"></a>
（选项二）9. 使用 Sakura Frp 进行穿透
</h2><p>先去 sakurafrp 官网 <a href="https://www.natfrp.com/user/" target="_blank" rel="noopener noreferrer nofollow">https://www.natfrp.com/user/</a>
 注册用户：</p>
<p><img src="/images/openclaw-image-2.png" alt="alt text"></p>
<p>再进行实名认证，需要1元。 <img src="/images/openclaw-image-13.png" alt="alt text"></p>
<p><img src="/images/openclaw-image-14.png" alt="alt text"></p>
<p>认证成功之后，在云电脑中先在剪切板里面粘贴命令，之后打开终端粘贴后后回车，</p>
<p>输入：</p>
<pre tabindex="0"><code>wget https://cdn.jsdelivr.net/gh/fjh1997/CTF-@main/sakura_frp.sh &amp;&amp; bash sakura_frp.sh
</code></pre><p><img src="/images/2026-03-12-15-38-50.png" alt="2026-03-12-15-38-50">
执行一段时间后会提示你输入密钥，先不动，如果卡住了，使用ctrl+c中断命令，然后按方向键上键重试即可：
<img src="/images/2026-03-12-15-44-02.png" alt="2026-03-12-15-44-02"></p>
<p><img src="/images/openclaw-image-6.png" alt="alt text"></p>
<p>之后复制访问密钥，在剪切板里面粘贴，之后再复制到终端里面：<img src="/images/2026-03-12-15-47-47.png" alt="2026-03-12-15-47-47"></p>
<p>复制完访问密钥之后，设置远程管理密码，可以看到安装成功的界面：</p>
<p><img src="/images/openclaw-image-8.png" alt="alt text"></p>
<p>输入`bash /mnt/workspace/sakura_frp/<a href="http://start.sh" target="_blank" rel="noopener noreferrer nofollow">start.sh</a>
`启动穿透。</p>
<p>以后设备重启后需要输入<code>bash /mnt/workspace/sakura_frp/start.sh</code>启动穿透。<br>
之后点击服务-隧道列表：<br>
<img src="/images/openclaw-image-9.png" alt="alt text"><br>
随便选一个，可以选浙江移动<br>
<img src="/images/openclaw-image-10.png" alt="alt text"><br>
隧道类型选tcp<br>
<img src="/images/openclaw-image-11.png" alt="alt text"><br>
选22端口：<br>
<img src="/images/openclaw-image-12.png" alt="alt text"><br>
创建成功之后去远程管理页面：<br>
<img src="/images/openclaw-image-15.png" alt="alt text"><br>
如果没显示出来多按几下刷新，或者重启服务<br>
<img src="/images/openclaw-image-16.png" alt="alt text"><br>
<img src="/images/openclaw-image-17.png" alt="alt text"></p>
<p>输入连接密码并连接： <img src="/images/openclaw-image-18.png" alt="alt text"><br>
把创建好的隧道拖到加号上<br>
<img src="/images/openclaw-image-19.png" alt="alt text"><br>
成功后会显示连接信息：</p>
<p><img src="/images/openclaw-image-20.png" alt="alt text"><br>
也可以去日志里查看连接地址：
<img src="/images/2026-03-12-16-19-41.png" alt="2026-03-12-16-19-41">
之后使用windterm进行连接，使用用户名root和密码即可：</p>
<p><img src="/images/2026-03-12-16-21-21.png" alt="2026-03-12-16-21-21">
<img src="/images/2026-03-12-16-22-09.png" alt="2026-03-12-16-22-09">
<img src="/images/openclaw-image-22.png" alt="alt text"></p>
<h2 id="10上传代码包让小龙虾自动审计">
<a class="header-anchor" href="#10%e4%b8%8a%e4%bc%a0%e4%bb%a3%e7%a0%81%e5%8c%85%e8%ae%a9%e5%b0%8f%e9%be%99%e8%99%be%e8%87%aa%e5%8a%a8%e5%ae%a1%e8%ae%a1"></a>
10.上传代码包让小龙虾自动审计
</h2><p><img src="/images/openclaw-image-23.png" alt="alt text"><br>
之后上传你需要审计的代码包，如unserialize.zip,拖到左下角小框里： <img src="/images/openclaw-image-24.png" alt="alt text"></p>
<p>之后你和openclaw说话他就会自动帮你审计： <img src="/images/openclaw-image-25.png" alt="alt text"></p>
<h2 id="11接入飞书">
<a class="header-anchor" href="#11%e6%8e%a5%e5%85%a5%e9%a3%9e%e4%b9%a6"></a>
11.接入飞书
</h2><p>先和openclaw说:</p>
<pre tabindex="0"><code>帮我安装飞书插件npx -y @larksuite/openclaw-lark-tools install
</code></pre><p><img src="/images/2026-03-12-18-15-45.png" alt="2026-03-12-18-15-45">
等openclaw处理好之后在终端里面再次输入：</p>
<pre tabindex="0"><code>npx -y @larksuite/openclaw-lark-tools install
</code></pre><p>之后下载飞书app扫码：<br>
<img src="/images/2026-03-12-18-11-06.png" alt="2026-03-12-18-11-06">
即可连接机器人</p>

        
        <hr><p>本文2026-03-09首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-09</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Fenvi AX1800 MT7921AU 在monitor mode下 监听不到beacon管理帧BUG修复</title>
      <link>https://csdn.fjh1997.top/posts/20260308.html</link>
      <pubDate>Sun, 08 Mar 2026 22:00:00 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/20260308.html</guid>
      <description>
        <![CDATA[<h1>Fenvi AX1800 MT7921AU 在monitor mode下 监听不到beacon管理帧BUG修复</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h2 id="起因">
<a class="header-anchor" href="#%e8%b5%b7%e5%9b%a0"></a>
起因
</h2><p>我有一个 Fenvi AX1800 USB 无线网卡（芯片 MediaTek MT7921AU，驱动 mt76），平时用来做无线安全研究。某天升级内核后发现，网卡在监控模式下抓不到管理帧了。</p>
<p>具体表现是：当无线网卡同时存在 managed 接口和 monitor 接口时（即并存模式），monitor 接口完全抓不到任何帧。而在内核 6.12 及以前，这一切都是正常的。</p>
<p>在 GitHub 上搜索发现已经有人报告了同样的问题：<a href="https://github.com/morrownr/USB-WiFi/issues/682" target="_blank" rel="noopener noreferrer nofollow">USB-WiFi#682</a>
，但一直没有修复。于是决定自己动手调试。</p>
<h2 id="环境搭建">
<a class="header-anchor" href="#%e7%8e%af%e5%a2%83%e6%90%ad%e5%bb%ba"></a>
环境搭建
</h2><p>我的调试环境是：</p>
<ul>
<li><strong>宿主机</strong>：Windows + VMware Workstation</li>
<li><strong>虚拟机</strong>：Ubuntu 24.04 LTS（默认内核 6.8）</li>
<li><strong>无线网卡</strong>：Fenvi AX1800（MT7921AU），通过 USB 穿透到虚拟机</li>
<li><strong>内核版本</strong>：通过 Ubuntu Mainline Kernel 安装多个版本进行对比测试</li>
</ul>
<p>选择 Ubuntu 的原因是 <a href="https://kernel.ubuntu.com/mainline/" target="_blank" rel="noopener noreferrer nofollow">Ubuntu Mainline Kernel Archive</a>
 提供了预编译的 <code>.deb</code> 内核包，可以非常方便地安装任意版本的内核来测试，不需要自己从头编译整个内核。</p>
<p>安装方法很简单，以 6.13 为例：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> /tmp
</span></span><span class="line"><span class="cl">wget https://kernel.ubuntu.com/mainline/v6.13/amd64/linux-headers-6.13.0-061300-generic_6.13.0-061300.202501192034_amd64.deb
</span></span><span class="line"><span class="cl">wget https://kernel.ubuntu.com/mainline/v6.13/amd64/linux-headers-6.13.0-061300_6.13.0-061300.202501192034_all.deb
</span></span><span class="line"><span class="cl">wget https://kernel.ubuntu.com/mainline/v6.13/amd64/linux-image-unsigned-6.13.0-061300-generic_6.13.0-061300.202501192034_amd64.deb
</span></span><span class="line"><span class="cl">wget https://kernel.ubuntu.com/mainline/v6.13/amd64/linux-modules-6.13.0-061300-generic_6.13.0-061300.202501192034_amd64.deb
</span></span><span class="line"><span class="cl">sudo dpkg -i *.deb
</span></span><span class="line"><span class="cl">sudo reboot
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="基线测试确认-bug-存在">
<a class="header-anchor" href="#%e5%9f%ba%e7%ba%bf%e6%b5%8b%e8%af%95%e7%a1%ae%e8%ae%a4-bug-%e5%ad%98%e5%9c%a8"></a>
基线测试：确认 Bug 存在
</h2><p>先在默认的 6.8 内核上确认网卡功能正常。</p>
<h3 id="测试方法">
<a class="header-anchor" href="#%e6%b5%8b%e8%af%95%e6%96%b9%e6%b3%95"></a>
测试方法
</h3><p>两种场景分别测试：</p>
<p><strong>场景一：纯 Monitor 模式</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> wlx18d6c70a4715 down
</span></span><span class="line"><span class="cl">sudo iw dev wlx18d6c70a4715 <span class="nb">set</span> <span class="nb">type</span> monitor
</span></span><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> wlx18d6c70a4715 up
</span></span><span class="line"><span class="cl">sudo timeout <span class="m">5</span> tcpdump -i wlx18d6c70a4715 -c <span class="m">50</span> <span class="s1">&#39;type mgt&#39;</span> -n
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>场景二：Managed + Monitor 并存</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> wlx18d6c70a4715 up  <span class="c1"># managed 模式</span>
</span></span><span class="line"><span class="cl">sudo iw dev wlx18d6c70a4715 interface add mon0 <span class="nb">type</span> monitor
</span></span><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> mon0 up
</span></span><span class="line"><span class="cl">sudo timeout <span class="m">5</span> tcpdump -i mon0 -c <span class="m">50</span> <span class="s1">&#39;type mgt&#39;</span> -n
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="68-基线结果">
<a class="header-anchor" href="#68-%e5%9f%ba%e7%ba%bf%e7%bb%93%e6%9e%9c"></a>
6.8 基线结果
</h3><table>
  <thead>
      <tr>
          <th>场景</th>
          <th>结果</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>纯 Monitor</td>
          <td>✅ 正常抓到管理帧</td>
      </tr>
      <tr>
          <td>Managed + Monitor</td>
          <td>✅ 正常抓到管理帧</td>
      </tr>
  </tbody>
</table>
<p>一切正常。然后切换到 6.13 内核。</p>
<h3 id="613-测试结果">
<a class="header-anchor" href="#613-%e6%b5%8b%e8%af%95%e7%bb%93%e6%9e%9c"></a>
6.13 测试结果
</h3><table>
  <thead>
      <tr>
          <th>场景</th>
          <th>结果</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>纯 Monitor</td>
          <td>✅ 正常</td>
      </tr>
      <tr>
          <td>Managed + Monitor</td>
          <td>❌ 0 帧</td>
      </tr>
  </tbody>
</table>
<p>Bug 确认。并存模式下完全抓不到帧。</p>
<h2 id="定位根因">
<a class="header-anchor" href="#%e5%ae%9a%e4%bd%8d%e6%a0%b9%e5%9b%a0"></a>
定位根因
</h2><h3 id="快速编译策略">
<a class="header-anchor" href="#%e5%bf%ab%e9%80%9f%e7%bc%96%e8%af%91%e7%ad%96%e7%95%a5"></a>
快速编译策略
</h3><p>调试内核 bug 最头疼的就是编译时间。完整编译一个内核可能需要几十分钟甚至几个小时。但实际上我们只需要修改 <code>mac80211</code> 模块，所以可以只编译这一个模块：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> /root/kernel/linux-6.13
</span></span><span class="line"><span class="cl">cp /boot/config-<span class="k">$(</span>uname -r<span class="k">)</span> .config
</span></span><span class="line"><span class="cl">make olddefconfig
</span></span><span class="line"><span class="cl">make modules_prepare
</span></span><span class="line"><span class="cl">cp /lib/modules/<span class="k">$(</span>uname -r<span class="k">)</span>/build/Module.symvers .
</span></span><span class="line"><span class="cl">make <span class="nv">M</span><span class="o">=</span>net/mac80211 modules  <span class="c1"># 只编译 mac80211，大约 30 秒</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后热替换模块，不需要重启：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ip link <span class="nb">set</span> wlx18d6c70a4715 down
</span></span><span class="line"><span class="cl">sudo rmmod mt7921u mt7921_common mt792x_lib mt76_connac_lib mt76_usb mt76 mac80211
</span></span><span class="line"><span class="cl">sudo insmod net/mac80211/mac80211.ko
</span></span><span class="line"><span class="cl">sudo modprobe mt7921u
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样每次修改代码到测试验证的周期只需要不到一分钟。</p>
<h3 id="分析代码变更">
<a class="header-anchor" href="#%e5%88%86%e6%9e%90%e4%bb%a3%e7%a0%81%e5%8f%98%e6%9b%b4"></a>
分析代码变更
</h3><p>问题出在 <code>net/mac80211/tx.c</code> 的 <code>ieee80211_monitor_start_xmit()</code> 函数。这是监控模式下发送（注入）帧的入口。</p>
<p>通过 <code>git log</code> 追踪，找到了引入回归的 commit：</p>
<blockquote>
<p><code>0a44dfc07074</code> (&ldquo;wifi: mac80211: simplify non-chanctx drivers&rdquo;)</p>
</blockquote>
<p>这个 commit 在&quot;简化&quot;代码时，删除了一个关键的 fallback 路径。修改前的逻辑（简化表示）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">chanctx_conf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">chanctx_conf</span><span class="o">-&gt;</span><span class="n">def</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">_oper_chandef</span><span class="p">;</span>  <span class="c1">// fallback
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>修改后：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">chanctx_conf</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">chanctx_conf</span><span class="o">-&gt;</span><span class="n">def</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span> <span class="nf">if</span> <span class="p">(</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">emulate_chanctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">hw</span><span class="p">.</span><span class="n">conf</span><span class="p">.</span><span class="n">chandef</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">    <span class="k">goto</span> <span class="n">fail_rcu</span><span class="p">;</span>  <span class="c1">// 直接失败！
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>问题在于：对于使用&quot;真正的&quot;channel context 的驱动（如 mt76），当 monitor 接口和 managed 接口并存时，monitor 的虚拟接口（sdata）并不会被分配自己的 chanctx，即使系统中存在一个来自 managed 接口的活跃 chanctx。</p>
<p>之前的代码会 fallback 到 <code>local-&gt;_oper_chandef</code>，所以能正常工作。新代码直接 <code>goto fail_rcu</code>，静默丢弃了所有帧。</p>
<p>后来的 commit <code>d594cc6f2c58</code> (&ldquo;wifi: mac80211: restore non-chanctx injection behaviour&rdquo;) 修复了使用 <code>emulate_chanctx</code> 的驱动，但<strong>明确留下了真正 chanctx 驱动未修复</strong>。</p>
<h3 id="修复方案">
<a class="header-anchor" href="#%e4%bf%ae%e5%a4%8d%e6%96%b9%e6%a1%88"></a>
修复方案
</h3><p>修复思路很直接：当 monitor 接口没有 chanctx 时，从 <code>local-&gt;chanctx_list</code> 中取第一个可用的 chanctx 作为 fallback。这个模式在 <code>ieee80211_hw_conf_chan()</code> 中已经被使用过了，是安全的。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="n">chanctx_conf</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">chanctx_conf</span><span class="o">-&gt;</span><span class="n">def</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">emulate_chanctx</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">hw</span><span class="p">.</span><span class="n">conf</span><span class="p">.</span><span class="n">chandef</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="cm">/*
</span></span></span><span class="line"><span class="cl"><span class="cm">     * For real chanctx drivers (e.g. mt76), the monitor
</span></span></span><span class="line"><span class="cl"><span class="cm">     * interface may not have a chanctx assigned when running
</span></span></span><span class="line"><span class="cl"><span class="cm">     * concurrently with another interface. Fall back to any
</span></span></span><span class="line"><span class="cl"><span class="cm">     * active chanctx so that injection can still work on the
</span></span></span><span class="line"><span class="cl"><span class="cm">     * operating channel.
</span></span></span><span class="line"><span class="cl"><span class="cm">     */</span>
</span></span><span class="line"><span class="cl">    <span class="k">struct</span> <span class="n">ieee80211_chanctx</span> <span class="o">*</span><span class="n">ctx</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">ctx</span> <span class="o">=</span> <span class="nf">list_first_entry_or_null</span><span class="p">(</span><span class="o">&amp;</span><span class="n">local</span><span class="o">-&gt;</span><span class="n">chanctx_list</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                   <span class="k">struct</span> <span class="n">ieee80211_chanctx</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                                   <span class="n">list</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">ctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">chandef</span> <span class="o">=</span> <span class="o">&amp;</span><span class="n">ctx</span><span class="o">-&gt;</span><span class="n">conf</span><span class="p">.</span><span class="n">def</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="k">goto</span> <span class="n">fail_rcu</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="跨版本验证">
<a class="header-anchor" href="#%e8%b7%a8%e7%89%88%e6%9c%ac%e9%aa%8c%e8%af%81"></a>
跨版本验证
</h2><p>仅修复一个版本是不够的。我需要确认这个补丁能修复所有受影响的版本。</p>
<h3 id="源码级分析">
<a class="header-anchor" href="#%e6%ba%90%e7%a0%81%e7%ba%a7%e5%88%86%e6%9e%90"></a>
源码级分析
</h3><p>为了避免在每个版本上都走一遍完整的&quot;安装内核→重启→编译→测试&quot;流程，我先从 kernel.org 下载了各版本的 <code>tx.c</code> 源码进行对比分析：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 下载各版本的 tx.c 进行对比</span>
</span></span><span class="line"><span class="cl"><span class="k">for</span> ver in 6.13 6.14 6.15 6.16 6.17 6.18 6.19<span class="p">;</span> <span class="k">do</span>
</span></span><span class="line"><span class="cl">    curl -o tx_<span class="si">${</span><span class="nv">ver</span><span class="si">}</span>.c <span class="s2">&#34;https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/plain/net/mac80211/tx.c?h=v</span><span class="si">${</span><span class="nv">ver</span><span class="si">}</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="cl"><span class="k">done</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>分析发现：</p>
<ul>
<li><strong>6.13–6.18</strong>：没有 <code>emulate_chanctx</code> 分支，直接 <code>if/else goto fail_rcu</code></li>
<li><strong>6.19+</strong>：有 <code>emulate_chanctx</code> 分支（来自 <code>d594cc6f2c58</code>），但 else 仍然 <code>goto fail_rcu</code></li>
</ul>
<p>两种变体都需要同样的修复，只是上下文略有不同。我的补丁基于 6.19+ 的代码编写，通过 <code>Fixes:</code> 标签和 <code>Cc: stable@vger.kernel.org</code> 来触发自动回溯。</p>
<h3 id="发现第二个-bug">
<a class="header-anchor" href="#%e5%8f%91%e7%8e%b0%e7%ac%ac%e4%ba%8c%e4%b8%aa-bug"></a>
发现第二个 Bug
</h3><p>在 6.18 内核上测试时，发现了一个意外情况：<strong>即使是纯 Monitor 模式也抓不到帧</strong>。这跟 6.13 的表现不同（6.13 纯 Monitor 是正常的）。</p>
<p>经过排查，发现 6.17–6.18 的 mt76 驱动中多了一行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// drivers/net/wireless/mediatek/mt76/mt792x_core.c
</span></span></span><span class="line"><span class="cl"><span class="nf">ieee80211_hw_set</span><span class="p">(</span><span class="n">hw</span><span class="p">,</span> <span class="n">NO_VIRTUAL_MONITOR</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这个标志告诉 mac80211 不要创建虚拟 monitor 接口，导致整个监控模式都不工作。这个标志在 6.19 中被 revert 了。</p>
<p>所以实际上有<strong>两个独立的 Bug</strong>：</p>
<pre class="mermaid">
  graph TD
    A[6.12 及之前: 一切正常] --> B[6.13: tx.c chanctx fallback 被删除]
    B --> C[6.13-6.16: 纯 Monitor ✅ / 并存 ❌]
    B --> D[6.17-6.18: 额外添加 NO_VIRTUAL_MONITOR]
    D --> E[6.17-6.18: 纯 Monitor ❌ / 并存 ❌]
    D --> F[6.19: NO_VIRTUAL_MONITOR 被 revert]
    F --> G[6.19+: 纯 Monitor ✅ / 并存 ❌]
</pre><h3 id="完整测试结果">
<a class="header-anchor" href="#%e5%ae%8c%e6%95%b4%e6%b5%8b%e8%af%95%e7%bb%93%e6%9e%9c"></a>
完整测试结果
</h3><p>在代表性版本上进行了实际测试：</p>
<p><strong>补丁前：</strong></p>
<table>
  <thead>
      <tr>
          <th>内核版本</th>
          <th>纯 Monitor</th>
          <th>Managed + Monitor</th>
          <th>原因</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>6.8</td>
          <td>✅ 正常</td>
          <td>✅ 正常</td>
          <td>基线</td>
      </tr>
      <tr>
          <td>6.13</td>
          <td>✅ 正常</td>
          <td>❌ 0 帧</td>
          <td>Bug 1</td>
      </tr>
      <tr>
          <td>6.17</td>
          <td>❌ 0 帧</td>
          <td>❌ 0 帧</td>
          <td>Bug 1 + Bug 2</td>
      </tr>
      <tr>
          <td>6.18</td>
          <td>❌ 0 帧</td>
          <td>❌ 0 帧</td>
          <td>Bug 1 + Bug 2</td>
      </tr>
      <tr>
          <td>6.19</td>
          <td>✅ 正常</td>
          <td>❌ 0 帧</td>
          <td>Bug 1</td>
      </tr>
      <tr>
          <td>7.0-rc2</td>
          <td>✅ 正常</td>
          <td>❌ 0 帧</td>
          <td>Bug 1</td>
      </tr>
  </tbody>
</table>
<p><strong>补丁后（tx.c 修复）：</strong></p>
<table>
  <thead>
      <tr>
          <th>内核版本</th>
          <th>纯 Monitor</th>
          <th>Managed + Monitor</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>6.13</td>
          <td>✅ 正常</td>
          <td>✅ ~37 帧/5秒</td>
      </tr>
      <tr>
          <td>6.19</td>
          <td>✅ 正常</td>
          <td>✅ ~39 帧/5秒</td>
      </tr>
      <tr>
          <td>7.0-rc2</td>
          <td>✅ 正常</td>
          <td>✅ ~33 帧/5秒</td>
      </tr>
  </tbody>
</table>
<h2 id="提交上游补丁">
<a class="header-anchor" href="#%e6%8f%90%e4%ba%a4%e4%b8%8a%e6%b8%b8%e8%a1%a5%e4%b8%81"></a>
提交上游补丁
</h2><p>确认修复有效后，按照 Linux 内核贡献流程提交补丁。</p>
<h3 id="生成补丁">
<a class="header-anchor" href="#%e7%94%9f%e6%88%90%e8%a1%a5%e4%b8%81"></a>
生成补丁
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> /root/kernel/linux-7.0-rc2
</span></span><span class="line"><span class="cl"><span class="c1"># 编辑 net/mac80211/tx.c 应用修复</span>
</span></span><span class="line"><span class="cl">git add net/mac80211/tx.c
</span></span><span class="line"><span class="cl">git commit -s  <span class="c1"># Signed-off-by 是必须的</span>
</span></span><span class="line"><span class="cl">git format-patch -1
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="checkpatch-检查">
<a class="header-anchor" href="#checkpatch-%e6%a3%80%e6%9f%a5"></a>
checkpatch 检查
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./scripts/checkpatch.pl 0001-wifi-mac80211-fix-monitor-mode-frame-capture-for-rea.patch
</span></span><span class="line"><span class="cl"><span class="c1"># total: 0 errors, 0 warnings, 41 lines checked</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="获取维护者列表">
<a class="header-anchor" href="#%e8%8e%b7%e5%8f%96%e7%bb%b4%e6%8a%a4%e8%80%85%e5%88%97%e8%a1%a8"></a>
获取维护者列表
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">./scripts/get_maintainer.pl 0001-wifi-mac80211-fix-monitor-mode-frame-capture-for-rea.patch
</span></span></code></pre></td></tr></table>
</div>
</div><p>输出的维护者和邮件列表就是你需要抄送的对象。</p>
<h3 id="发送补丁">
<a class="header-anchor" href="#%e5%8f%91%e9%80%81%e8%a1%a5%e4%b8%81"></a>
发送补丁
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git send-email <span class="se">\
</span></span></span><span class="line"><span class="cl">    --to<span class="o">=</span>linux-wireless@vger.kernel.org <span class="se">\
</span></span></span><span class="line"><span class="cl">    --cc<span class="o">=</span>johannes@sipsolutions.net <span class="se">\
</span></span></span><span class="line"><span class="cl">    --cc<span class="o">=</span>stable@vger.kernel.org <span class="se">\
</span></span></span><span class="line"><span class="cl">    0001-wifi-mac80211-fix-monitor-mode-frame-capture-for-rea.patch
</span></span></code></pre></td></tr></table>
</div>
</div><p>补丁中的关键标签：</p>
<ul>
<li><code>Fixes: 0a44dfc07074</code> — 指明修复哪个 commit 引入的 bug</li>
<li><code>Cc: stable@vger.kernel.org</code> — 请求回溯到受影响的 stable 分支</li>
</ul>
<p>补丁已发送到邮件列表：<a href="https://lore.kernel.org/linux-wireless/20260308164510.5927-1-fjhhz1997@gmail.com/T/#u" target="_blank" rel="noopener noreferrer nofollow">lore.kernel.org 链接</a>
</p>
<h2 id="调试过程中的坑">
<a class="header-anchor" href="#%e8%b0%83%e8%af%95%e8%bf%87%e7%a8%8b%e4%b8%ad%e7%9a%84%e5%9d%91"></a>
调试过程中的坑
</h2><h3 id="1-modulesymvers-缺失">
<a class="header-anchor" href="#1-modulesymvers-%e7%bc%ba%e5%a4%b1"></a>
1. Module.symvers 缺失
</h3><p>只编译单个模块时，如果不复制 <code>Module.symvers</code>，加载时会报 <code>undefined symbol</code> 错误：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp /lib/modules/<span class="k">$(</span>uname -r<span class="k">)</span>/build/Module.symvers .
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="2-模块热替换的顺序">
<a class="header-anchor" href="#2-%e6%a8%a1%e5%9d%97%e7%83%ad%e6%9b%bf%e6%8d%a2%e7%9a%84%e9%a1%ba%e5%ba%8f"></a>
2. 模块热替换的顺序
</h3><p>卸载模块时要注意依赖关系，需要先卸载依赖 mac80211 的驱动模块：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 查看依赖关系</span>
</span></span><span class="line"><span class="cl">lsmod <span class="p">|</span> grep mac80211
</span></span><span class="line"><span class="cl"><span class="c1"># mt7921u → mt7921_common → mt792x_lib → mt76_connac_lib → mt76 → mac80211</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 按依赖顺序卸载</span>
</span></span><span class="line"><span class="cl">sudo rmmod mt7921u mt7921_common mt792x_lib mt76_connac_lib mt76_usb mt76 mac80211
</span></span><span class="line"><span class="cl"><span class="c1"># 加载修改后的模块</span>
</span></span><span class="line"><span class="cl">sudo insmod net/mac80211/mac80211.ko
</span></span><span class="line"><span class="cl">sudo modprobe mt7921u  <span class="c1"># 自动加载整个 mt76 驱动链</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="3-脏模块状态">
<a class="header-anchor" href="#3-%e8%84%8f%e6%a8%a1%e5%9d%97%e7%8a%b6%e6%80%81"></a>
3. 脏模块状态
</h3><p>多次热替换模块后，偶尔会出现模块状态异常（表现为补丁明明应该生效但实际没效果）。遇到这种情况，做一次完整的卸载-重载循环即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo rmmod mt7921u mt7921_common mt792x_lib mt76_connac_lib mt76_usb mt76 mac80211 cfg80211
</span></span><span class="line"><span class="cl">sudo modprobe mac80211  <span class="c1"># 加载原版</span>
</span></span><span class="line"><span class="cl">sudo rmmod mac80211
</span></span><span class="line"><span class="cl">sudo insmod net/mac80211/mac80211.ko  <span class="c1"># 加载修改版</span>
</span></span><span class="line"><span class="cl">sudo modprobe mt7921u
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="4-补丁的版本兼容性">
<a class="header-anchor" href="#4-%e8%a1%a5%e4%b8%81%e7%9a%84%e7%89%88%e6%9c%ac%e5%85%bc%e5%ae%b9%e6%80%a7"></a>
4. 补丁的版本兼容性
</h3><p>我的补丁是基于最新主线（7.0-rc2）编写的，其中包含 <code>emulate_chanctx</code> 分支。但 6.13–6.18 的内核没有这个分支，所以补丁不能直接 <code>git apply</code>。</p>
<p>不过这不影响上游提交——补丁只需要能在当前主线上 apply 即可。stable 团队在回溯时会自行处理冲突，或者我可以在需要时提供针对特定版本的 backport。</p>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>这次调试的收获：</p>
<ol>
<li><strong>只编译单个模块</strong>是调试内核 bug 的高效方法，配合模块热替换可以做到分钟级的修改-测试循环</li>
<li>看似一个 bug 实际可能是<strong>多个独立回归的叠加</strong>，需要跨版本源码对比才能理清</li>
<li>Ubuntu Mainline Kernel 配合 VMware 快照是一个非常方便的多内核测试环境</li>
<li>Linux 内核的补丁提交流程其实并不复杂：<code>git format-patch</code> → <code>checkpatch.pl</code> → <code>get_maintainer.pl</code> → <code>git send-email</code></li>
</ol>

        
        <hr><p>本文2026-03-08首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-08</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>实现claude code抓包分析</title>
      <link>https://csdn.fjh1997.top/posts/54535.html</link>
      <pubDate>Fri, 06 Mar 2026 19:40:35 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/54535.html</guid>
      <description>
        <![CDATA[<h1>实现claude code抓包分析</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>需要设置环境变量</p>
<pre tabindex="0"><code>$env:NODE_TLS_REJECT_UNAUTHORIZED = &#34;0&#34; 
$env:https_proxy = &#34;http://127.0.0.1:8080&#34; 
</code></pre><p>之后启动claude或者插件
Burp里面要设置流式抓包，不然抓到的SSE包不全。
<img src="/images/2026-03-06-20-17-49.png" alt="2026-03-06-20-17-49">
<img src="/images/2026-03-06-20-21-01.png" alt="2026-03-06-20-21-01"></p>

        
        <hr><p>本文2026-03-06首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-06</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用命令行安装 Microsoft C&#43;&#43; (MSVC) Build Tools</title>
      <link>https://csdn.fjh1997.top/posts/26196.html</link>
      <pubDate>Mon, 02 Mar 2026 19:50:51 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/26196.html</guid>
      <description>
        <![CDATA[<h1>使用命令行安装 Microsoft C++ (MSVC) Build Tools</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <pre tabindex="0"><code>winget install Microsoft.VisualStudio.2022.BuildTools
</code></pre>
        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>kernelsu next临时卸载功能开发记录</title>
      <link>https://csdn.fjh1997.top/posts/18939.html</link>
      <pubDate>Mon, 02 Mar 2026 19:14:18 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/18939.html</guid>
      <description>
        <![CDATA[<h1>kernelsu next临时卸载功能开发记录</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p><img src="/images/a437e43e787927e26a27af9cd6e7f7a6.jpeg" alt="a437e43e787927e26a27af9cd6e7f7a6">
基于kernelsu next 3.1.0做了一个支持lkm模式下临时卸载模块的功能。现在无需和少部分牛逼的root检测app斗智斗勇了（比如bochk用的promon shield方案），要用检测root的app的时候临时卸载就行。临时卸载会短暂黑屏，就检测不到了，欢迎参加测试。网上的一些root检测app可能还是能检测到异常，很正常，能过app即可。
使用claude opus4.6开发，修复了pstore以记录内核和app崩溃日志，如果pstore无效可以使用<a href="https://csdn.fjh1997.top/posts/25235.html" target="_blank" rel="noopener noreferrer">高通自带方案</a>
dump日志，
开源地址：https://github.com/fjh1997/KernelSU-Next</p>
<p>pstore修复方案如下：
先找出自己设备地址的分配方案：
查看adb shell cat /proc/iomem | head -n 20 (查看物理内存分布)
用<a href="https://github.com/ssut/payload-dumper-go" target="_blank" rel="noopener noreferrer nofollow">payload-dumper-go</a>
和<a href="https://github.com/cfig/Android_boot_image_editor" target="_blank" rel="noopener noreferrer nofollow">Android_boot_image_editor</a>
解包vendor_boot分区得到很多dts文件，找到芯片型号接近的几个 <code>.dts</code> 文件，找到 <code>ramoops_region</code>，把里面的参数根据物理内存分布直接改成下面这样，我是一加Ace3 Pro：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-dts" data-lang="dts"><span class="line"><span class="cl"><span class="w">		</span><span class="nf">ramoops_region</span><span class="cm"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">compatible</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;ramoops&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="cm">/* 划重点：新基地址 0xffd80000，新总大小 0x280000 (2.5MB) */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">reg</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mh">0x00</span><span class="w"> </span><span class="mh">0xffd80000</span><span class="w"> </span><span class="mh">0x00</span><span class="w"> </span><span class="mh">0x280000</span><span class="o">&gt;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="cm">/* 内部的小 size 随便写或者不写都可以，反正 Bootloader 会强行覆盖它 */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">record-size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mh">0x40000</span><span class="o">&gt;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">console-size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mh">0x40000</span><span class="o">&gt;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">pmsg-size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mh">0x200000</span><span class="o">&gt;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">mem-type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mh">0x02</span><span class="o">&gt;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="na">phandle</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&lt;</span><span class="mi">0</span><span class="n">xXXX</span><span class="o">&gt;</span><span class="p">;</span><span class="w">         </span><span class="cm">/* 再次提醒：务必保留每个文件原本的 phandle！ */</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">			</span><span class="kr">status</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&#34;okay&#34;</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">		</span><span class="p">};</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>重新编译这 8 个文件，打包 <code>vendor_boot.img</code> 和对应的vbmeta一起刷入。
开机后，直接用 <code>dmesg | grep ramoops</code>。</p>
<p>以下是claude opus4.6记录：</p>
<h1 id="kernelsu-next-代码修改总结">
<a class="header-anchor" href="#kernelsu-next-%e4%bb%a3%e7%a0%81%e4%bf%ae%e6%94%b9%e6%80%bb%e7%bb%93"></a>
KernelSU-Next 代码修改总结
</h1><h2 id="一fjh1997-commit-a88b3885-审查结果">
<a class="header-anchor" href="#%e4%b8%80fjh1997-commit-a88b3885-%e5%ae%a1%e6%9f%a5%e7%bb%93%e6%9e%9c"></a>
一、fjh1997 commit <code>a88b3885</code> 审查结果
</h2><p><strong>结论: 代码质量良好，无需删除任何内容。</strong></p>
<table>
  <thead>
      <tr>
          <th>文件</th>
          <th>改动</th>
          <th>评估</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>allowlist.c</code></td>
          <td><code>try_module_get</code>/<code>module_put</code> 保护 task_work</td>
          <td>✅ 正确，防止 rmmod 后 use-after-free</td>
      </tr>
      <tr>
          <td><code>app_profile.c</code></td>
          <td><code>root_groups</code> 从 static 改为 heap alloc</td>
          <td>✅ 正确，防止 rmmod 后悬空指针</td>
      </tr>
      <tr>
          <td><code>kernel_umount.c</code></td>
          <td>module ref 保护 umount task_work</td>
          <td>✅ 正确</td>
      </tr>
      <tr>
          <td><code>setuid_hook.c</code></td>
          <td>module ref 保护 install-fd task_work</td>
          <td>✅ 正确</td>
      </tr>
      <tr>
          <td><code>su_mount_ns.c</code></td>
          <td>module ref 保护 mount-ns task_work</td>
          <td>✅ 正确</td>
      </tr>
      <tr>
          <td><code>supercalls.c</code></td>
          <td><code>do_prepare_unload()</code> + mount_list cleanup</td>
          <td>✅ SIGKILL fd 持有者是合理的</td>
      </tr>
      <tr>
          <td><code>ksud.c</code></td>
          <td>mutex 保护 kprobe 注册状态，恢复 init.rc fops</td>
          <td>✅ 正确，防止 double-unregister</td>
      </tr>
      <tr>
          <td><code>pkg_observer.c</code></td>
          <td>故意泄漏 fsnotify group (~1KB)</td>
          <td>⚠️ 可接受的 tradeoff，避免竞态 crash</td>
      </tr>
      <tr>
          <td><code>throne_tracker.c</code></td>
          <td>APK path hash 清理</td>
          <td>✅ 正确</td>
      </tr>
      <tr>
          <td><code>syscall_hook_manager.c</code></td>
          <td>unmark_all 在 unregister 之前</td>
          <td>✅ 正确</td>
      </tr>
      <tr>
          <td><code>ksu.c</code></td>
          <td><code>ksu_cred</code> 故意泄漏 + rcu_barrier</td>
          <td>✅ 注释充分，避免 rcu 回调后 put_cred crash</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="二rmmod-清理代码修改内核层">
<a class="header-anchor" href="#%e4%ba%8crmmod-%e6%b8%85%e7%90%86%e4%bb%a3%e7%a0%81%e4%bf%ae%e6%94%b9%e5%86%85%e6%a0%b8%e5%b1%82"></a>
二、rmmod 清理代码修改（内核层）
</h2><h3 id="执行顺序">
<a class="header-anchor" href="#%e6%89%a7%e8%a1%8c%e9%a1%ba%e5%ba%8f"></a>
执行顺序
</h3><pre tabindex="0"><code>kernelsu_exit()
  ├─ ksu_umount_all()          ← 新增：卸载所有模块 overlay (需要 ksu_cred)
  ├─ revert_kernelsu_rules()   ← 新增：恢复 SELinux policy
  ├─ flush_workqueue()          
  ├─ kobject_add() restore     
  ├─ ksu_allowlist_exit()      
  ├─ ksu_throne_tracker_exit() 
  ├─ ksu_observer_exit()       
  ├─ ksu_ksud_exit()           
  ├─ ksu_syscall_hook_manager_exit()
  ├─ ksu_supercalls_exit()     
  ├─ ksu_feature_exit()        
  ├─ ksu_cred = NULL           
  ├─ rcu_barrier()             
  └─ flush_workqueue()         
</code></pre>
  <blockquote class="alert-blockquote important">
    <p class="alert-heading">
      Important
    </p>
    <p><p><code>ksu_umount_all()</code> 必须在 <code>ksu_cred = NULL</code> 之前调用，因为它需要 <code>override_creds(ksu_cred)</code> 获取权限来执行 umount。</p></p>
  </blockquote>

<hr>
<h2 id="三用户态深度清理防御-zygisk-痕迹">
<a class="header-anchor" href="#%e4%b8%89%e7%94%a8%e6%88%b7%e6%80%81%e6%b7%b1%e5%ba%a6%e6%b8%85%e7%90%86%e9%98%b2%e5%be%a1-zygisk-%e7%97%95%e8%bf%b9"></a>
三、用户态深度清理（防御 Zygisk 痕迹）
</h2><p><strong>背景</strong>：
高级模块通过手动 shell 脚本执行 <code>mount --bind</code>，不经过 KernelSU 核心框架，因此内核级的 <code>ksu_umount_all()</code> 无法清理它们。模块开发者往往使用匿名 <code>tmpfs</code> 伪装，所以我们需要精准定位目标。</p>
<p><strong>修改文件</strong>：
render_diffs(file:///G:/下载/KernelSU-Next-dev/manager/app/src/main/java/com/rifsxd/ksunext/ui/screen/Settings.kt)</p>
<p><strong>清理方案，注重极致安全性 (绝对无系统损坏风险)</strong>：
在 Manager App 的“临时卸载”逻辑触发 rmmod 之前，通过 root shell 执行：</p>
<ol>
<li><strong>强制清理 Zygisk 文件</strong>：手动 <code>umount -l /system/bin/app_process32</code> 和 <code>app_process64</code>，剥离 Zygisk 劫持。（注：OS 级别 <code>app_process</code> 仅仅是一个文件，在原版镜像中绝不是独立挂载点。如果发生卸载报错会静默跳过，<strong>百分百安全</strong>）。</li>
<li><strong>杀死残留进程</strong>：执行 <code>killall -9 zygiskd</code>，确保由于 fd 继承没被杀干净的 Zygisk 守护进程死亡。</li>
</ol>

  <blockquote class="alert-blockquote caution">
    <p class="alert-heading">
      Caution
    </p>
    <p><p>基于用户要求的“系统维稳”策略，我们已经移除了对 <code>/data/resource-cache</code>、<code>/system/etc/security/cacerts</code> 与 <code>/apex/.../cacerts</code> 的一切卸载操作。因为这些路径在原生安卓中就属于系统基础组件甚至是底层 <code>tmpfs</code> 的构成部分。不盲目执行 umount 能极大地降低由于 APEX 冲突及第三方框架耦合导致的断网或系统崩溃风险，我们将稳定性放在了最优先级。</p></p>
  </blockquote>

<h1 id="kernelsu-next-rmmod-清理代码修改">
<a class="header-anchor" href="#kernelsu-next-rmmod-%e6%b8%85%e7%90%86%e4%bb%a3%e7%a0%81%e4%bf%ae%e6%94%b9"></a>
KernelSU-Next rmmod 清理代码修改
</h1><h2 id="问题">
<a class="header-anchor" href="#%e9%97%ae%e9%a2%98"></a>
问题
</h2><p><code>rmmod</code> 只卸载了内核模块代码，但留下 3 类残留物被 BOCHK 检测到：</p>
<ol>
<li>SELinux policydb 中的 <code>su</code> 域和规则</li>
<li>模块创建的 overlay 挂载</li>
<li><code>ksu_cred</code> 泄漏</li>
</ol>
<h2 id="proposed-changes">
<a class="header-anchor" href="#proposed-changes"></a>
Proposed Changes
</h2><hr>
<h3 id="1-selinux-policy-恢复">
<a class="header-anchor" href="#1-selinux-policy-%e6%81%a2%e5%a4%8d"></a>
1. SELinux Policy 恢复
</h3><h4 id="modify-rulesc">
<a class="header-anchor" href="#modify-rulesc"></a>
[MODIFY] <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/selinux/rules.c">rules.c</a>

</h4><p>添加 <code>revert_kernelsu_rules()</code> 函数：</p>
<ul>
<li>将 <code>su</code> 域从 <strong>permissive</strong> 改回 <strong>enforcing</strong></li>
<li>清除 <code>su</code> 域的 <strong>所有 avtab allow 规则</strong>（遍历 <code>te_avtab</code>，删除 source_type == su 的节点）</li>
<li>重置 AVC 缓存使改动生效</li>
</ul>

  <blockquote class="alert-blockquote warning">
    <p class="alert-heading">
      Warning
    </p>
    <p><p>完全从 policydb 中删除 <code>su</code> type 是不安全的（会导致 type_val_to_struct 下标错乱）。采用的策略是：<strong>将 su 域设为 enforcing + 清除所有 allow 规则</strong>，让 <code>su</code> 域变成一个无权限的死域。这对检测工具来说，和不存在效果相同。</p></p>
  </blockquote>

<h4 id="modify-selinuxh">
<a class="header-anchor" href="#modify-selinuxh"></a>
[MODIFY] <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/selinux/selinux.h">selinux.h</a>

</h4><p>声明 <code>revert_kernelsu_rules()</code> 函数。</p>
<hr>
<h3 id="2-全局-overlay-挂载清理">
<a class="header-anchor" href="#2-%e5%85%a8%e5%b1%80-overlay-%e6%8c%82%e8%bd%bd%e6%b8%85%e7%90%86"></a>
2. 全局 Overlay 挂载清理
</h3><h4 id="modify-kernel_">
<a class="header-anchor" href="#modify-kernel_"></a>
[MODIFY] <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/kernel_umount.c">kernel_umount.c</a>

</h4><p>添加 <code>ksu_umount_all()</code> 函数：</p>
<ul>
<li>遍历 <code>mount_list</code> 中的所有挂载点</li>
<li>用 <code>init</code> 的 cred + mount namespace 执行 <code>path_umount()</code></li>
<li>设置 <code>ksu_module_mounted = false</code></li>
</ul>
<h4 id="modify-kernel_-1">
<a class="header-anchor" href="#modify-kernel_-1"></a>
[MODIFY] <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/kernel_umount.h">kernel_umount.h</a>

</h4><p>声明 <code>ksu_umount_all()</code> 函数。</p>
<hr>
<h3 id="3-主退出函数集成">
<a class="header-anchor" href="#3-%e4%b8%bb%e9%80%80%e5%87%ba%e5%87%bd%e6%95%b0%e9%9b%86%e6%88%90"></a>
3. 主退出函数集成
</h3><h4 id="modify-ksuc">
<a class="header-anchor" href="#modify-ksuc"></a>
[MODIFY] <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/ksu.c">ksu.c</a>

</h4><p>在 <code>kernelsu_exit()</code> 的 <strong>最前面</strong> 添加：</p>
<ol>
<li><code>ksu_umount_all()</code> — 先卸载所有挂载</li>
<li><code>revert_kernelsu_rules()</code> — 再恢复 SELinux</li>
</ol>
<hr>
<h2 id="verification-plan">
<a class="header-anchor" href="#verification-plan"></a>
Verification Plan
</h2>
  <blockquote class="alert-blockquote important">
    <p class="alert-heading">
      Important
    </p>
    <p><p>这是内核模块代码，无法用常规 unit test。需要在 Android 设备上实际验证。</p></p>
  </blockquote>

<h3 id="manual-verification">
<a class="header-anchor" href="#manual-verification"></a>
Manual Verification
</h3><ol>
<li><strong>编译并加载修改后的 KSU 模块</strong></li>
<li><strong>安装 BOCHK 并确认检测到 root</strong> (<code>reason=22</code>)</li>
<li><strong>执行 <code>rmmod kernelsu</code></strong></li>
<li><strong>验证 SELinux</strong>:
<ul>
<li><code>adb shell cat /sys/fs/selinux/enforce</code> → 应为 <code>1</code></li>
<li><code>adb shell sesearch --allow -s su</code> → 应无结果或极少</li>
</ul>
</li>
<li><strong>验证挂载</strong>:
<ul>
<li><code>adb shell cat /proc/self/mountinfo | grep -i overlay</code> → 应无 KSU overlay</li>
</ul>
</li>
<li><strong>重新打开 BOCHK</strong> → 验证 <code>reason</code> 码是否降低或消失</li>
</ol>
<h1 id="kernelsu-next-临时卸载-vs-bochk-root检测--为什么仍被检测">
<a class="header-anchor" href="#kernelsu-next-%e4%b8%b4%e6%97%b6%e5%8d%b8%e8%bd%bd-vs-bochk-root%e6%a3%80%e6%b5%8b--%e4%b8%ba%e4%bb%80%e4%b9%88%e4%bb%8d%e8%a2%ab%e6%a3%80%e6%b5%8b"></a>
KernelSU-Next 临时卸载 vs BOCHK Root检测 — 为什么仍被检测
</h1><h2 id="kernelsu-next-的隐藏机制">
<a class="header-anchor" href="#kernelsu-next-%e7%9a%84%e9%9a%90%e8%97%8f%e6%9c%ba%e5%88%b6"></a>
KernelSU-Next 的隐藏机制
</h2><p>KernelSU-Next 有三个核心隐藏功能：</p>
<h3 id="1-kernel_umount--模块挂载卸载">
<a class="header-anchor" href="#1-kernel_umount--%e6%a8%a1%e5%9d%97%e6%8c%82%e8%bd%bd%e5%8d%b8%e8%bd%bd"></a>
1. <code>KERNEL_UMOUNT</code> — 模块挂载卸载
</h3><p><strong>文件</strong>: <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/kernel_umount.c">kernel_umount.c</a>
</p>
<pre tabindex="0"><code>触发链:
  zygote fork → setresuid() → ksu_handle_setresuid() → ksu_handle_umount()
  → 检查 UID 是否在 deny list → task_work 调度 → umount_tw_func()
  → 遍历 mount_list → try_umount() 每个条目
</code></pre><p><strong>只卸载</strong>: KSU 模块添加的 overlay 挂载点（如 Zygisk 模块注入的 /system 覆盖）</p>
<h3 id="2-avc_spoof--selinux-审计欺骗">
<a class="header-anchor" href="#2-avc_spoof--selinux-%e5%ae%a1%e8%ae%a1%e6%ac%ba%e9%aa%97"></a>
2. <code>AVC_SPOOF</code> — SELinux 审计欺骗
</h3><p><strong>文件</strong>: <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/extras.c">extras.c</a>
</p>
<pre tabindex="0"><code>kprobe hook slow_avc_audit():
  当 tsid == su_sid 时 → 替换为 priv_app_sid
  → 隐藏 SELinux 对 su 域的 denied 审计日志
</code></pre><p><strong>只隐藏</strong>: SELinux <code>avc: denied</code> 日志中的 <code>su</code> context，不隐藏实际的 SELinux policy 修改</p>
<h3 id="3-su_compat--su-二进制兼容">
<a class="header-anchor" href="#3-su_compat--su-%e4%ba%8c%e8%bf%9b%e5%88%b6%e5%85%bc%e5%ae%b9"></a>
3. <code>SU_COMPAT</code> — su 二进制兼容
</h3><p><strong>文件</strong>: <a href="file:///G:/%e4%b8%8b%e8%bd%bd/KernelSU-Next-dev/kernel/sucompat.c">sucompat.c</a>
</p>
<p>KernelSU 没有落地 su 二进制文件，通过内核 hook 直接处理 su 请求</p>
<hr>
<h2 id="bochk-检测-vs-kernelsu-next-隐藏--逐项对照">
<a class="header-anchor" href="#bochk-%e6%a3%80%e6%b5%8b-vs-kernelsu-next-%e9%9a%90%e8%97%8f--%e9%80%90%e9%a1%b9%e5%af%b9%e7%85%a7"></a>
BOCHK 检测 vs KernelSU-Next 隐藏 — 逐项对照
</h2><table>
  <thead>
      <tr>
          <th>BOCHK 检测方法</th>
          <th>KSU 是否隐藏</th>
          <th>原因</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>RootBeer <code>checkSuExists()</code></strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>Runtime.exec(&ldquo;which su&rdquo;) — KSU 不落地su文件，但某些模块可能会</td>
      </tr>
      <tr>
          <td><strong>RootBeer <code>checkForRWPaths()</code></strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>读 <code>/proc/mounts</code> 检查系统分区 rw → KSU 的 overlay mount 可能暴露 rw 挂载</td>
      </tr>
      <tr>
          <td><strong>RootBeer <code>checkForRootNative()</code></strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>Native JNI 检测 → 扫描 <code>/system/xbin/su</code> 等路径</td>
      </tr>
      <tr>
          <td><strong>RootBeer <code>detectRootManagementApps()</code></strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>检查已安装App包名 (Magisk/KSU Manager) → KSU Manager 依然存在</td>
      </tr>
      <tr>
          <td><strong>RootBeer <code>detectRootCloakingApps()</code></strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>检查 Shamiko/RootCloak 等包名</td>
      </tr>
      <tr>
          <td><strong>Promon <code>/mountinfo</code> 扫描</strong></td>
          <td>⚠️ <strong>部分</strong></td>
          <td>KSU umount 只移除模块挂载，但内核本身的修改痕迹仍在 mountinfo</td>
      </tr>
      <tr>
          <td><strong>Promon SVC <code>openat(/proc/self/maps)</code></strong></td>
          <td>❌ <strong>完全无效</strong></td>
          <td>直接 SVC 系统调用，不经过任何可 hook 的层</td>
      </tr>
      <tr>
          <td><strong>Promon GOT 验证</strong></td>
          <td>❌ <strong>完全无效</strong></td>
          <td>检查 libc GOT 表完整性 — KSU 的 syscall hook 不修改 GOT</td>
      </tr>
      <tr>
          <td><strong>Promon Frida线程检测</strong></td>
          <td>❌ <strong>不相关</strong></td>
          <td>这是检测 Frida，不是 root</td>
      </tr>
      <tr>
          <td><strong>Promon 设备完整性</strong></td>
          <td>❌ <strong>未隐藏</strong></td>
          <td>Play Integrity API → bootloader unlocked / custom kernel</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="reason22-你的设备-具体泄露点">
<a class="header-anchor" href="#reason22-%e4%bd%a0%e7%9a%84%e8%ae%be%e5%a4%87-%e5%85%b7%e4%bd%93%e6%b3%84%e9%9c%b2%e7%82%b9"></a>
<code>reason=22</code> (你的设备) 具体泄露点
</h2><p><code>reason=22</code> = 二进制 <code>10110</code>:</p>
<ul>
<li><strong>bit4 = 1</strong>: <code>checkSuExists()</code> — <strong>最可能的泄露</strong></li>
<li><strong>bit2 = 1</strong>: <code>checkForRWPaths()</code> — <strong>模块 overlay mount 泄露</strong></li>
<li><strong>bit1 = 1</strong>: <code>checkForRootNative()</code> — <strong>native 层泄露</strong></li>
</ul>
<h3 id="bit4-checksuexists-触发原因">
<a class="header-anchor" href="#bit4-checksuexists-%e8%a7%a6%e5%8f%91%e5%8e%9f%e5%9b%a0"></a>
bit4: <code>checkSuExists()</code> 触发原因
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// RootBeer 实现</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">public</span><span class="w"> </span><span class="kt">boolean</span><span class="w"> </span><span class="nf">checkSuExists</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">Process</span><span class="w"> </span><span class="n">process</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Runtime</span><span class="p">.</span><span class="na">getRuntime</span><span class="p">().</span><span class="na">exec</span><span class="p">(</span><span class="k">new</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="p">{</span><span class="s">&#34;which&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;su&#34;</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 读取 stdout，如果返回路径则 detected</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>KernelSU-Next <strong>不落地 su 文件</strong>，但：</p>
<ul>
<li>如果安装了 KSU 模块（如 Zygisk-Next），可能会在 <code>/system/bin</code> overlay 中注入 su wrapper</li>
<li><code>KERNEL_UMOUNT</code> 只在 deny list 中的 App （如 BOCHK）启动时卸载 overlay</li>
<li>但 <code>checkSuExists()</code> 用 <code>Runtime.exec(&quot;which su&quot;)</code> 在全局 PATH 中搜索</li>
<li>KSU 的 <code>sucompat.c</code> hook 了 <code>faccessat</code> syscall 来处理 su — 这个 hook <strong>仍在内核中活跃</strong></li>
</ul>
<h3 id="bit2-checkforrwpaths-触发原因">
<a class="header-anchor" href="#bit2-checkforrwpaths-%e8%a7%a6%e5%8f%91%e5%8e%9f%e5%9b%a0"></a>
bit2: <code>checkForRWPaths()</code> 触发原因
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// RootBeer 实现</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="kd">private</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">pathsThatShouldNotBeWritable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;/system&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;/system/bin&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;/system/sbin&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;/system/xbin&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="s">&#34;/vendor/bin&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;/sbin&#34;</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;/etc&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">};</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>KernelSU 模块通过 <code>magic mount</code> (overlay) 修改 <code>/system</code>，这些 overlay 在 <code>kernel_umount.c</code> 的 <code>mount_list</code> 中：</p>
<ul>
<li>如果 BOCHK 不在 deny list → overlay mount 完全可见</li>
<li>即使在 deny list 中，umount 是异步的 (<code>task_work</code>)，可能存在<strong>竞态条件</strong></li>
</ul>
<h3 id="bit1-checkforrootnative-触发原因">
<a class="header-anchor" href="#bit1-checkforrootnative-%e8%a7%a6%e5%8f%91%e5%8e%9f%e5%9b%a0"></a>
bit1: <code>checkForRootNative()</code> 触发原因
</h3><p>RootBeer 的 native 检测通过 JNI 调用 <code>libtool-checker.so</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="c1">// Native root detection
</span></span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">checkForRoot</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// 检测 su, busybox 等二进制文件的存在
</span></span></span><span class="line"><span class="cl">    <span class="c1">// 检测 /system/app/Superuser.apk 等
</span></span></span><span class="line"><span class="cl">    <span class="c1">// 检测 selinux enforcing 状态
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>KernelSU-Next <strong>修改了 SELinux policy</strong>（通过 <code>sepolicy.c</code>），这些修改在内核 policydb 中持久存在，native 代码可以检测到新增的 policy rules。</p>
<hr>
<h2 id="根本原因分析">
<a class="header-anchor" href="#%e6%a0%b9%e6%9c%ac%e5%8e%9f%e5%9b%a0%e5%88%86%e6%9e%90"></a>
根本原因分析
</h2><pre class="mermaid">
  graph TD
    A["KernelSU-Next 临时卸载"] --> B["kernel_umount.c<br/>只卸载 module overlay mounts"]
    A --> C["extras.c<br/>只 spoof SELinux audit log"]
    
    D["BOCHK Java层检测"] --> E["RootBeer 10项检测<br/>走 Java/JNI 标准 API"]
    D --> F["PackageManager<br/>检查 KSU Manager 包名"]
    
    G["BOCHK Native层检测"] --> H["Promon SVC #0<br/>直接系统调用 → 内核<br/>绕过所有 userspace"]
    
    B -.->|"部分有效"| E
    B -.->|"无效"| H
    C -.->|"无效"| E
    
    style H fill:#f44,color:#fff
    style B fill:#ffa,color:#000
    style C fill:#ffa,color:#000
</pre><p><strong>核心问题</strong>: KernelSU-Next 的隐藏机制工作在 <strong>mount namespace</strong> 层面，只处理文件系统覆盖。但 BOCHK 的检测工作在多个层面：</p>
<ol>
<li><strong>Java 层</strong>: <code>Runtime.exec(&quot;which su&quot;)</code>, <code>PackageManager.getInstalledApplications()</code> — KSU umount 无法隐藏非文件系统的痕迹</li>
<li><strong>Native JNI 层</strong>: <code>libtool-checker.so</code> 直接检测 — 不经过 KSU 的任何 hook</li>
<li><strong>Promon SVC 层</strong>: 直接 <code>SVC #0</code> 读取 <code>/proc/self/maps</code> 和 <code>/proc/self/mountinfo</code> — <strong>完全绕过所有 userspace hook</strong>，包括 KSU 的 syscall table hook</li>
</ol>
<hr>
<h2 id="具体泄露清单">
<a class="header-anchor" href="#%e5%85%b7%e4%bd%93%e6%b3%84%e9%9c%b2%e6%b8%85%e5%8d%95"></a>
具体泄露清单
</h2><table>
  <thead>
      <tr>
          <th>#</th>
          <th>泄露类型</th>
          <th>检测方</th>
          <th>KSU 组件</th>
          <th>状态</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>KSU Manager App 包名</td>
          <td>RootBeer <code>detectRootManagementApps</code></td>
          <td>无隐藏</td>
          <td>⚠️ 需要在 deny list 中隐藏</td>
      </tr>
      <tr>
          <td>2</td>
          <td><code>/system</code> overlay mount</td>
          <td>RootBeer <code>checkForRWPaths</code></td>
          <td><code>kernel_umount.c</code></td>
          <td>⚠️ 仅对 deny list UID 有效</td>
      </tr>
      <tr>
          <td>3</td>
          <td>su 相关文件路径</td>
          <td>RootBeer <code>checkSuExists</code></td>
          <td><code>sucompat.c</code> hook</td>
          <td>⚠️ hook 在内核仍活跃</td>
      </tr>
      <tr>
          <td>4</td>
          <td>SELinux policy 修改</td>
          <td>RootBeer native</td>
          <td><code>sepolicy.c</code></td>
          <td>❌ 无法隐藏内核 policydb</td>
      </tr>
      <tr>
          <td>5</td>
          <td>Bootloader 解锁状态</td>
          <td>Promon 设备完整性</td>
          <td>无</td>
          <td>❌ 硬件层面无法隐藏</td>
      </tr>
      <tr>
          <td>6</td>
          <td><code>/proc/self/mountinfo</code></td>
          <td>Promon SVC 直读</td>
          <td>无</td>
          <td>❌ SVC 绕过所有 userspace</td>
      </tr>
      <tr>
          <td>7</td>
          <td>内核模块痕迹</td>
          <td>Promon <code>/proc/modules</code></td>
          <td>无</td>
          <td>❌ KSU 以模块加载时可见</td>
      </tr>
      <tr>
          <td>8</td>
          <td><code>ro.debuggable</code>/build props</td>
          <td>Promon 模拟器检测</td>
          <td>无</td>
          <td>⚠️ 取决于 ROM</td>
      </tr>
  </tbody>
</table>
<h2 id="建议">
<a class="header-anchor" href="#%e5%bb%ba%e8%ae%ae"></a>
建议
</h2><p>要绕过 BOCHK 的检测，需要在<strong>多个层面</strong>同时隐藏：</p>
<ol>
<li><strong>确保 BOCHK 在 deny list 中</strong> — 否则 <code>kernel_umount</code> 完全不工作</li>
<li><strong>隐藏 KSU Manager</strong> — 改包名或从已安装列表中隐藏</li>
<li><strong>处理 Promon SVC 检测</strong> — 需要在内核层面 hook <code>sys_openat</code> 返回假的 maps/mountinfo 给特定进程</li>
<li><strong>隐藏 SELinux policy</strong> — <code>extras.c</code> 的 <code>avc_spoof</code> 只隐藏 audit 日志，不隐藏 policy 本身</li>
<li><strong>处理 Play Integrity</strong> — bootloader 解锁 → 需要 Play Integrity Fix 模块</li>
</ol>

        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用claude code分析bochk 中银香港app防护机制</title>
      <link>https://csdn.fjh1997.top/posts/6786.html</link>
      <pubDate>Mon, 02 Mar 2026 19:04:14 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/6786.html</guid>
      <description>
        <![CDATA[<h1>使用claude code分析bochk 中银香港app防护机制</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <h1 id="分析方法">
<a class="header-anchor" href="#%e5%88%86%e6%9e%90%e6%96%b9%e6%b3%95"></a>
分析方法：
</h1><p>让claude code opus 4.6写frida dump脚本dump出libbochk_aos.so，之后结合<a href="https://github.com/KiFilterFiberContext/promon-reversal" target="_blank" rel="noopener noreferrer nofollow">开源脱壳工具</a>
用jadx反编译<br>
还使用了MCP工具：<a href="https://github.com/mrexodia/ida-pro-mcp" target="_blank" rel="noopener noreferrer nofollow">ida-pro-mcp</a>
 和<a href="https://github.com/mrexodia/ida-pro-mcp" target="_blank" rel="noopener noreferrer nofollow">jadx-ai-mcp</a>
</p>
<p>仅供安全研究学习使用，不得他用。</p>
<h1 id="bochk-app-root--hooking-detection-完整分析报告">
<a class="header-anchor" href="#bochk-app-root--hooking-detection-%e5%ae%8c%e6%95%b4%e5%88%86%e6%9e%90%e6%8a%a5%e5%91%8a"></a>
BOCHK App Root &amp; Hooking Detection 完整分析报告
</h1><h2 id="安全警告-url-参数解码">
<a class="header-anchor" href="#%e5%ae%89%e5%85%a8%e8%ad%a6%e5%91%8a-url-%e5%8f%82%e6%95%b0%e8%a7%a3%e7%a0%81"></a>
安全警告 URL 参数解码
</h2><pre tabindex="0"><code>https://www.bochk.com/dam/securitywarning.html
  ?reason=22
  &amp;manufacturer=OnePlus&amp;model=PJX110&amp;android=36
  &amp;version=6.6.1
  &amp;hookingframeworks=F4
  &amp;return=4
  &amp;srcApp=bochk
</code></pre><table>
  <thead>
      <tr>
          <th>参数</th>
          <th>值</th>
          <th>含义</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>reason</code></td>
          <td><strong>22</strong></td>
          <td>Root检测错误码（<code>BOCLFRootUtils.getRootErrorCode()</code> 生成的10位二进制转十进制）</td>
      </tr>
      <tr>
          <td><code>hookingframeworks</code></td>
          <td><strong>F4</strong></td>
          <td>Promon Shield native 层检测到的 hooking framework 位掩码</td>
      </tr>
      <tr>
          <td><code>return</code></td>
          <td><strong>4</strong></td>
          <td>返回行为码：打开浏览器显示安全警告</td>
      </tr>
      <tr>
          <td><code>reason=50</code></td>
          <td><em>(另一个URL)</em></td>
          <td>恶意软件检测（<code>MainActivity.a(C0566h)</code> 触发）</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="检测架构">
<a class="header-anchor" href="#%e6%a3%80%e6%b5%8b%e6%9e%b6%e6%9e%84"></a>
检测架构
</h2><pre class="mermaid">
  graph TD
    A["App启动"] --> B["jtqupujl.aP.attachBaseContext()<br/>(extends Application)"]
    B --> C["jtqupujl.Y.c() → d() → b()<br/>System.loadLibrary('bochk_aos')"]
    C --> D["libbochk_aos.so JNI_OnLoad<br/>Promon Shield 初始化"]
    
    D --> E["Native 检测引擎<br/>SVC 直接系统调用"]
    E --> E1["DoCodetracerDetection<br/>sub_26B680"]
    E --> E2["CodetracerDetection<br/>sub_26BD20"]
    E --> E3["AllowedPackagesForRootingCheck<br/>protobuf 配置"]
    
    E1 --> F["jtqupujl.U Service<br/>native a()/b()/c()/d()"]
    E2 --> F
    F --> G["jtqupujl.G AbstractBinder<br/>IPC 传递检测结果"]
    G --> H["构建 URL<br/>reason=22 & hookingframeworks=F4"]
    H --> I["k.j().D(fragment, url)<br/>Intent.ACTION_VIEW 打开浏览器"]

    A --> J["BOCHKLaunchFlow.Launch()"]
    J --> K["BOCHKLaunchFlow.K()<br/>Java 层 Root 检测"]
    K --> L["BOCLFRootUtils.checkRoot()<br/>10项 RootBeer 检测"]
    L -->|"rooted"| M["BOCLFRootUtils.getRootErrorCode()<br/>生成 reason 码"]
    M --> N["BOCHKLaunchFlow.Q()<br/>上报 rootErrorCode 到服务器"]
    L -->|"not rooted"| O["BOCHKLaunchFlow.F()<br/>继续启动流程"]
</pre><hr>
<h2 id="第一层java-root-检测">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%80%e5%b1%82java-root-%e6%a3%80%e6%b5%8b"></a>
第一层：Java Root 检测
</h2><h3 id="入口bochklaunchflowk">
<a class="header-anchor" href="#%e5%85%a5%e5%8f%a3bochklaunchflowk"></a>
入口：<a href="file:///G:/%e4%b8%8b%e8%bd%bd/promon-string-deobfuscator-main/apktool_work/decoded/smali_classes5/com/bochklaunchflow/BOCHKLaunchFlow.smali">BOCHKLaunchFlow.K()</a>

</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// BOCHKLaunchFlow.K() — Root 检查决策</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="na">f32533m</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">  </span><span class="c1">// setCheckRoot(false) 可跳过</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">F</span><span class="p">(</span><span class="n">activity</span><span class="p">);</span><span class="w">  </span><span class="c1">// 跳过 root 检测</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">BOCLFRootUtils</span><span class="p">.</span><span class="na">checkRoot</span><span class="p">(</span><span class="n">activity</span><span class="p">.</span><span class="na">getApplicationContext</span><span class="p">()))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">F</span><span class="p">(</span><span class="n">activity</span><span class="p">);</span><span class="w">  </span><span class="c1">// 未 root，继续</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">String</span><span class="w"> </span><span class="n">rootErrorCode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">BOCLFRootUtils</span><span class="p">.</span><span class="na">getRootErrorCode</span><span class="p">(</span><span class="n">ctx</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">Q</span><span class="p">(</span><span class="n">activity</span><span class="p">,</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="na">f32529i</span><span class="p">,</span><span class="w"> </span><span class="n">rootErrorCode</span><span class="p">);</span><span class="w">  </span><span class="c1">// 上报错误码</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 显示 root 提示对话框</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="boclfrootutilscheckroot--10项检测">
<a class="header-anchor" href="#boclfrootutilscheckroot--10%e9%a1%b9%e6%a3%80%e6%b5%8b"></a>
<a href="file:///G:/%e4%b8%8b%e8%bd%bd/promon-string-deobfuscator-main/apktool_work/decoded/smali_classes5/com/bochklaunchflow/utils/BOCLFRootUtils.smali">BOCLFRootUtils.checkRoot()</a>
 — 10项检测
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="k">return</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectRootManagementApps</span><span class="p">()</span><span class="w">     </span><span class="c1">// bit9: Root管理App (Magisk/SuperSU)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectPotentiallyDangerousApps</span><span class="p">()</span><span class="w"> </span><span class="c1">// bit8: 危险App</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForBinary</span><span class="p">(</span><span class="s">&#34;su&#34;</span><span class="p">)</span><span class="w">             </span><span class="c1">// bit5: su二进制</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForRWPaths</span><span class="p">()</span><span class="w">                </span><span class="c1">// bit4: RW路径挂载</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectTestKeys</span><span class="p">()</span><span class="w">                 </span><span class="c1">// bit7: 测试签名keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkSuExists</span><span class="p">()</span><span class="w">                  </span><span class="c1">// bit3: su进程存在</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForRootNative</span><span class="p">()</span><span class="w">             </span><span class="c1">// bit1: Native root检测</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="o">||</span><span class="w"> </span><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectRootCloakingApps</span><span class="p">();</span><span class="w">         </span><span class="c1">// bit0: Root隐藏App</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="boclfrootutilsgetrooterrorcode--reason-码生成">
<a class="header-anchor" href="#boclfrootutilsgetrooterrorcode--reason-%e7%a0%81%e7%94%9f%e6%88%90"></a>
<a href="file:///G:/%e4%b8%8b%e8%bd%bd/promon-string-deobfuscator-main/apktool_work/decoded/smali_classes5/com/bochklaunchflow/utils/BOCLFRootUtils.smali">BOCLFRootUtils.getRootErrorCode()</a>
 — reason 码生成
</h3><p>生成 <strong>10位二进制字符串</strong>，转十进制作为 <code>reason</code> 值：</p>
<table>
  <thead>
      <tr>
          <th>Bit (高→低)</th>
          <th>检测项</th>
          <th>你的设备</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>bit9 (MSB)</td>
          <td><code>detectRootManagementApps()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit8</td>
          <td><code>detectPotentiallyDangerousApps()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit7</td>
          <td><code>detectTestKeys()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit6</td>
          <td><em>(固定0)</em></td>
          <td>0</td>
      </tr>
      <tr>
          <td>bit5</td>
          <td><code>checkForSuBinary()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit4</td>
          <td><code>checkSuExists()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit3</td>
          <td><code>checkForRWPaths()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit2</td>
          <td><em>(固定0)</em></td>
          <td>0</td>
      </tr>
      <tr>
          <td>bit1</td>
          <td><code>checkForRootNative()</code></td>
          <td>?</td>
      </tr>
      <tr>
          <td>bit0 (LSB)</td>
          <td><code>detectRootCloakingApps()</code></td>
          <td>?</td>
      </tr>
  </tbody>
</table>

  <blockquote class="alert-blockquote important">
    <p class="alert-heading">
      Important
    </p>
    <p><p><code>reason=22</code> = 十进制22 = 二进制 <code>0000010110</code></p>
<ul>
<li>bit4 (=1): <code>checkSuExists()</code> 检测到 su</li>
<li>bit2 (=1): <code>checkForRWPaths()</code> 检测到 RW 路径</li>
<li>bit1 (=1): <code>checkForRootNative()</code> native层 root 检测</li>
</ul></p>
  </blockquote>

<hr>
<h2 id="第二层promon-shield-native-检测-hookingframeworksf4">
<a class="header-anchor" href="#%e7%ac%ac%e4%ba%8c%e5%b1%82promon-shield-native-%e6%a3%80%e6%b5%8b-hookingframeworksf4"></a>
第二层：Promon Shield Native 检测 (hookingframeworks=F4)
</h2><h3 id="初始化链">
<a class="header-anchor" href="#%e5%88%9d%e5%a7%8b%e5%8c%96%e9%93%be"></a>
初始化链
</h3><table>
  <thead>
      <tr>
          <th>步骤</th>
          <th>类</th>
          <th>方法</th>
          <th>作用</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td><code>jtqupujl.aP</code></td>
          <td><code>attachBaseContext()</code></td>
          <td>Application 入口，调用 Promon init</td>
      </tr>
      <tr>
          <td>2</td>
          <td><code>jtqupujl.Y</code></td>
          <td><code>c()</code> → <code>d()</code> → <code>b()</code></td>
          <td>加载 <code>libbochk_aos.so</code></td>
      </tr>
      <tr>
          <td>3</td>
          <td><code>jtqupujl.Y</code></td>
          <td><code>a(Application)</code> (native)</td>
          <td>初始化 Promon Shield</td>
      </tr>
      <tr>
          <td>4</td>
          <td><code>jtqupujl.U</code></td>
          <td><code>a()</code>, <code>b()</code>, <code>c()</code>, <code>d()</code> (native)</td>
          <td>Service 中暴露检测结果</td>
      </tr>
      <tr>
          <td>5</td>
          <td><code>jtqupujl.G</code></td>
          <td><code>a()</code>, <code>b()</code>, <code>c()</code>, <code>d()</code></td>
          <td>Binder IPC 代理检测结果</td>
      </tr>
  </tbody>
</table>
<h3 id="检测类型枚举-jtqupujlenumc0539aa--17种完整映射">
<a class="header-anchor" href="#%e6%a3%80%e6%b5%8b%e7%b1%bb%e5%9e%8b%e6%9e%9a%e4%b8%be-jtqupujlenumc0539aa--17%e7%a7%8d%e5%ae%8c%e6%95%b4%e6%98%a0%e5%b0%84"></a>
检测类型枚举 (<code>jtqupujl.EnumC0539aa</code>) — 17种完整映射
</h3>
  <blockquote class="alert-blockquote important">
    <p class="alert-heading">
      Important
    </p>
    <p><p>以下映射通过 JADX 源码分析（每个枚举值对应一个 <code>aO</code> 子类）+ IDA protobuf 字符串 + Promon Shield 官方文档交叉验证得出。</p></p>
  </blockquote>

<table>
  <thead>
      <tr>
          <th>#</th>
          <th>枚举值</th>
          <th>实现类</th>
          <th>Key字段</th>
          <th>数据结构</th>
          <th>推断检测类型</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td><strong><code>m</code></strong></td>
          <td><code>C0571m</code></td>
          <td>1-4</td>
          <td>bool + 3×int</td>
          <td><strong>Root检测</strong> — 核心检测，keys 1-4 最小编号，3个int存root方法计数</td>
      </tr>
      <tr>
          <td>2</td>
          <td><strong><code>f</code></strong></td>
          <td><code>C0562d</code></td>
          <td>257 (0x101)</td>
          <td>bool</td>
          <td><strong>Frida 检测</strong> — 单布尔值，检测frida-server/agent</td>
      </tr>
      <tr>
          <td>3</td>
          <td><strong><code>b</code></strong></td>
          <td><code>aQ</code></td>
          <td>513 (0x201)</td>
          <td>bool</td>
          <td><strong>调试器检测 (Debugger)</strong> — 单布尔值，反JDWP/ptrace</td>
      </tr>
      <tr>
          <td>4</td>
          <td><strong><code>r</code></strong></td>
          <td><code>C0559au</code></td>
          <td>769 (0x301)</td>
          <td>bool</td>
          <td><strong>重打包检测 (Repackaging)</strong> — 签名校验</td>
      </tr>
      <tr>
          <td>5</td>
          <td><strong><code>i</code></strong></td>
          <td><code>ay</code></td>
          <td>1025-1030</td>
          <td>bool + 5×str</td>
          <td><strong>Hooking框架检测</strong> — 包含框架名/路径/版本等5字段</td>
      </tr>
      <tr>
          <td>6</td>
          <td><strong><code>h</code></strong></td>
          <td><code>C0573o</code></td>
          <td>1537 (0x601)</td>
          <td>bool</td>
          <td><strong>屏幕叠加/录屏检测</strong> — 防止Overlay攻击</td>
      </tr>
      <tr>
          <td>7</td>
          <td><strong><code>q</code></strong></td>
          <td><code>aG</code></td>
          <td>1793-1798</td>
          <td>bool + 5×str</td>
          <td><strong>代码追踪器检测 (Code Tracer)</strong> — 与IDA中<code>DoCodetracerDetection</code>/<code>CodetracerDetection</code>对应</td>
      </tr>
      <tr>
          <td>8</td>
          <td><strong><code>n</code></strong></td>
          <td><code>C0564f</code></td>
          <td>5633-5634</td>
          <td>bool + int</td>
          <td><strong>模拟器检测 (Emulator)</strong> — int存模拟器类型码</td>
      </tr>
      <tr>
          <td>9</td>
          <td><strong><code>o</code></strong></td>
          <td><code>aB</code></td>
          <td>6145-6146</td>
          <td>2×bool</td>
          <td><strong>无障碍服务检测</strong> — 两个bool分别检测是否开启和是否恶意</td>
      </tr>
      <tr>
          <td>10</td>
          <td><strong><code>g</code></strong></td>
          <td><code>K</code></td>
          <td>8705-8707</td>
          <td>str + 2×bool</td>
          <td><strong>篡改检测 (Tampering)</strong> — 字符串存证书hash</td>
      </tr>
      <tr>
          <td>11</td>
          <td><strong><code>l</code></strong></td>
          <td><code>S</code></td>
          <td>8450-8451</td>
          <td>2×bool</td>
          <td><strong>虚拟环境检测</strong> — 双布尔，<code>d()</code>=a或b任一触发</td>
      </tr>
      <tr>
          <td>12</td>
          <td><strong><code>k</code></strong></td>
          <td><code>T</code></td>
          <td>12289-12291</td>
          <td>ComponentName + 2×str</td>
          <td><strong>恶意Activity检测</strong> — 存Activity组件名和包名</td>
      </tr>
      <tr>
          <td>13</td>
          <td><strong><code>c</code></strong></td>
          <td><code>C0540ab</code></td>
          <td>16384 (0x4000)</td>
          <td>bool</td>
          <td><strong>SSL Pinning/证书验证</strong> — 高key值检测</td>
      </tr>
      <tr>
          <td>14</td>
          <td><strong><code>p</code></strong></td>
          <td><code>C0549ak</code></td>
          <td>16640</td>
          <td>list(8-field)</td>
          <td><strong>已安装App扫描</strong> — 8字段详细记录每个可疑App信息</td>
      </tr>
      <tr>
          <td>15</td>
          <td><strong><code>d</code></strong></td>
          <td><code>C0572n</code></td>
          <td>16897 (0x4201)</td>
          <td>bool</td>
          <td><strong>设备完整性检测</strong> — Play Integrity / SafetyNet</td>
      </tr>
      <tr>
          <td>16</td>
          <td><strong><code>j</code></strong></td>
          <td><code>W</code></td>
          <td>17153 (0x4301)</td>
          <td>bool</td>
          <td><strong>密钥存储检测</strong> — Keystore安全检测</td>
      </tr>
      <tr>
          <td>17</td>
          <td><strong><code>a</code></strong></td>
          <td><code>aD</code></td>
          <td>LIVE_RESULT_SUCCESS</td>
          <td>list(5-field)</td>
          <td><strong>恶意App哈希匹配</strong> — 与服务器下发hash比对</td>
      </tr>
  </tbody>
</table>
<h3 id="检测结果回调流程">
<a class="header-anchor" href="#%e6%a3%80%e6%b5%8b%e7%bb%93%e6%9e%9c%e5%9b%9e%e8%b0%83%e6%b5%81%e7%a8%8b"></a>
检测结果回调流程
</h3><pre class="mermaid">
  graph LR
    A["Native Detection<br/>libbochk_aos.so"] -->|JNI| B["jtqupujl.Q.b()<br/>注册观察者 (native)"]
    B --> C["创建 aO 子类实例<br/>(如 C0571m/C0562d等)"]
    C --> D["InterfaceC0567i.a(aO)<br/>回调观察者"]
    D --> E["x1.b.a(aO)<br/>BOCHK 回调处理"]
    E -->|"enum a"| F["恶意App哈希匹配<br/>→ load_unofficial_app_key"]
    E -->|"enum p"| G["已安装App扫描<br/>→ load_unofficial_app_key"]
    D --> H["Promon内部处理<br/>构建 securitywarning URL"]
    H --> I["k.j().D()<br/>打开浏览器"]
</pre><h3 id="关键发现x1b-回调实现">
<a class="header-anchor" href="#%e5%85%b3%e9%94%ae%e5%8f%91%e7%8e%b0x1b-%e5%9b%9e%e8%b0%83%e5%ae%9e%e7%8e%b0"></a>
关键发现：<code>x1.b</code> 回调实现
</h3><p><code>x1.b</code> 实现了 <code>InterfaceC0567i</code>，专门处理两种枚举的检测结果：</p>
<ul>
<li><strong><code>EnumC0539aa.a</code></strong> (aD类): 遍历恶意App列表，提取包名/hash/路径 → 上传为 JSON</li>
<li><strong><code>EnumC0539aa.p</code></strong> (C0549ak类): 遍历已安装App列表（8字段详细信息）→ 上传为 JSON</li>
<li>两者合并后通过 <code>h2.a.c(&quot;load_unofficial_app_key&quot;)</code> 上报到服务器</li>
</ul>
<h3 id="native-层检测技术-ida-分析">
<a class="header-anchor" href="#native-%e5%b1%82%e6%a3%80%e6%b5%8b%e6%8a%80%e6%9c%af-ida-%e5%88%86%e6%9e%90"></a>
Native 层检测技术 (IDA 分析)
</h3><table>
  <thead>
      <tr>
          <th>函数</th>
          <th>IDA地址</th>
          <th>技术</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>DoCodetracerDetection</code></td>
          <td><code>sub_26B680</code></td>
          <td>通过 SVC 直接系统调用扫描 /proc/self/maps，检测 Frida agent 内存映射</td>
      </tr>
      <tr>
          <td><code>CodetracerDetection</code></td>
          <td><code>sub_26BD20</code></td>
          <td>检测代码追踪器（Frida/Xposed/Substrate 线程名和内存特征）</td>
      </tr>
      <tr>
          <td><code>OnCodeTracerDetectedCallback</code></td>
          <td>内部回调</td>
          <td>检测到后触发 pipe 通知</td>
      </tr>
      <tr>
          <td><code>SyscallNo</code></td>
          <td><code>0x3c099</code></td>
          <td>内联 SVC 系统调用号标记，绕过 libc hook</td>
      </tr>
  </tbody>
</table>
<h3 id="hookingframeworksf4-解析">
<a class="header-anchor" href="#hookingframeworksf4-%e8%a7%a3%e6%9e%90"></a>
<code>hookingframeworks=F4</code> 解析
</h3><p><code>F4</code> 十六进制 = <code>244</code> 十进制 = 二进制 <code>11110100</code>，表示 Promon Shield 通过 <code>EnumC0539aa</code> 的多个检测类型均返回阳性：</p>
<table>
  <thead>
      <tr>
          <th>Bit</th>
          <th>可能含义</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>bit2=1</td>
          <td><strong>Frida</strong> 检测（内存中发现 frida-agent）</td>
      </tr>
      <tr>
          <td>bit4=1</td>
          <td><strong>Xposed Framework</strong></td>
      </tr>
      <tr>
          <td>bit5=1</td>
          <td><strong>Substrate/LSposed</strong></td>
      </tr>
      <tr>
          <td>bit6=1</td>
          <td>代码追踪器/调试器</td>
      </tr>
      <tr>
          <td>bit7=1</td>
          <td>其他检测</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="第三层恶意软件检测-reason50">
<a class="header-anchor" href="#%e7%ac%ac%e4%b8%89%e5%b1%82%e6%81%b6%e6%84%8f%e8%bd%af%e4%bb%b6%e6%a3%80%e6%b5%8b-reason50"></a>
第三层：恶意软件检测 (reason=50)
</h2><p>在 <code>MainActivity.a(C0566h)</code> 中，如果检测到恶意软件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="n">k</span><span class="p">.</span><span class="na">j</span><span class="p">().</span><span class="na">D</span><span class="p">(</span><span class="n">fragment</span><span class="p">,</span><span class="w"> </span><span class="s">&#34;https://www.bochk.com/dam/securitywarning.html?reason=50&amp;srcApp=bochk&#34;</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">PageManager</span><span class="p">.</span><span class="na">getInstance</span><span class="p">().</span><span class="na">removeAllFragment</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">finish</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">System</span><span class="p">.</span><span class="na">exit</span><span class="p">(</span><span class="n">0</span><span class="p">);</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>恶意软件扫描流程: <code>jtqupujl.aR</code> → <code>jtqupujl.aM.a()</code> 扫描已安装App → 与服务器下发的 SHA-256 哈希比对 → 匹配则触发 <code>reason=50</code>。</p>
<hr>
<h2 id="第四层cloudwalk-活体检测环境安全检查">
<a class="header-anchor" href="#%e7%ac%ac%e5%9b%9b%e5%b1%82cloudwalk-%e6%b4%bb%e4%bd%93%e6%a3%80%e6%b5%8b%e7%8e%af%e5%a2%83%e5%ae%89%e5%85%a8%e6%a3%80%e6%9f%a5"></a>
第四层：CloudWalk 活体检测环境安全检查
</h2><p>CloudWalk SDK (<code>cn.cloudwalk</code>) 是 BOCHK 使用的<strong>人脸活体检测</strong>组件。在启动活体检测前，会进行独立的环境安全检查。</p>
<h3 id="入口cwbaselivefragmentcheckroot">
<a class="header-anchor" href="#%e5%85%a5%e5%8f%a3cwbaselivefragmentcheckroot"></a>
入口：<code>CwBaseLiveFragment.checkRoot()</code>
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// 1. 先检查 Root</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mConfig</span><span class="p">.</span><span class="na">isCheckRuntimeEnvironment</span><span class="p">()</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">RootUtil</span><span class="p">.</span><span class="na">isDeviceRooted</span><span class="p">(</span><span class="n">getActivity</span><span class="p">(),</span><span class="w"> </span><span class="n">mConfig</span><span class="p">.</span><span class="na">isCheckBusyBox</span><span class="p">()))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mConfig</span><span class="p">.</span><span class="na">isInterceptUnsafeRuntimeEnvironment</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="c1">// 设备环境不安全，终止活体检测</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="n">handler</span><span class="p">.</span><span class="na">sendEmptyMessageDelayed</span><span class="p">(</span><span class="n">CMD</span><span class="p">.</span><span class="na">SERVER_RECEIVE_USER_DATA</span><span class="p">,</span><span class="w"> </span><span class="p">...);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// 回调 onLivenessFail(UNSAFE_ENVIRONMENT)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 2. 禁用 Xposed</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">disableXposed</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 3. 检测 Hooking Framework</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">mConfig</span><span class="p">.</span><span class="na">isCheckRuntimeEnvironment</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">HookToolDetector</span><span class="p">.</span><span class="na">c</span><span class="p">().</span><span class="na">a</span><span class="p">(</span><span class="n">context</span><span class="p">,</span><span class="w"> </span><span class="n">callback</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="c1">// 4. 检测 HTTP 代理</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">DeviceUtil</span><span class="p">.</span><span class="na">isHttpProxy</span><span class="p">())</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="n">detectFail</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span><span class="w"> </span><span class="n">CwLiveCode</span><span class="p">.</span><span class="na">UNSAFE_NETWORK_ENVIRONMENT</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="p">}</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="hooktooldetector-6项检测加载-libcwutilsso">
<a class="header-anchor" href="#hooktooldetector-6%e9%a1%b9%e6%a3%80%e6%b5%8b%e5%8a%a0%e8%bd%bd-libcwutilsso"></a>
<code>HookToolDetector</code> 6项检测（加载 <code>LibCwUtils.so</code>）
</h3><table>
  <thead>
      <tr>
          <th>方法</th>
          <th>检测技术</th>
          <th>详情</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>e()</code></td>
          <td><strong>Xposed 类加载检测</strong></td>
          <td>尝试 <code>ClassLoader.loadClass(&quot;de.robv.android.xposed.XposedHelpers&quot;)</code> 和 <code>&quot;XposedBridge&quot;</code>，加载成功=被 hook</td>
      </tr>
      <tr>
          <td><code>d()</code></td>
          <td><strong>Xposed 异常栈检测</strong></td>
          <td>故意抛出异常，遍历 <code>StackTrace</code> 检查是否包含 Xposed 类名</td>
      </tr>
      <tr>
          <td><code>f()</code></td>
          <td><strong>内存映射检测</strong></td>
          <td>读取 <code>/proc/self/maps</code>，搜索 3 个 Xposed 相关 so 库名（混淆字符）</td>
      </tr>
      <tr>
          <td><code>a()</code></td>
          <td><strong>Frida 线程检测</strong></td>
          <td>读取 <code>/proc/[pid]/task/*/status</code>，搜索 <strong>&ldquo;frida&rdquo;</strong>、<strong>&ldquo;gmain&rdquo;</strong>、<strong>&ldquo;gdbus&rdquo;</strong> 线程名</td>
      </tr>
      <tr>
          <td><code>b()</code></td>
          <td><strong>调试器 TracerPid 检测</strong></td>
          <td>读取 <code>/proc/[pid]/status</code> 的 <code>TracerPid</code> 字段，非0=被调试</td>
      </tr>
      <tr>
          <td><code>isFileExists()</code></td>
          <td><strong>Native 文件完整性</strong></td>
          <td>通过 <code>LibCwUtils.so</code> native 方法检测 sandbox/虚拟环境（创建测试文件 <code>cw-test.txt</code>，native 层验证文件是否真实存在）</td>
      </tr>
  </tbody>
</table>

  <blockquote class="alert-blockquote note">
    <p class="alert-heading">
      Note
    </p>
    <p><p>CloudWalk 还额外检测：</p>
<ul>
<li><strong>模拟器</strong>: <code>d.j().a(context)</code> — 模拟器环境检测</li>
<li><strong>HTTP 代理</strong>: <code>DeviceUtil.isHttpProxy()</code> — 检测中间人代理</li>
<li><strong>Mock 位置</strong>: <code>Location.isFromMockProvider()</code> — GPS 位置模拟检测</li>
</ul></p>
  </blockquote>

<hr>
<h2 id="关键类映射表">
<a class="header-anchor" href="#%e5%85%b3%e9%94%ae%e7%b1%bb%e6%98%a0%e5%b0%84%e8%a1%a8"></a>
关键类映射表
</h2><table>
  <thead>
      <tr>
          <th>类</th>
          <th>功能</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>com.bochklaunchflow.BOCHKLaunchFlow</code></td>
          <td>启动流程总控：Root检测→版本检查→黑名单→维护</td>
      </tr>
      <tr>
          <td><code>com.bochklaunchflow.utils.BOCLFRootUtils</code></td>
          <td>Java Root检测：10项RootBeer检测 + 生成 reason 码</td>
      </tr>
      <tr>
          <td><code>com.tradelink.boc.rootdetection.ui.RootDetectionActivity</code></td>
          <td>Root检测 Activity UI</td>
      </tr>
      <tr>
          <td><code>com.scottyab.rootbeer.RootBeer</code></td>
          <td>第三方 Root 检测库</td>
      </tr>
      <tr>
          <td><code>cn.cloudwalk.libproject.hook.HookToolDetector</code></td>
          <td>CloudWalk Hook/Root/Frida 检测（加载 <code>LibCwUtils.so</code>）</td>
      </tr>
      <tr>
          <td><code>cn.cloudwalk.libproject.live.CwBaseLiveFragment</code></td>
          <td>活体检测入口，调用 <code>checkRoot()</code></td>
      </tr>
      <tr>
          <td><code>jtqupujl.aP</code></td>
          <td>Promon Application 入口</td>
      </tr>
      <tr>
          <td><code>jtqupujl.Y</code></td>
          <td>加载 <code>libbochk_aos.so</code>，初始化 Promon</td>
      </tr>
      <tr>
          <td><code>jtqupujl.U</code></td>
          <td>Service，暴露 native 检测结果</td>
      </tr>
      <tr>
          <td><code>jtqupujl.G</code></td>
          <td>Binder IPC 代理</td>
      </tr>
      <tr>
          <td><code>jtqupujl.aO</code></td>
          <td>检测结果 HashMap 存储</td>
      </tr>
      <tr>
          <td><code>jtqupujl.EnumC0539aa</code></td>
          <td>17种检测类型枚举</td>
      </tr>
      <tr>
          <td><code>jtqupujl.aR</code></td>
          <td>恶意软件扫描管理</td>
      </tr>
      <tr>
          <td><code>jtqupujl.aM</code></td>
          <td>恶意软件应用匹配</td>
      </tr>
      <tr>
          <td><code>jtqupujl.aS</code></td>
          <td><code>libjni_proxy_launcher.so</code> 加载</td>
      </tr>
      <tr>
          <td><code>com.bochk.base.utils.k.D()</code></td>
          <td><code>Intent.ACTION_VIEW</code> 打开安全警告 URL</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="总结">
<a class="header-anchor" href="#%e6%80%bb%e7%bb%93"></a>
总结
</h2><p>BOCHK App 使用 <strong>四层防护</strong>：</p>
<ol>
<li><strong>Java RootBeer</strong> (<code>BOCLFRootUtils</code>): 10项软检测，生成 <code>reason</code> 码（你的 <code>reason=22</code> = su存在 + RW路径 + native root）</li>
<li><strong>Promon Shield Native</strong> (<code>libbochk_aos.so</code>): 通过内联 SVC 系统调用检测 Frida/Xposed/调试器，生成 <code>hookingframeworks</code> 码（你的 <code>F4</code> = 多种框架被检测到）</li>
<li><strong>恶意软件扫描</strong> (<code>jtqupujl.aR/aM</code>): 比对服务器哈希数据库，触发 <code>reason=50</code></li>
<li><strong>CloudWalk 环境检查</strong> (<code>HookToolDetector</code>): 在人脸活体检测前执行 6 项独立检测（Xposed类加载/栈/maps + Frida线程 + TracerPid + native文件），加载 <code>LibCwUtils.so</code>，还检测模拟器/HTTP代理/Mock位置</li>
</ol>
<p>所有检测结果通过 <code>k.j().D(fragment, url)</code> → <code>Intent.ACTION_VIEW</code> 打开浏览器显示安全警告页面。</p>
<h1 id="bochk-17种-promon-shield-检测方法深度分析">
<a class="header-anchor" href="#bochk-17%e7%a7%8d-promon-shield-%e6%a3%80%e6%b5%8b%e6%96%b9%e6%b3%95%e6%b7%b1%e5%ba%a6%e5%88%86%e6%9e%90"></a>
BOCHK 17种 Promon Shield 检测方法深度分析
</h1>
  <blockquote class="alert-blockquote important">
    <p class="alert-heading">
      Important
    </p>
    <p><p>Promon Shield 对所有敏感字符串（frida/xposed/su/magisk等）进行了<strong>运行时加密</strong>，静态分析无法直接找到明文。以下分析结合了 IDA 反编译、JADX 源码及 Promon Shield 官方文档。</p></p>
  </blockquote>

<hr>
<h2 id="检测方法总览">
<a class="header-anchor" href="#%e6%a3%80%e6%b5%8b%e6%96%b9%e6%b3%95%e6%80%bb%e8%a7%88"></a>
检测方法总览
</h2><pre class="mermaid">
  graph TD
    subgraph "Native Layer - libbochk_aos.so"
        JIT["JIT代码生成器<br/>动态组装 ARM SVC 指令"]
        SVC["SVC #0 直接系统调用<br/>绕过 libc hook"]
        PROC["/proc 文件系统扫描<br/>maps/status/mountinfo"]
        GOT["GOT 表完整性验证"]
        HASH["文件/段 Hash 校验"]
    end
    
    subgraph "Java Layer - jtqupujl.*"
        OBS["InterfaceC0567i 观察者"]
        ENUM["EnumC0539aa 17种类型"]
        AO["aO 子类实例化"]
    end
    
    JIT --> SVC
    SVC --> PROC
    PROC --> AO
    GOT --> AO
    HASH --> AO
    AO --> OBS
</pre><hr>
<h2 id="1-root检测-enumc0539aam--c0571m">
<a class="header-anchor" href="#1-root%e6%a3%80%e6%b5%8b-enumc0539aam--c0571m"></a>
1. Root检测 (<code>EnumC0539aa.m</code> → <code>C0571m</code>)
</h2><h3 id="native-层-sub_a87f8">
<a class="header-anchor" href="#native-%e5%b1%82-sub_a87f8"></a>
Native 层 (sub_A87F8)
</h3><pre tabindex="0"><code>技术: 读取 /proc/self/mountinfo 检测可疑挂载
1. 通过 SVC 直接 openat() 打开 /mountinfo
2. 扫描挂载点寻找:
   - Magisk overlay 挂载 (tmpfs on /system)
   - /su, /magisk 路径
   - rw 挂载的系统分区 (system/vendor)
3. 检查 AllowedPackagesForRootingCheck protobuf 白名单
</code></pre><h3 id="java-层-rootbeer">
<a class="header-anchor" href="#java-%e5%b1%82-rootbeer"></a>
Java 层 (RootBeer)
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// BOCLFRootUtils.checkRoot() — 10项检测</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectRootManagementApps</span><span class="p">()</span><span class="w">      </span><span class="c1">// Magisk Manager, SuperSU, KingRoot 等包名</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectPotentiallyDangerousApps</span><span class="p">()</span><span class="w"> </span><span class="c1">// BusyBox, Titanium Backup 等</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForBinary</span><span class="p">(</span><span class="s">&#34;su&#34;</span><span class="p">)</span><span class="w">            </span><span class="c1">// PATH 中搜索 su 二进制</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForRWPaths</span><span class="p">()</span><span class="w">               </span><span class="c1">// /system, /vendor 是否 rw 挂载</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectTestKeys</span><span class="p">()</span><span class="w">                </span><span class="c1">// ro.build.tags != release-keys</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkSuExists</span><span class="p">()</span><span class="w">                 </span><span class="c1">// Runtime.exec(&#34;which su&#34;)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">checkForRootNative</span><span class="p">()</span><span class="w">            </span><span class="c1">// Native JNI 检测 (libtool-checker.so)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">rootBeer</span><span class="p">.</span><span class="na">detectRootCloakingApps</span><span class="p">()</span><span class="w">        </span><span class="c1">// RootCloak, Xposed Installer 包名</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p><strong><code>reason=22</code> 解码</strong>: 22 = 二进制 <code>10110</code> → bit4(checkSuExists) + bit2(checkForRWPaths) + bit1(checkForRootNative)</p>
<p><strong>IDA 关键地址</strong>: <code>sub_A87F8</code> (mountinfo解析), protobuf <code>AllowedPackagesForRootingCheck</code> @ <code>0x36808</code></p>
<hr>
<h2 id="2-frida检测-enumc0539aaf--c0562d">
<a class="header-anchor" href="#2-frida%e6%a3%80%e6%b5%8b-enumc0539aaf--c0562d"></a>
2. Frida检测 (<code>EnumC0539aa.f</code> → <code>C0562d</code>)
</h2><h3 id="native-层--jit-svc-代码追踪器">
<a class="header-anchor" href="#native-%e5%b1%82--jit-svc-%e4%bb%a3%e7%a0%81%e8%bf%bd%e8%b8%aa%e5%99%a8"></a>
Native 层 — JIT SVC 代码追踪器
</h3><pre tabindex="0"><code>函数: DoCodetracerDetection (sub_26B680)
技术: 动态生成 ARM 机器码，直接通过 SVC #0 调用内核

1. JIT 生成 openat() SVC 指令 → 打开 /proc/self/maps
2. JIT 生成 read() SVC 指令 → 逐行读取内存映射
3. 在内存中搜索加密后的 Frida 特征:
   - &#34;frida-agent&#34; 共享库映射
   - &#34;frida-gadget&#34; 
   - &#34;linjector&#34; (Frida 注入器线程)
4. JIT 生成 openat() → /proc/[pid]/task/[tid]/status
5. 搜索线程名特征:
   - &#34;frida&#34; (frida-server 线程)
   - &#34;gmain&#34; (GLib main loop - Frida 依赖)
   - &#34;gdbus&#34; (GLib D-Bus - Frida 依赖)
6. 端口扫描: connect() 到 localhost:27042 (Frida 默认端口)

关键: 所有 I/O 使用 SVC 直接系统调用，不经过 libc
      → Frida 的 Interceptor.attach(libc.open) 无法拦截
</code></pre><p><strong>IDA 关键地址</strong>: <code>sub_26B680</code> (DoCodetracerDetection), <code>sub_26BD20</code> (CodetracerDetection), <code>0x3c099</code> (SyscallNo), <code>0x2f91a</code> (OnCodeTracerDetectedCallback)</p>
<hr>
<h2 id="3-调试器检测-enumc0539aab--aq">
<a class="header-anchor" href="#3-%e8%b0%83%e8%af%95%e5%99%a8%e6%a3%80%e6%b5%8b-enumc0539aab--aq"></a>
3. 调试器检测 (<code>EnumC0539aa.b</code> → <code>aQ</code>)
</h2><h3 id="native-层">
<a class="header-anchor" href="#native-%e5%b1%82"></a>
Native 层
</h3><pre tabindex="0"><code>技术:
1. SVC openat(/proc/self/status) → 读取 TracerPid 字段
   - TracerPid != 0 → 有调试器 (ptrace/JDWP)
2. SVC ptrace(PTRACE_TRACEME) → 自我附加
   - 失败 = 已有调试器附加
3. 检查 /proc/self/wchan 是否包含 &#34;ptrace_stop&#34;
4. 定时器反调试: 测量代码执行时间
   - clock_gettime() 差值过大 → 单步调试中
</code></pre><hr>
<h2 id="4-重打包检测-enumc0539aar--c0559au">
<a class="header-anchor" href="#4-%e9%87%8d%e6%89%93%e5%8c%85%e6%a3%80%e6%b5%8b-enumc0539aar--c0559au"></a>
4. 重打包检测 (<code>EnumC0539aa.r</code> → <code>C0559au</code>)
</h2><h3 id="native-层-1">
<a class="header-anchor" href="#native-%e5%b1%82-1"></a>
Native 层
</h3><pre tabindex="0"><code>技术:
1. 读取 APK 签名证书 → 计算 SHA-256 hash
2. 与 protobuf 配置中的预存 hash 比对:
   - promon.pbi.HashedFile (@ 0x42dbf)
   - promon.pbi.FileHashes (@ 0x331d8)
   - promon.pbi.SegmentHashInfo (@ 0x36832)
3. 校验 DEX 文件完整性 (.dex headers + code segments)
4. 验证 native library hash:
   - promon.pbi.HashedShieldLibrary (@ 0x323f2)
   - promon.pbi.HashedShieldLibrary.filename (@ 0x3f019)
</code></pre><hr>
<h2 id="5-hooking-框架检测-enumc0539aai--ay">
<a class="header-anchor" href="#5-hooking-%e6%a1%86%e6%9e%b6%e6%a3%80%e6%b5%8b-enumc0539aai--ay"></a>
5. Hooking 框架检测 (<code>EnumC0539aa.i</code> → <code>ay</code>)
</h2><h3 id="native-层-2">
<a class="header-anchor" href="#native-%e5%b1%82-2"></a>
Native 层
</h3><pre tabindex="0"><code>技术 (ay 存储 bool + 5个字符串 = 框架名/路径/版本/hash/签名):
1. /proc/self/maps 扫描: 搜索 Xposed/Substrate 特征 so 库
   - XposedBridge.jar 内存映射
   - libsubstrate.so / libsubstrate-dvm.so  
   - libart.so 的 inline hook 标记
2. Java ClassLoader 检查:
   - 尝试加载 &#34;de.robv.android.xposed.XposedHelpers&#34;
   - 尝试加载 &#34;de.robv.android.xposed.XposedBridge&#34;
3. 异常栈帧检查: 遍历 StackTrace 寻找 Xposed 类
4. GOT 表验证 (sub_16E2A0):
   - promon.pbi.GotVerifyInfo (@ 0x3243c)
   - 检查 libc/libart 的 GOT 入口是否被修改
   - GOT 指向非原始库地址 = 被 inline hook
</code></pre><p><strong>IDA 关键地址</strong>: <code>sub_16E2A0</code> (GotVerifyInfo 验证), <code>sub_16E764</code> (GOT 二次验证)</p>
<hr>
<h2 id="6-屏幕叠加录屏检测-enumc0539aah--c0573o">
<a class="header-anchor" href="#6-%e5%b1%8f%e5%b9%95%e5%8f%a0%e5%8a%a0%e5%bd%95%e5%b1%8f%e6%a3%80%e6%b5%8b-enumc0539aah--c0573o"></a>
6. 屏幕叠加/录屏检测 (<code>EnumC0539aa.h</code> → <code>C0573o</code>)
</h2><h3 id="native-层--java-代理">
<a class="header-anchor" href="#native-%e5%b1%82--java-%e4%bb%a3%e7%90%86"></a>
Native 层 + Java 代理
</h3><pre tabindex="0"><code>技术:
1. promon.pbi.ScreenMirroringBlock (@ 0x439e7)
   配置 app_block_layout_name 和 landscape 版本
2. 检测前台是否有其他 Activity overlay (FLAG_SECURE)
3. 检测 MediaProjection API 录屏
4. 检测 AccessibilityService 是否在读取屏幕内容
5. 前台 Activity 切换监控:
   - promon.pbi.AllowedActivitiesForScreenshots (@ 0x32411)
   → 白名单外的 Activity 被覆盖时触发
</code></pre><p><strong>IDA 关键地址</strong>: <code>sub_17196C</code> (ScreenMirroringBlock 初始化), <code>sub_171AFC</code> (布局检测)</p>
<hr>
<h2 id="7-代码追踪器检测-enumc0539aaq--ag">
<a class="header-anchor" href="#7-%e4%bb%a3%e7%a0%81%e8%bf%bd%e8%b8%aa%e5%99%a8%e6%a3%80%e6%b5%8b-enumc0539aaq--ag"></a>
7. 代码追踪器检测 (<code>EnumC0539aa.q</code> → <code>aG</code>)
</h2><h3 id="native-层--核心-jit-检测引擎">
<a class="header-anchor" href="#native-%e5%b1%82--%e6%a0%b8%e5%bf%83-jit-%e6%a3%80%e6%b5%8b%e5%bc%95%e6%93%8e"></a>
Native 层 — 核心 JIT 检测引擎
</h3><pre tabindex="0"><code>函数: DoCodetracerDetection (sub_26B680) + CodetracerDetection (sub_26BD20)
技术: 与 Frida 检测共享引擎，但更广泛:

1. 动态 JIT 生成 ARM 指令序列:
   a. MOV R8, #syscall_number (加密)  → 设置系统调用号
   b. SVC #0                         → 触发内核调用
   c. 后续指令处理返回值

2. 生成的系统调用链:
   - openat(AT_FDCWD, &#34;/proc/self/maps&#34;, O_RDONLY)
   - read(fd, buf, size)  → 逐块读取
   - 在 buf 中搜索加密特征字符串
   - close(fd)

3. 注册 OnCodeTracerDetectedCallback (@ 0x2f91a)
   → 检测到异常时通过 pipe 通知 Java 层

4. aG 存储 bool + 5个字符串:
   - 追踪器类型名称
   - 检测位置 (maps/threads/ports)
   - 进程/线程信息
   - 时间戳
   - 详细描述
</code></pre><hr>
<h2 id="8-模拟器检测-enumc0539aan--c0564f">
<a class="header-anchor" href="#8-%e6%a8%a1%e6%8b%9f%e5%99%a8%e6%a3%80%e6%b5%8b-enumc0539aan--c0564f"></a>
8. 模拟器检测 (<code>EnumC0539aa.n</code> → <code>C0564f</code>)
</h2><h3 id="native-层-3">
<a class="header-anchor" href="#native-%e5%b1%82-3"></a>
Native 层
</h3><pre tabindex="0"><code>技术 (C0564f 存储 bool + int模拟器类型码):
1. 系统属性检查 (SVC 读取):
   - ro.hardware: goldfish/ranchu/vbox86
   - ro.product.model: SDK/Emulator/Android SDK built
   - ro.kernel.qemu: 1
   - ro.secure: 0
2. /proc/cpuinfo 特征:
   - Hardware: Goldfish/Ranchu
   - 缺少物理 CPU 特征
3. 传感器检查:
   - 加速度/陀螺仪等传感器数据异常
4. 电池状态: 永远充电/电量不变
5. Build 指纹:
   - Build.FINGERPRINT 包含 &#34;generic&#34;/&#34;sdk&#34;/&#34;test-keys&#34;
   - Build.HARDWARE == &#34;goldfish&#34;
6. Play Integrity API 查询 (新版)
</code></pre><hr>
<h2 id="9-无障碍服务检测-enumc0539aao--ab">
<a class="header-anchor" href="#9-%e6%97%a0%e9%9a%9c%e7%a2%8d%e6%9c%8d%e5%8a%a1%e6%a3%80%e6%b5%8b-enumc0539aao--ab"></a>
9. 无障碍服务检测 (<code>EnumC0539aa.o</code> → <code>aB</code>)
</h2><h3 id="java-层--native-层">
<a class="header-anchor" href="#java-%e5%b1%82--native-%e5%b1%82"></a>
Java 层 + Native 层
</h3><pre tabindex="0"><code>技术 (aB 存储 2×bool: 是否开启 + 是否恶意):
1. AccessibilityManager.getEnabledAccessibilityServiceList()
   - 枚举所有启用的无障碍服务
2. promon.pbi.AllowedActivitiesForScreenreader (@ 0x34796)
   - 白名单比对，非白名单服务 = 可疑
3. 检测是否有服务正在读取 View 树内容
4. 检查 canRetrieveWindowContent 权限
</code></pre><p><strong>IDA 关键地址</strong>: protobuf <code>AllowedActivitiesForScreenreader</code> @ <code>0x34796</code>, xrefs 在 <code>0x42323</code></p>
<hr>
<h2 id="10-篡改检测-enumc0539aag--k">
<a class="header-anchor" href="#10-%e7%af%a1%e6%94%b9%e6%a3%80%e6%b5%8b-enumc0539aag--k"></a>
10. 篡改检测 (<code>EnumC0539aa.g</code> → <code>K</code>)
</h2><h3 id="native-层-4">
<a class="header-anchor" href="#native-%e5%b1%82-4"></a>
Native 层
</h3><pre tabindex="0"><code>技术 (K 存储 str证书hash + 2×bool):
1. APK 签名验证:
   - PackageManager.GET_SIGNING_CERTIFICATES
   - 计算证书 SHA-256 与配置比对
2. DEX 文件 CRC 校验:
   - classes.dex 完整性验证
3. native library 代码段 hash:
   - promon.pbi.SegmentHashInfo (@ 0x36832)
   - .text section hash 比对
4. promon.pbi.LibraryInfo (@ 0x351e2) 验证:
   - soname / filename 比对
   - promon.pbi.LibraryInfos (@ 0x42df2) 列表
</code></pre><hr>
<h2 id="11-虚拟环境检测-enumc0539aal--s">
<a class="header-anchor" href="#11-%e8%99%9a%e6%8b%9f%e7%8e%af%e5%a2%83%e6%a3%80%e6%b5%8b-enumc0539aal--s"></a>
11. 虚拟环境检测 (<code>EnumC0539aa.l</code> → <code>S</code>)
</h2><h3 id="native-层-5">
<a class="header-anchor" href="#native-%e5%b1%82-5"></a>
Native 层
</h3><pre tabindex="0"><code>技术 (S 存储 2×bool, d()=任一触发):
bool[0]: 虚拟空间检测 (VirtualXposed/VirtualApp/太极)
  - 检查 /data/data 下是否有多层嵌套 uid
  - 检测 android.os.Binder.getCallingUid() 异常
  - 扫描 /proc/self/maps 中虚拟框架 so 库

bool[1]: 工作配置文件/容器检测
  - 检测 Android Work Profile 环境
  - 检测三星 Knox / MIUI 分身 等系统级双开
</code></pre><hr>
<h2 id="12-恶意activity检测-enumc0539aak--t">
<a class="header-anchor" href="#12-%e6%81%b6%e6%84%8factivity%e6%a3%80%e6%b5%8b-enumc0539aak--t"></a>
12. 恶意Activity检测 (<code>EnumC0539aa.k</code> → <code>T</code>)
</h2><h3 id="java--native-层">
<a class="header-anchor" href="#java--native-%e5%b1%82"></a>
Java + Native 层
</h3><pre tabindex="0"><code>技术 (T 存储 ComponentName + 2×str):
1. promon.pbi.LaunchActivities (@ 0x351f9) 配置
   - 定义合法的 Launch Activity 列表
   - promon.pbi.LaunchActivity.class_name (@ 0x37c5d)
   - promon.pbi.LaunchActivity.hash (@ 0x39b49)
2. 监控当前前台 Activity 组件名
   - 非白名单 Activity 启动 = 可能被篡改/注入
3. promon.pbi.ConsentActivities 同意弹窗验证
</code></pre><hr>
<h2 id="13-ssl-pinning证书验证-enumc0539aac--c0540ab">
<a class="header-anchor" href="#13-ssl-pinning%e8%af%81%e4%b9%a6%e9%aa%8c%e8%af%81-enumc0539aac--c0540ab"></a>
13. SSL Pinning/证书验证 (<code>EnumC0539aa.c</code> → <code>C0540ab</code>)
</h2><h3 id="native-层-libressl">
<a class="header-anchor" href="#native-%e5%b1%82-libressl"></a>
Native 层 (LibreSSL)
</h3><pre tabindex="0"><code>技术 (C0540ab 存储 bool):
1. 内置 LibreSSL 库 (@ /build/sfs/shield/third_party/libressl/)
   - 不依赖系统 SSL，防止证书替换
2. Trust Root 验证 (@ 0x3cd40):
   - &#34;root ca not trusted&#34; (@ 0x43400) 错误信息
   - setCext-hashedRoot (@ 0x4293e)
3. 证书链验证:
   - set-policy-root (@ 0x401f7)
   - trustRoot (@ 0x37856)
4. 检测证书被用户安装的 CA 替换
   - 抓包工具 (Charles/Fiddler/mitmproxy) 的证书会触发
</code></pre><hr>
<h2 id="14-已安装app扫描-enumc0539aap--c0549ak">
<a class="header-anchor" href="#14-%e5%b7%b2%e5%ae%89%e8%a3%85app%e6%89%ab%e6%8f%8f-enumc0539aap--c0549ak"></a>
14. 已安装App扫描 (<code>EnumC0539aa.p</code> → <code>C0549ak</code>)
</h2><h3 id="java-层-x1b-回调处理">
<a class="header-anchor" href="#java-%e5%b1%82-x1b-%e5%9b%9e%e8%b0%83%e5%a4%84%e7%90%86"></a>
Java 层 (x1.b 回调处理)
</h3><pre tabindex="0"><code>技术 (C0549ak 存储 8字段对象列表):
1. PackageManager.getInstalledApplications() 获取列表
2. 每个App记录 8 个字段:
   - packageName, versionName, sourceDir
   - apkHash (SHA-256), signature, label
   - installTime, flags
3. 与 promon.pbi.ClassIds (@ 0x33afe) 配置黑名单比对
4. 上报到服务器: h2.a.c(&#34;load_unofficial_app_key&#34;)
5. 记为 JSON 包含 uuid + deviceModel + osVersion + unofficialApps
</code></pre><hr>
<h2 id="15-设备完整性检测-enumc0539aad--c0572n">
<a class="header-anchor" href="#15-%e8%ae%be%e5%a4%87%e5%ae%8c%e6%95%b4%e6%80%a7%e6%a3%80%e6%b5%8b-enumc0539aad--c0572n"></a>
15. 设备完整性检测 (<code>EnumC0539aa.d</code> → <code>C0572n</code>)
</h2><h3 id="java--native-层-1">
<a class="header-anchor" href="#java--native-%e5%b1%82-1"></a>
Java + Native 层
</h3><pre tabindex="0"><code>技术 (C0572n 存储 bool):
1. Google Play Integrity API 调用
   - 获取设备完整性令牌
   - 检查 MEETS_DEVICE_INTEGRITY
2. SafetyNet Attestation (旧版回退)
   - ctsProfileMatch + basicIntegrity
3. bootloader 锁定状态检测:
   - ro.boot.verifiedbootstate
   - ro.boot.flash.locked
</code></pre><hr>
<h2 id="16-密钥存储检测-enumc0539aaj--w">
<a class="header-anchor" href="#16-%e5%af%86%e9%92%a5%e5%ad%98%e5%82%a8%e6%a3%80%e6%b5%8b-enumc0539aaj--w"></a>
16. 密钥存储检测 (<code>EnumC0539aa.j</code> → <code>W</code>)
</h2><h3 id="java--native-层-2">
<a class="header-anchor" href="#java--native-%e5%b1%82-2"></a>
Java + Native 层
</h3><pre tabindex="0"><code>技术 (W 存储 bool):
1. Android Keystore 安全检测
   - 检查硬件级 Keystore (TEE/StrongBox)
   - KeyInfo.isInsideSecureHardware()
2. Keymaster/Keymint 版本验证
3. 检测 Magisk 是否 hook 了 Keystore 接口
4. 检测 KeyAttestation 证书链是否被篡改
</code></pre><hr>
<h2 id="17-恶意app哈希匹配-enumc0539aaa--ad">
<a class="header-anchor" href="#17-%e6%81%b6%e6%84%8fapp%e5%93%88%e5%b8%8c%e5%8c%b9%e9%85%8d-enumc0539aaa--ad"></a>
17. 恶意App哈希匹配 (<code>EnumC0539aa.a</code> → <code>aD</code>)
</h2><h3 id="java-层-jtqupujlam--x1b">
<a class="header-anchor" href="#java-%e5%b1%82-jtqupujlam--x1b"></a>
Java 层 (jtqupujl.aM + x1.b)
</h3><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-java" data-lang="java"><span class="line"><span class="cl"><span class="c1">// jtqupujl.aM.a(context, packageManager, list, str)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">技术</span><span class="w"> </span><span class="p">(</span><span class="n">aD</span><span class="w"> </span><span class="n">存储</span><span class="w"> </span><span class="n">5字段对象列表</span><span class="p">):</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">1</span><span class="p">.</span><span class="w"> </span><span class="n">从服务器下载</span><span class="w"> </span><span class="n">malware_applications</span><span class="w"> </span><span class="n">JSON</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="o">-</span><span class="w"> </span><span class="n">包含</span><span class="w"> </span><span class="n">appPackageName</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">apkHashSHA256</span><span class="w"> </span><span class="n">列表</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">2</span><span class="p">.</span><span class="w"> </span><span class="n">PackageManager</span><span class="p">.</span><span class="na">getInstalledApplications</span><span class="p">(</span><span class="n">131072</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="o">-</span><span class="w"> </span><span class="n">过滤系统App</span><span class="w"> </span><span class="p">(</span><span class="n">flags</span><span class="w"> </span><span class="o">&amp;</span><span class="w"> </span><span class="n">FLAG_SYSTEM</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">3</span><span class="p">.</span><span class="w"> </span><span class="n">计算每个非系统App的</span><span class="w"> </span><span class="n">APK</span><span class="w"> </span><span class="n">SHA</span><span class="o">-</span><span class="n">256</span><span class="w"> </span><span class="n">hash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">4</span><span class="p">.</span><span class="w"> </span><span class="n">与服务器下发的</span><span class="w"> </span><span class="n">hash</span><span class="w"> </span><span class="n">列表比对</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">5</span><span class="p">.</span><span class="w"> </span><span class="n">匹配成功</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="n">C0552an</span><span class="w"> </span><span class="n">记录</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="o">-</span><span class="w"> </span><span class="n">packageName</span><span class="p">,</span><span class="w"> </span><span class="n">sourceDir</span><span class="p">,</span><span class="w"> </span><span class="n">label</span><span class="p">,</span><span class="w"> </span><span class="n">versionName</span><span class="p">,</span><span class="w"> </span><span class="n">hash</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">6</span><span class="p">.</span><span class="w"> </span><span class="n">通过</span><span class="w"> </span><span class="n">jtqupujl</span><span class="p">.</span><span class="na">aR</span><span class="p">.</span><span class="na">a</span><span class="p">().</span><span class="na">a</span><span class="p">(</span><span class="n">c0566h</span><span class="p">)</span><span class="w"> </span><span class="n">通知观察者</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="n">7</span><span class="p">.</span><span class="w"> </span><span class="n">MainActivity</span><span class="p">.</span><span class="na">a</span><span class="p">(</span><span class="n">C0566h</span><span class="p">)</span><span class="w"> </span><span class="err">→</span><span class="w"> </span><span class="n">打开</span><span class="w"> </span><span class="n">reason</span><span class="o">=</span><span class="n">50</span><span class="w"> </span><span class="n">URL</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><hr>
<h2 id="native-层核心反检测对抗技术">
<a class="header-anchor" href="#native-%e5%b1%82%e6%a0%b8%e5%bf%83%e5%8f%8d%e6%a3%80%e6%b5%8b%e5%af%b9%e6%8a%97%e6%8a%80%e6%9c%af"></a>
Native 层核心反检测对抗技术
</h2><h3 id="1-jit-svc-引擎-最关键">
<a class="header-anchor" href="#1-jit-svc-%e5%bc%95%e6%93%8e-%e6%9c%80%e5%85%b3%e9%94%ae"></a>
1. JIT SVC 引擎 (最关键)
</h3><pre tabindex="0"><code>sub_26B680 (DoCodetracerDetection):
  动态生成 ARM32 机器码 → 分配可执行内存 → 直接执行
  
生成的指令序列 (重建):
  PUSH {R4-R7,LR}
  MOV R8, #&lt;encrypted_syscall_no&gt;   // openat = 322
  EOR R8, R8, #&lt;key&gt;                // 解密syscall号
  MOV R0, #-100                     // AT_FDCWD
  LDR R1, [PC, #offset]            // 指向加密的路径字符串
  MOV R2, #0                        // O_RDONLY
  SVC #0                            // 直接调用内核!
  ... (read/scan/close)
  
优势: 
  - Frida Interceptor 无法拦截 (不经过 libc)
  - 代码在运行时才生成 (静态分析看不到)
  - SyscallNo 加密存储，每次运行解密
</code></pre><h3 id="2-字符串全加密">
<a class="header-anchor" href="#2-%e5%ad%97%e7%ac%a6%e4%b8%b2%e5%85%a8%e5%8a%a0%e5%af%86"></a>
2. 字符串全加密
</h3><pre tabindex="0"><code>所有敏感字符串 (frida/xposed/su/magisk/com.topjohnwu 等)
在二进制中以加密形式存储，运行时动态解密到栈上
→ IDA strings 搜索找不到任何检测目标名称
</code></pre><h3 id="3-got-完整性验证">
<a class="header-anchor" href="#3-got-%e5%ae%8c%e6%95%b4%e6%80%a7%e9%aa%8c%e8%af%81"></a>
3. GOT 完整性验证
</h3><pre tabindex="0"><code>sub_16E2A0 (GotVerifyInfo):
  1. 记录 libc.so 的 GOT 表地址
  2. 定时扫描 GOT 入口是否被修改
  3. GOT[open] 不指向 libc → 被 hook
  → 检测 PLT hook (LD_PRELOAD/Frida replace)
</code></pre><h3 id="4-41个-protobuf-配置消息">
<a class="header-anchor" href="#4-41%e4%b8%aa-protobuf-%e9%85%8d%e7%bd%ae%e6%b6%88%e6%81%af"></a>
4. 41个 Protobuf 配置消息
</h3><pre tabindex="0"><code>promon.pbi.* 完整列表:
  AllowedPackagesForRootingCheck    → Root检测白名单
  AllowedActivitiesForScreenshots   → 截屏白名单
  AllowedActivitiesForScreenreader  → 无障碍白名单
  ScreenMirroringBlock              → 屏幕叠加阻断
  HashedShieldLibrary / HashedFile  → 文件完整性
  FileHashes / SegmentHashInfo      → 代码段hash
  GotVerifyInfo                     → GOT hook检测
  ClassIds / MemberId               → Java类监控
  LaunchActivities / LaunchActivity → Activity验证
  ConsentActivities                 → 用户同意弹窗
  LibraryInfo / LibraryInfos        → so库验证
  PullBindings / PushBindings       → 绑定配置
  JigsawBlock / EncryptedBlock      → 代码加密分块
  SignedPbiData / UnsignedPbiData   → 签名配置
  Value / Binding                   → 通用绑定
</code></pre>
        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>windows下git中文乱码的解决方案</title>
      <link>https://csdn.fjh1997.top/posts/22358.html</link>
      <pubDate>Mon, 02 Mar 2026 18:04:59 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/22358.html</guid>
      <description>
        <![CDATA[<h1>windows下git中文乱码的解决方案</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>网上查的都没用，因为设置的是让git输出utf-8，而powershell按gbk来读取，无论怎么读都是乱码，如：</p>
<p><img src="/images/20260302180651.png" alt="20260302180651">
所以可以尝试：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="p">[</span><span class="no">System.Console</span><span class="p">]::</span><span class="n">OutputEncoding</span> <span class="p">=</span> <span class="p">[</span><span class="no">System.Text.Encoding</span><span class="p">]::</span><span class="n">UTF8</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样就能读取utf8字符串 ，而chcp 65001则只对cmd生效，对powershell无效，因为powershell内部还有一个处理数据的地方。</p>
<p>下面是永久生效方法：
<strong>1. 开放脚本执行权限（非常重要，很多配置不生效就是因为这个）：</strong>
以<strong>管理员身份</strong>打开一个新的 PowerShell 窗口，运行：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="nb">Set-ExecutionPolicy</span> <span class="n">RemoteSigned</span> <span class="n">-Scope</span> <span class="n">CurrentUser</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>（提示时输入 <code>Y</code> 并回车确认）。</p>
<p><strong>2. 把配置写入启动文件：</strong>
回到你普通的 PowerShell 窗口，依次运行下面两行命令（第一行是确保文件存在，第二行是直接把配置追加到文件末尾）：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(!(</span><span class="nb">Test-Path</span> <span class="n">-Path</span> <span class="nv">$PROFILE</span><span class="p">))</span> <span class="p">{</span> <span class="nb">New-Item</span> <span class="n">-ItemType</span> <span class="n">File</span> <span class="n">-Path</span> <span class="nv">$PROFILE</span> <span class="n">-Force</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">Add-Content</span> <span class="n">-Path</span> <span class="nv">$PROFILE</span> <span class="n">-Value</span> <span class="s1">&#39;[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>3. 验证成果：</strong>
关掉所有 PowerShell 窗口，重新打开一个全新的窗口，输入 <code>git status</code>。</p>

        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>windows上codex插件&#43;vscode配置中转站API参考以及中文乱码还有自动同意策略、管理员权限的解决方案</title>
      <link>https://csdn.fjh1997.top/posts/18834.html</link>
      <pubDate>Mon, 02 Mar 2026 16:54:20 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/18834.html</guid>
      <description>
        <![CDATA[<h1>windows上codex插件+vscode配置中转站API参考以及中文乱码还有自动同意策略、管理员权限的解决方案</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>可以先配置好CLIProxyAPI，代理是在内部proxy-url可以设置<br>
然后在%USERPROFILE%/.codex/config.toml中参考以下配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="nx">model_provider</span> <span class="p">=</span> <span class="s2">&#34;fox&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">model</span> <span class="p">=</span> <span class="s2">&#34;gpt-5.3-codex&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">model_reasoning_effort</span> <span class="p">=</span> <span class="s2">&#34;high&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">features</span><span class="p">.</span><span class="nx">powershell_utf8</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="nx">approval_policy</span> <span class="p">=</span> <span class="s2">&#34;never&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">sandbox_mode</span> <span class="p">=</span> <span class="s2">&#34;danger-full-access&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">windows</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">sandbox</span> <span class="p">=</span> <span class="s2">&#34;elevated&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">model_providers</span><span class="p">.</span><span class="nx">fox</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;fox&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">base_url</span> <span class="p">=</span> <span class="s2">&#34;http://192.168.1.5:8317/v1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">wire_api</span> <span class="p">=</span> <span class="s2">&#34;responses&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">requires_openai_auth</span> <span class="p">=</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">features</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">powershell_utf8</span> <span class="p">=</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">mcp_servers</span><span class="p">.</span><span class="nx">ida-pro-mcp</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">command</span> <span class="p">=</span> <span class="s2">&#34;C:\\Users\\54930\\AppData\\Local\\Programs\\Python\\Python314\\python.exe&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">args</span> <span class="p">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;C:\\Users\\54930\\AppData\\Local\\Programs\\Python\\Python314\\Lib\\site-packages\\ida_pro_mcp\\server.py&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--ida-rpc&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;http://127.0.0.1:13337&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">[</span><span class="nx">mcp_servers</span><span class="p">.</span><span class="nx">jadx_mcp_server</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">command</span> <span class="p">=</span> <span class="s2">&#34;C:\\Users\\54930\\.local\\bin\\uv.exe&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">args</span> <span class="p">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;--directory&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;G:\\\u4E0B\u8F7D\\jadx-mcp-server-v6.1.0\\jadx-mcp-server&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;run&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;jadx_mcp_server.py&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">env</span> <span class="p">=</span> <span class="p">{</span> <span class="nx">PYTHONUTF8</span> <span class="p">=</span> <span class="s2">&#34;1&#34;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="nx">enabled</span> <span class="p">=</span> <span class="kc">true</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>还有%USERPROFILE%/.codex/auth.json</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;OPENAI_API_KEY&#34;</span><span class="p">:</span><span class="s2">&#34;your-api-key-1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意如果有中文路径可能会导致stdio方式我i收的mcp握手失败<code>MCP startup failed: handshaking ... connection closed: initialize response</code>
需要加上<code>env = { PYTHONUTF8 = &quot;1&quot; }</code>参数，不然会导致中文编码乱码问题。<br>
还需要在提示词里面加上，每次使用powershell之前要$PSDefaultParameterValues[&lsquo;Get-Content:Encoding&rsquo;] = &lsquo;UTF8&rsquo;，不然Get-Content也可能会乱码。
也可以在powershell的profile里面配置：</p>
<pre tabindex="0"><code>code $PROFILE
$PSDefaultParameterValues[&#39;Get-Content:Encoding&#39;] = &#39;utf8&#39;
</code></pre><p>加了approval_policy = &ldquo;never&quot;之后可以避免烦人的同意按钮。</p>
<pre tabindex="0"><code>sandbox_mode = &#34;danger-full-access&#34;  
[windows]
sandbox = &#34;elevated&#34;
</code></pre><p>加上可以让codex用管理员身份启动</p>
<pre tabindex="0"><code>[features]
powershell_utf8 = false
</code></pre><p>这一行最好也加上不然容易乱码</p>
<p>测试脚本如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">tomllib</span><span class="o">,</span> <span class="nn">pathlib</span><span class="o">,</span> <span class="nn">subprocess</span><span class="o">,</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl"><span class="n">cfg</span> <span class="o">=</span> <span class="n">pathlib</span><span class="o">.</span><span class="n">Path</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;C:\Users\54930\.codex\config.toml&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">d</span> <span class="o">=</span> <span class="n">tomllib</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">read_text</span><span class="p">(</span><span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="n">j</span> <span class="o">=</span> <span class="n">d</span><span class="p">[</span><span class="s1">&#39;mcp_servers&#39;</span><span class="p">][</span><span class="s1">&#39;jadx_mcp_server&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="n">cmd</span> <span class="o">=</span> <span class="p">[</span><span class="n">j</span><span class="p">[</span><span class="s1">&#39;command&#39;</span><span class="p">],</span> <span class="o">*</span><span class="n">j</span><span class="p">[</span><span class="s1">&#39;args&#39;</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="n">p</span> <span class="o">=</span> <span class="n">subprocess</span><span class="o">.</span><span class="n">Popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">stdin</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stdout</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">,</span> <span class="n">stderr</span><span class="o">=</span><span class="n">subprocess</span><span class="o">.</span><span class="n">PIPE</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">1.0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">chunk</span> <span class="o">=</span> <span class="n">p</span><span class="o">.</span><span class="n">stderr</span><span class="o">.</span><span class="n">peek</span><span class="p">(</span><span class="mi">256</span><span class="p">)[:</span><span class="mi">256</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;stderr_chunk_len=&#39;</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">chunk</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">chunk</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">,</span><span class="s1">&#39;strict&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;stderr_utf8_strict=OK&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="nb">print</span><span class="p">(</span><span class="s1">&#39;stderr_utf8_strict=FAIL&#39;</span><span class="p">,</span> <span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span> <span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="k">finally</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">p</span><span class="o">.</span><span class="n">terminate</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="k">try</span><span class="p">:</span> <span class="n">p</span><span class="o">.</span><span class="n">wait</span><span class="p">(</span><span class="n">timeout</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">except</span><span class="p">:</span> <span class="k">pass</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>另外Codex的历史记录会在C:\Users\54930.codex\sessions\2026\03\02*.jsonl这个里面</p>

        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>apt设置代理的简易方法</title>
      <link>https://csdn.fjh1997.top/posts/42401.html</link>
      <pubDate>Mon, 02 Mar 2026 10:22:46 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/42401.html</guid>
      <description>
        <![CDATA[<h1>apt设置代理的简易方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>apt设置代理，网上的方法都太复杂，实际上只要用环境变量即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">http_proxy</span><span class="o">=</span>http://127.0.0.1:10808
</span></span><span class="line"><span class="cl"><span class="nb">export</span> <span class="nv">https_proxy</span><span class="o">=</span>http://127.0.0.1:10808
</span></span></code></pre></td></tr></table>
</div>
</div><p>但是设置完不生效是为什么呢，因为apt往往要加sudo运行，而sudo会把之前的环境变量给重置掉。<br>
所以只要让sudo不重置，即可，那就是使用<code>sudo -E</code>即可</p>
<pre tabindex="0"><code>sudo -E apt update
</code></pre>
        
        <hr><p>本文2026-03-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-03-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>安卓导出内核崩溃日志</title>
      <link>https://csdn.fjh1997.top/posts/25235.html</link>
      <pubDate>Fri, 27 Feb 2026 17:18:27 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/25235.html</guid>
      <description>
        <![CDATA[<h1>安卓导出内核崩溃日志</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>在kernelsu开发过程中但往往会导致内核崩溃，需要导出内核日志进行分析，目前试了下设备树编译pstore无效，之后发现高通的QPST可以解决这个问题：<br>
我是一加手机，输入*#800#可以进入如下界面：<br>
<img src="/images/Screenshot_2026-02-27-17-16-22-95_fa8ac6a9881a1f9f70c31a31fb1c2162.jpg" alt=""><br>
里面需要配置dump：<br>
<img src="/images/Screenshot_2026-02-27-17-16-51-12_fa8ac6a9881a1f9f70c31a31fb1c2162.jpg" alt=""><br>
之后手机内核如果崩溃会进入这个界面：
Qualcomm Crashdump Mode<br>
<img src="/images/clipboard_2026-02-27_17-47.png" alt="clipboard_2026-02-27_17-47"><br>
保持页面，下载高通驱动重启，</p>
<p>1.安装 <a href="https://qcomdriver.com/" target="_blank" rel="noopener noreferrer nofollow">https://qcomdriver.com/</a>
 — 设备会显示为 Qualcomm HS-USB Diagnostics 900E
2.安装 <a href="https://qpsttool.com/qpst-tool-v2-7-496" target="_blank" rel="noopener noreferrer nofollow">QPST tool</a>

3.打开 QPST Configuration，会自动dump内存，之后只要在QPST Configuration中用Vscode打开日志即可：
<img src="/images/20260227174337.png" alt="20260227174337">
<img src="/images/20260227173456.png" alt="20260227173456"><br>
<img src="/images/20260227173534.png" alt="20260227173534"></p>

        
        <hr><p>本文2026-02-27首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-27</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用bettercap破解wifi密码</title>
      <link>https://csdn.fjh1997.top/posts/59406.html</link>
      <pubDate>Tue, 24 Feb 2026 19:03:33 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/59406.html</guid>
      <description>
        <![CDATA[<h1>使用bettercap破解wifi密码</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>最近过年回爷爷家，发现爷爷家有一个特殊的USB无线网卡Tenda U6和COMFAST CF-952AX v2，淘宝上都很便宜，还有一个奋威 Fenvi FU-AX1800  是MT7921<br>
想起了以前上学时候使用这种USB无线网卡破wifi的经历，就尝试了一下：<br>
破解wifi的网卡最重要的是驱动是否支持，可以去<a href="https://github.com/morrownr/USB-WiFi/blob/main/home/Recommended_Adapters_for_Kali_Linux.md" target="_blank" rel="noopener noreferrer nofollow">这里</a>
查询<br>
如果支持了，可以使用Bettercap进行破解，需要注意这几个问题：<br>
1.操作系统内核版本，如果是COMFAST CF-952AX v2用的是RTL8852BU需要满足linux内核在6.17以上.奋威AX1800则需要满足内核6.12（含6.12）以下，6.13开始会有<a href="https://github.com/morrownr/USB-WiFi/issues/687" target="_blank" rel="noopener noreferrer nofollow">bug</a>
抓不到管理帧Beacon<br>
2.操作系统是否开启了WEXT支持，可以用<code>grep -i wext /boot/config-$(uname -r) </code>查看，如果提示 <code>CONFIG_CFG80211_WEXT is not set</code>则iwlist用不了，需要使用<a href="https://github.com/bettercap/bettercap/pull/1248" target="_blank" rel="noopener noreferrer nofollow">patch过的版本</a>
来使用NL80211协议的iw（我和作者battle不过QAQ）<br>
解决以上问题之后，在虚拟机里面透传usb无线网卡，我是mac用的vmware Fusion。并使用源码编译的方式安装Bettercap：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">git clone https://github.com/bettercap/bettercap.git
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> bettercap
</span></span><span class="line"><span class="cl">make install
</span></span></code></pre></td></tr></table>
</div>
</div><p>之后使用命令开启webui:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"> bettercap -eval <span class="s2">&#34;set ui.address 0.0.0.0;set api.rest.address 0.0.0.0 ;ui on&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>在webui里面可以开启wifi模块，当你看到wifi模块里面某个wifi有几个红色的client的时候：<br>
<img src="/images/20260224194242.png" alt="20260224194242"><br>
记住他的信道，在这里输入：</p>
<pre tabindex="0"><code>wifi.recon.channel 11
</code></pre><p><img src="/images/20260224194405.png" alt="20260224194405"><br>
之后可以使用deauth攻击等着嗅探出握手包.<br>
需要注意的是，wifi网卡一次只能监听一个信道，所以一开始的界面是轮流监听信道，可能抓到的握手包不完整，只能当扫描器使用，真正的嗅探握手包还是需要指定信道的。 <br>
<img src="/images/20260224194520.png" alt="20260224194520"><br>
如果抓到握手包了就可以看到一把钥匙，这个就是抓包文件：<br>
<img src="/images/20260224194613.png" alt="20260224194613"><br>
之后使用hcxpcapngtool即可导出让hashcat破解,这个工具也需要<a href="https://github.com/ZerBea/hcxtools" target="_blank" rel="noopener noreferrer nofollow">编译安装</a>
：</p>
<pre tabindex="0"><code>hcxpcapngtool bettercap-wifi-handshakes.pcap -o keyfile
</code></pre><p>里面的EAPOL pairs(best)就是成功的导出数量：</p>
<pre tabindex="0"><code>EAPOL pairs (total)......................: 32
EAPOL pairs (best).......................: 3
</code></pre><p>之后使用hashcat即可破解，需要用好一点的显卡：</p>
<pre tabindex="0"><code>.\hashcat.exe -m 22000 -a 3 .\keyfile ?d?d?d?d?d?d?d?d
</code></pre><p>或者字典攻击，可以使用<a href="https://github.com/danielmiessler/SecLists/blob/master/Passwords/WiFi-WPA/probable-v2-wpa-top447.txt" target="_blank" rel="noopener noreferrer nofollow">seclist</a>
：</p>
<pre tabindex="0"><code>.\hashcat.exe -m 22000 -a 0 .\keyfile .\probable-v2-wpa-top4800.txt
</code></pre><p>总的来说这个工具比aircrack-ng好用。赞一个。除此之外，你也可以尝试使用命令<code>wifi.deauth all</code>或者<code>wifi.assoc all</code>来批量发送deauth攻击和pmkid攻击，锁定信道效果更佳，需要注意的是可能有假阳性存在，可以看<a href="https://github.com/bettercap/bettercap/pull/1249" target="_blank" rel="noopener noreferrer nofollow">我这个pr</a>
</p>
<p>顺带一提我在mac上跑Fedora 43，运行aireplay-ng的时候提示Couldn&rsquo;t determine current channel for wlan0mon, you should either force the operation with &ndash;ignore-negative-one or apply a kernel patch.，这就是WEXT兼容性的问题，需要<a href="https://github.com/aircrack-ng/aircrack-ng/pull/2702" target="_blank" rel="noopener noreferrer nofollow">我这个补丁</a>
来解决。</p>

        
        <hr><p>本文2026-02-24首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-24</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用caddy签发ip证书</title>
      <link>https://csdn.fjh1997.top/posts/52007.html</link>
      <pubDate>Wed, 18 Feb 2026 11:56:45 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/52007.html</guid>
      <description>
        <![CDATA[<h1>使用caddy签发ip证书</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>使用SSL证书可以确保网页的安全性，但是往往需要一个域名才能签发，之前能白嫖ip6.arpa域名，但是根据Ballot SC-086v3已经下架了。目前我们如果有公网ip可以用lets encrypt签发证书，时间只有几天，但使用caddy可以自动续期，配置文件如下：</p>
<pre tabindex="0"><code># HTTPS site (existing)
123.123.123.123 {
	tls {
		issuer acme {
			dir https://acme-v02.api.letsencrypt.org/directory
			profile shortlived
		}
	}



	handle {
		reverse_proxy localhost:80
	}
}
</code></pre>
        
        <hr><p>本文2026-02-18首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-18</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>记一次奇怪的ssh公钥登录失败的情况</title>
      <link>https://csdn.fjh1997.top/posts/57831.html</link>
      <pubDate>Sun, 15 Feb 2026 10:40:13 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/57831.html</guid>
      <description>
        <![CDATA[<h1>记一次奇怪的ssh公钥登录失败的情况</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>配置了公钥之后提示登录失败，于是开启了-vvv模式，提示：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">debug1: Offering public key: /Users/jihanfu/.ssh/id_rsa RSA SHA256:HYJ/2VQ9GbMqG8KZAHfuNlcU+j8qWeQSTi+NEZFR1Tw
</span></span><span class="line"><span class="cl">debug3: send packet: <span class="nb">type</span> <span class="m">50</span>
</span></span><span class="line"><span class="cl">debug2: we sent a publickey packet, <span class="nb">wait</span> <span class="k">for</span> reply
</span></span><span class="line"><span class="cl">debug3: receive packet: <span class="nb">type</span> <span class="m">51</span>
</span></span><span class="line"><span class="cl">debug1: Authentications that can <span class="k">continue</span>: publickey,password
</span></span><span class="line"><span class="cl">debug1: Trying private key: /Users/jihanfu/.ssh/id_ecdsa
</span></span><span class="line"><span class="cl">debug3: no such identity: /Users/jihanfu/.ssh/id_ecdsa: No such file or directory
</span></span><span class="line"><span class="cl">debug1: Trying private key: /Users/jihanfu/.ssh/id_ecdsa_sk
</span></span><span class="line"><span class="cl">debug3: no such identity: /Users/jihanfu/.ssh/id_ecdsa_sk: No such file or directory
</span></span></code></pre></td></tr></table>
</div>
</div><p>注意到中间receive packet: type 51，收到了51，代表不接受我发送的公钥的指纹，然后我使用命令检查了一下我的私钥派生的公钥</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">➜  CSDN git:<span class="o">(</span>main<span class="o">)</span> ✗ ssh-keygen -y -f ~/.ssh/id_rsa
</span></span><span class="line"><span class="cl">ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCzNv9/IPwLbklJEJWdCGKPSOb/2ePExmC6/lXN2Zj+4ZcEc3hupGRB0CU736moTlDN0A8DmEHmjRnKybA4yA7uNPYLp3
</span></span></code></pre></td></tr></table>
</div>
</div><p>居然和linux上面的~/.ssh/authorized_keys里面的内容时一样的，这就很奇怪了。公钥明明正确但不接受。
之后去问了一下gemini，gemini建议我检查一下指纹，于是我检查了一下指纹。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"> CSDN git:<span class="o">(</span>main<span class="o">)</span> ✗ ssh-keygen -l -f &lt;<span class="o">(</span>ssh-keygen -yf ~/.ssh/id_rsa <span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="m">3072</span> SHA256:BrDxupUTSNIgnoX+lIpuOVoqr4K4sqL3LniG4cDImAc jihanfu@jihandeMacBook-Pro.local <span class="o">(</span>RSA<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>发现指纹不匹配。BrDxupUTSNIgnoX+lIpuOVoqr4K4sqL3LniG4cDImAc，但我实际发送的是HYJ/2VQ9GbMqG8KZAHfuNlcU+j8qWeQSTi+NEZFR1Tw.
之后再次问了gemini，得到一个可能性，虽然日志里面写的是读取公钥文件 Offering public key: /Users/jihanfu/.ssh/id_rsa.
但实际上读的是/Users/jihanfu/.ssh/id_rsa.pub.
之后检查了一下id_rsa.pub，果然：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">➜  CSDN git:<span class="o">(</span>main<span class="o">)</span> ✗ ssh-keygen -l -f ~/.ssh/id_rsa.pub
</span></span><span class="line"><span class="cl"><span class="m">3072</span> SHA256:HYJ/2VQ9GbMqG8KZAHfuNlcU+j8qWeQSTi+NEZFR1Tw jihanfu@jihandeMacBook-Pro.local <span class="o">(</span>RSA<span class="o">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>这里的指纹和发送过去的对的上，所以说ssh的日志本身具有误导性，ssh在有id_rsa.pub的时候会读id_rsa.pub，没有的时候会从id_rsa文件派生。
而这个id_rsa.pub文件因为错误配置导致和id_rsa文件匹配不上了。
因此删除不一样的id_rsa.pub之后果然即可成功登录。</p>

        
        <hr><p>本文2026-02-15首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-15</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>openclaw开启bash命令执行实现RCE</title>
      <link>https://csdn.fjh1997.top/posts/45249.html</link>
      <pubDate>Thu, 12 Feb 2026 21:15:14 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/45249.html</guid>
      <description>
        <![CDATA[<h1>openclaw开启bash命令执行实现RCE</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>在渗透测试演习中，一旦入侵了openclaw（如<a href="https://github.com/fjh1997/BruteClaw" target="_blank" rel="noopener noreferrer">爆破token</a>
）之后该怎么远程执行命令呢？其实不用想办法和大模型玩越狱。直接修改这几处即可：<br>
主要修改两处：
<img src="/images/20260212211558.png" alt="20260212211558">
这里enable<br>
<img src="/images/20260212211627.png" alt="20260212211627"><br>
这里不光需要enable还需要设置webchat与通配符<br>
<img src="/images/20260212211907.png" alt="20260212211907">
之后使用/bash 命令即可执行程序。<br>
本文仅供安全研究使用，请勿违法使用。</p>

        
        <hr><p>本文2026-02-12首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-12</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>office里面你所在的区域不支持Copilot的解决方法</title>
      <link>https://csdn.fjh1997.top/posts/40329.html</link>
      <pubDate>Tue, 10 Feb 2026 00:01:30 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/40329.html</guid>
      <description>
        <![CDATA[<h1>office里面你所在的区域不支持Copilot的解决方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>最近了一年office 365的<a href="https://www.nodeseek.com/post-589290-1" target="_blank" rel="noopener noreferrer nofollow">羊毛</a>
,想试用copilot的时候遇到这个问题：<br>
<img src="/images/7a17103e89cc7a2e6d4eb65d8b0c2436.png" alt="7a17103e89cc7a2e6d4eb65d8b0c2436"><br>
梯子开了美国全局tun也没用，之后怀疑是缓存问题，因为一开始没开梯子导致加载了中国区的js文件，所以没法用<br>
用<a href="https://learn.microsoft.com/zh-cn/office/dev/add-ins/testing/clear-cache" target="_blank" rel="noopener noreferrer nofollow">微软官方网站</a>
上的方法试了下清缓存：<br>
删除以下文件夹的内容</p>
<pre tabindex="0"><code>%LOCALAPPDATA%\Microsoft\Office\16.0\Wef\
</code></pre><p>之后保持美国全局tun重启word即可：<br>
<img src="/images/20260210000843.png" alt="20260210000843">
如果还是不行，可以尝试office 365的网页版，也能用Copilot</p>

        
        <hr><p>本文2026-02-10首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-02-10</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>解决浙江省专业技术人才管理服务系统出现你的连接不是专用连接或者403Forbidden HTTP Proxy的问题</title>
      <link>https://csdn.fjh1997.top/posts/27888.html</link>
      <pubDate>Fri, 23 Jan 2026 21:13:19 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/27888.html</guid>
      <description>
        <![CDATA[<h1>解决浙江省专业技术人才管理服务系统出现你的连接不是专用连接或者403Forbidden HTTP Proxy的问题</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>一开始出现了这样的问题<br>
<img src="/images/20260123211452.png" alt="20260123211452"><br>
点击高级之后出现<br>
<img src="/images/20260123211528.png" alt="20260123211528"><br>
点进去之后<br>
<img src="/images/20260123211408.png" alt="20260123211408"><br>
通过分析网络数据包发现ip地址是：<br>
<img src="/images/20260123211748.png" alt="20260123211748"><br>
也就是<br>
[2409:8728:cff:2038::1:2]:443<br>
之后去itdog看了一下<br>
<img src="/images/20260123211908.png" alt="20260123211908"><br>
发现只有10.13%解析到这个ip地址<br>
<img src="/images/20260123212052.png" alt="20260123212052"><br>
而这些ip地址恰好全是国外DNS解析的。<br>
尝试修改系统的DNS为国内的，无效，之后在浏览器设置里面发现了一个开关：<br>
<img src="/images/20260123212144.png" alt="20260123212144"><br>
把这个开关关掉，不使用安全DNS，这样就不会用国外的DNS解析了。毕竟安全DNS和系统内置DNS不一样走的是HTTPS协议，连的国外服务器。</p>

        
        <hr><p>本文2026-01-23首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-01-23</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>记录EPIC-game出现AS-3错误问题的排查</title>
      <link>https://csdn.fjh1997.top/posts/13165.html</link>
      <pubDate>Tue, 13 Jan 2026 21:18:18 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/13165.html</guid>
      <description>
        <![CDATA[<h1>记录EPIC-game出现AS-3错误问题的排查</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>登录的时候出现了这个问题，使用雷神加速器还是不行，查看了下日志，发现如下问题：</p>
<pre tabindex="0"><code>[2026.01.13-12.05.45:338][  0]LogOnlineIdentity: OSS: Sending Login request. url=https://account-public-service-prod03.ol.epicgames.com/account, type=refresh, id=[REDACTED]
[2026.01.13-12.05.45:349][  0]LogInit: Using libcurl 7.55.1-DEV
[2026.01.13-12.05.45:349][  0]LogInit:  - built for x86_64-pc-win32
[2026.01.13-12.05.45:350][  0]LogInit:  - supports SSL with OpenSSL/1.1.1
[2026.01.13-12.05.45:350][  0]LogInit:  - supports HTTP deflate (compression) using libz 1.2.8
[2026.01.13-12.05.45:350][  0]LogInit:  - other features:
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_SSL
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_LIBZ
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_IPV6
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_ASYNCHDNS
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_LARGEFILE
[2026.01.13-12.05.45:350][  0]LogInit:      CURL_VERSION_IDN
[2026.01.13-12.05.45:350][  0]LogInit:  CurlRequestOptions (configurable via config and command line):
[2026.01.13-12.05.45:350][  0]LogInit:  - bVerifyPeer = true  - Libcurl will verify peer certificate
[2026.01.13-12.05.45:350][  0]LogInit:  - bUseHttpProxy = true  - Libcurl will use HTTP proxy
[2026.01.13-12.05.45:350][  0]LogInit:  - HttpProxyAddress = &#39;127.0.0.1:52345&#39;
[2026.01.13-12.05.45:350][  0]LogInit:  - bDontReuseConnections = false  - Libcurl will reuse connections
[2026.01.13-12.05.45:350][  0]LogInit:  - MaxHostConnections = 0  - Libcurl will NOT limit the number of connections to a host
[2026.01.13-12.05.45:350][  0]LogInit:  - LocalHostAddr = Default
[2026.01.13-12.05.45:350][  0]LogInit:  - BufferSize = 524288
[2026.01.13-12.07.11:083][924]LogOnline: Warning: OSS: https://launcher-public-service-prod06.ol.epicgames.com/launcher/api/public/assets/v2/platform/Windows/launcher?label=Live-HighlandWarrior&amp;clientVersion=17.2.0-38549760%2B%2B%2BPortal%2BRelease-Live-Windows&amp;machineId=44bfe7a8465be3cf51b9abb69b28456a
[2026.01.13-12.07.11:083][924]LogOnline: Warning: OSS: Response:
[2026.01.13-12.07.11:083][924]LogOnline: Warning: OSS: 连接服务器失败。
[2026.01.13-12.07.11:083][924]LogInit: AllCheckComplete SelfUpdate=0 SignedIn=0 RequiresRestart=0
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: invalid HTTP response code received. URL: https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token, HTTP code: 0, content length: 0, actual payload size: 0
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: request failed, libcurl error: 35 (SSL connect error)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 0 (Found bundle for host account-public-service-prod03.ol.epicgames.com: 0x1d774b4fc40 [serially])
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 1 (Hostname 127.0.0.1 was found in DNS cache)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 2 (  Trying 127.0.0.1...)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 3 (TCP_NODELAY set)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 4 (Connected to 127.0.0.1 (127.0.0.1) port 52345 (#4))
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 5 (allocate connect buffer!)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 6 (Establish HTTP proxy tunnel to account-public-service-prod03.ol.epicgames.com:443)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 7 (Proxy replied OK to CONNECT request)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 8 (CONNECT phase completed!)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 9 (ALPN, offering http/1.1)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 10 (Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 11 (TLSv1.3 (OUT), TLS handshake, Client hello (1):)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 12 (CONNECT phase completed!)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 13 (CONNECT phase completed!)
[2026.01.13-12.07.12:820][976]LogHttp: Warning: 000001D76E82EDC0: libcurl info message cache 14 (OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to account-public-service-prod03.ol.epicgames.com:443 )
</code></pre><p>很明显是libcurl走代理了目标地址是127.0.0.1:52345，但是系统里面又没有设置全局的系统代理，之后使用netstat查了一下发现是xray.exe在监听。
<img src="/images/20260113212448.png" alt="20260113212448">
通过排查发现是v2raya服务启动的，关掉这个之后就能正常连通了，虽然没找到v2raya是在哪里修改libcurl的代理的。</p>

        
        <hr><p>本文2026-01-13首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-01-13</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>迁移csdn到hexo</title>
      <link>https://csdn.fjh1997.top/posts/14575.html</link>
      <pubDate>Mon, 05 Jan 2026 13:26:46 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/14575.html</guid>
      <description>
        <![CDATA[<h1>迁移csdn到hexo</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>虽然csdn的markdown编辑器很好用，但是我的部分文章被设置为VIP可见了，背离了我分享知识的初衷，导致我不得不迁移。
使用我的脚本即可：
<a href="https://github.com/fjh1997/csdn2md" target="_blank" rel="noopener noreferrer">https://github.com/fjh1997/csdn2md</a>

或者其他人的脚本我感觉也不错：
<a href="https://github.com/Kalzncc/Csdn2Local" target="_blank" rel="noopener noreferrer nofollow">https://github.com/Kalzncc/Csdn2Local</a>

我的脚本的使用方法是点击编辑文章之后打开开发人员工具在里面把请求包复制到curl
<img src="/images/8eb7c926505a4208aa9ac662db634e7d.png" alt="在这里插入图片描述">
之后使用<a href="https://curlconverter.com/" target="_blank" rel="noopener noreferrer nofollow">curl2python</a>
转换即可，用转换后得到的头修改我的脚本。
<img src="/images/760c6b584de44961b88777ceab7d2a8f.png" alt="在这里插入图片描述"></p>

        
        <hr><p>本文2026-01-05首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2026-01-05</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>使用wireguard搭建校园网VPN</title>
      <link>https://csdn.fjh1997.top/posts/33122.html</link>
      <pubDate>Wed, 31 Dec 2025 14:52:23 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/33122.html</guid>
      <description>
        <![CDATA[<h1>使用wireguard搭建校园网VPN</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p><br>目前遇到两种场景：
<br>逻辑是：
<br>电脑 C （wireguard客户端） ———&gt;服务器 A (wireguard服务端) ———&gt;服务器 B（wireguard linux客户端） ———&gt;校园网内网资源。
<br>电脑 C （wireguard客户端） ———&gt;服务器 A (wireguard服务端) ———&gt;电脑 B（wireguard windows客户端） ———&gt;校园网内网资源。</p>
<p><br>比如内网网段是 10.0.0.0/8，wireguard网段是10.7.0.0/24</p>
<h2 id="1安装wireguard">
<a class="header-anchor" href="#1%e5%ae%89%e8%a3%85wireguard"></a>
1.安装wireguard
</h2><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wget -O wireguard.sh https://get.vpnsetup.net/wg
</span></span><span class="line"><span class="cl">sudo bash wireguard.sh --auto
</span></span></code></pre></td></tr></table>
</div>
</div><p>生成客户端，一个客户端生成一次，拷贝json文件到客户端
参考：
<a href="https://github.com/hwdsl2/wireguard-install/blob/master/README-zh.md" target="_blank" rel="noopener noreferrer nofollow">https://github.com/hwdsl2/wireguard-install/blob/master/README-zh.md</a>
</p>
<h2 id="2配置allow-ip">
<a class="header-anchor" href="#2%e9%85%8d%e7%bd%aeallow-ip"></a>
2.配置allow-ip
</h2><p>给你的所有客户端里面的allowip改为</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">AllowedIPs</span> <span class="o">=</span> 10.7.0.0/24, 10.0.0.0/8
</span></span></code></pre></td></tr></table>
</div>
</div><p>给把你的跳板客户端的allowip改为</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">AllowedIPs</span> <span class="o">=</span> 10.7.0.0/24
</span></span></code></pre></td></tr></table>
</div>
</div><p>服务端里面，找到你想要作为nat跳板的peer的allowip改为</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">AllowedIPs</span> <span class="o">=</span> 10.7.0.0/24, 10.0.0.0/8
</span></span></code></pre></td></tr></table>
</div>
</div><p>表示10.0.0.0/8使用这个节点</p>
<h2 id="场景一设置校园网内linux-nat">
<a class="header-anchor" href="#%e5%9c%ba%e6%99%af%e4%b8%80%e8%ae%be%e7%bd%ae%e6%a0%a1%e5%9b%ad%e7%bd%91%e5%86%85linux-nat"></a>
(场景一)设置校园网内Linux Nat
</h2><p>开启内核转发</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">echo</span> <span class="s2">&#34;net.ipv4.ip_forward = 1&#34;</span> <span class="p">|</span> sudo tee -a /etc/sysctl.conf
</span></span><span class="line"><span class="cl">sudo sysctl -p
</span></span></code></pre></td></tr></table>
</div>
</div><p>将客户端配置文件改成如下格式，其中eth0改为你自己的网口</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="o">[</span>Interface<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nv">Address</span> <span class="o">=</span> 10.7.0.2/24
</span></span><span class="line"><span class="cl"><span class="nv">PrivateKey</span> <span class="o">=</span> <span class="o">[</span>服务器B的私钥<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 核心：开启转发和 NAT，让电脑 C 能访问内网其他机器</span>
</span></span><span class="line"><span class="cl"><span class="nv">PostUp</span> <span class="o">=</span> iptables -A FORWARD -i wg0 -j ACCEPT<span class="p">;</span> iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
</span></span><span class="line"><span class="cl"><span class="nv">PostDown</span> <span class="o">=</span> iptables -D FORWARD -i wg0 -j ACCEPT<span class="p">;</span> iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span>Peer<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nv">PublicKey</span> <span class="o">=</span> <span class="o">[</span>公钥<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nv">PresharedKey</span> <span class="o">=</span> <span class="o">[</span>公钥<span class="o">]</span>
</span></span><span class="line"><span class="cl"><span class="nv">Endpoint</span> <span class="o">=</span> 221.12.18.205:51820
</span></span><span class="line"><span class="cl"><span class="c1"># 这里设置 VPN 内部全段</span>
</span></span><span class="line"><span class="cl"><span class="nv">AllowedIPs</span> <span class="o">=</span> 10.7.0.0/24
</span></span><span class="line"><span class="cl"><span class="nv">PersistentKeepalive</span> <span class="o">=</span> <span class="m">25</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>之后把文件放到/etc/wireguard/wg0.conf这里
使用命令：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">wg-quick up wg0
</span></span></code></pre></td></tr></table>
</div>
</div><p>启动该配置文件</p>
<h2 id="场景二设置校园网内windows-nat注意不是开启路由转发开启路由转发需要本地路由器支持">
<a class="header-anchor" href="#%e5%9c%ba%e6%99%af%e4%ba%8c%e8%ae%be%e7%bd%ae%e6%a0%a1%e5%9b%ad%e7%bd%91%e5%86%85windows-nat%e6%b3%a8%e6%84%8f%e4%b8%8d%e6%98%af%e5%bc%80%e5%90%af%e8%b7%af%e7%94%b1%e8%bd%ac%e5%8f%91%e5%bc%80%e5%90%af%e8%b7%af%e7%94%b1%e8%bd%ac%e5%8f%91%e9%9c%80%e8%a6%81%e6%9c%ac%e5%9c%b0%e8%b7%af%e7%94%b1%e5%99%a8%e6%94%af%e6%8c%81"></a>
(场景二)设置校园网内windows NAT，注意，不是开启路由转发，开启路由转发需要本地路由器支持
</h2><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span><span class="lnt">9
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># 首先，找到你要设置的网卡的 InterfaceIndex，例如这里是 wg_server </span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-NetAdapter</span>
</span></span><span class="line"><span class="cl"><span class="c"># 给网卡 wg_server 设置 IP 如果没有需要分配ip，因为前面已经有ip了所以不用</span>
</span></span><span class="line"><span class="cl"><span class="c"># New-NetIPAddress -IPAddress 172.22.0.1 -PrefixLength 24 -InterfaceIndex 68 # 68 是我的 wg_server 的 InterfaceIndex</span>
</span></span><span class="line"><span class="cl"><span class="c"># 添加 NAT</span>
</span></span><span class="line"><span class="cl"><span class="c"># Name: 设置 NAT的名称，随便起，我这里是 wgservernat。</span>
</span></span><span class="line"><span class="cl"><span class="c"># InternalIPInterfaceAddressPrefix: CIDR</span>
</span></span><span class="line"><span class="cl"><span class="nb">New-NetNat</span> <span class="n">-Name</span> <span class="n">wgservernat</span> <span class="n">-InternalIPInterfaceAddressPrefix</span> <span class="mf">10.7</span><span class="p">.</span><span class="py">0</span><span class="p">.</span><span class="mf">0</span><span class="p">/</span><span class="mf">24</span>
</span></span><span class="line"><span class="cl"><span class="nb">Get-NetNat</span> 
</span></span></code></pre></td></tr></table>
</div>
</div><p><br>也可以用这个：https://github.com/micahmo/WgServerforWindows
<br>参考：https://kenvix.com/post/setup-nat-on-windows/</p>

        
        <hr><p>本文2025-12-31首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-12-31</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>用python模拟的MultiByteToWideChar然后WideCharToMultiByte出错情况</title>
      <link>https://csdn.fjh1997.top/posts/64617.html</link>
      <pubDate>Mon, 20 Oct 2025 21:49:02 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/64617.html</guid>
      <description>
        <![CDATA[<h1>用python模拟的MultiByteToWideChar然后WideCharToMultiByte出错情况</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>最近遇到一个CTF题。只有出错了才能够得到flag
原函数这样：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c" data-lang="c"><span class="line"><span class="cl"><span class="kt">int</span> <span class="kr">__cdecl</span> <span class="nf">sub_401D30</span><span class="p">(</span><span class="n">LPCCH</span> <span class="n">lpMultiByteStr</span><span class="p">,</span> <span class="kt">int</span> <span class="n">cbMultiByte</span><span class="p">,</span> <span class="kt">int</span> <span class="o">*</span><span class="n">a3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v3</span><span class="p">;</span> <span class="c1">// eax
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v4</span><span class="p">;</span> <span class="c1">// ebx
</span></span></span><span class="line"><span class="cl">  <span class="n">WCHAR</span> <span class="o">*</span><span class="n">lpWideCharStr</span><span class="p">;</span> <span class="c1">// eax
</span></span></span><span class="line"><span class="cl">  <span class="n">WCHAR</span> <span class="o">*</span><span class="n">v6</span><span class="p">;</span> <span class="c1">// esi
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v7</span><span class="p">;</span> <span class="c1">// eax
</span></span></span><span class="line"><span class="cl">  <span class="n">CHAR</span> <span class="o">*</span><span class="n">v8</span><span class="p">;</span> <span class="c1">// eax
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">cchWideChar</span><span class="p">;</span> <span class="c1">// [esp+14h] [ebp-28h]
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v11</span><span class="p">;</span> <span class="c1">// [esp+28h] [ebp-14h]
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v12</span><span class="p">;</span> <span class="c1">// [esp+28h] [ebp-14h]
</span></span></span><span class="line"><span class="cl">  <span class="kt">int</span> <span class="n">v13</span><span class="p">;</span> <span class="c1">// [esp+2Ch] [ebp-10h]
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="o">*</span><span class="n">a3</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span> <span class="n">lpMultiByteStr</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span> <span class="n">cbMultiByte</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">v3</span> <span class="o">=</span> <span class="nf">MultiByteToWideChar</span><span class="p">(</span><span class="mh">0xFDE9u</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">lpMultiByteStr</span><span class="p">,</span> <span class="n">cbMultiByte</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="n">v4</span> <span class="o">=</span> <span class="n">v3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span> <span class="n">v3</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">lpWideCharStr</span> <span class="o">=</span> <span class="p">(</span><span class="n">WCHAR</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">v3</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">v6</span> <span class="o">=</span> <span class="n">lpWideCharStr</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span> <span class="n">lpWideCharStr</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nf">MultiByteToWideChar</span><span class="p">(</span><span class="mh">0xFDE9u</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">lpMultiByteStr</span><span class="p">,</span> <span class="n">cbMultiByte</span><span class="p">,</span> <span class="n">lpWideCharStr</span><span class="p">,</span> <span class="n">v4</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="n">v7</span> <span class="o">=</span> <span class="nf">WideCharToMultiByte</span><span class="p">(</span><span class="mh">0x4E4u</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">v6</span><span class="p">,</span> <span class="n">v4</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">          <span class="k">if</span> <span class="p">(</span> <span class="n">v7</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">v11</span> <span class="o">=</span> <span class="n">v7</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">v8</span> <span class="o">=</span> <span class="p">(</span><span class="n">CHAR</span> <span class="o">*</span><span class="p">)</span><span class="nf">malloc</span><span class="p">(</span><span class="n">v7</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span> <span class="n">v8</span> <span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="n">cchWideChar</span> <span class="o">=</span> <span class="n">v11</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">              <span class="n">v13</span> <span class="o">=</span> <span class="n">v11</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">              <span class="n">v12</span> <span class="o">=</span> <span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">v8</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">              <span class="nf">WideCharToMultiByte</span><span class="p">(</span><span class="mh">0x4E4u</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">v6</span><span class="p">,</span> <span class="n">v4</span><span class="p">,</span> <span class="n">v8</span><span class="p">,</span> <span class="n">cchWideChar</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">              <span class="nf">free</span><span class="p">(</span><span class="n">v6</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">              <span class="o">*</span><span class="n">a3</span> <span class="o">=</span> <span class="n">v12</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">              <span class="k">return</span> <span class="n">v13</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="nf">free</span><span class="p">(</span><span class="n">v6</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>逻辑先是0xFDE9u的MultiByteToWideChar也是cp65001 utf-8到0x4E4u的WideCharToMultiByte也就是cp1252。
其中utf-8遇到不认识的字符会转化为�（U+FFFD）然后转化为cp1252会变成\xFD,认识的宽字节字符也会取后面那个字节，如utf-8的 b&rsquo;\xc2\x9d&rsquo; U+009D 变成&rsquo;\x9d&rsquo;，utf-8的b&rsquo;\xc3\xbd&rsquo; U+00FD变成&rsquo;\xFD'
用python模拟的时候废了很大的劲，主要是</p>
<blockquote>
<p>UnicodeEncodeError: &lsquo;charmap&rsquo; codec can&rsquo;t encode character &lsquo;\x9d&rsquo; in
position 0: character maps to <undefined></p>
</blockquote>
<p>U+009D 在cp1252里面识别不了
解决方法如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="c1"># 原始字节序列</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x24</span><span class="p">,</span> <span class="mh">0x59</span><span class="p">,</span> <span class="mh">0x19</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xBD</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xB6</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0x9D</span><span class="p">,</span> <span class="mh">0x27</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x43</span><span class="p">,</span> <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xA8</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xBE</span><span class="p">,</span> <span class="mh">0xC5</span><span class="p">,</span> <span class="mh">0xA0</span><span class="p">,</span> <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0x58</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0x85</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xBA</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0x8D</span><span class="p">,</span> <span class="mh">0x7B</span><span class="p">,</span> <span class="mh">0x56</span><span class="p">,</span> <span class="mh">0x49</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xA9</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xAC</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0x9D</span><span class="p">,</span> <span class="mh">0x26</span><span class="p">,</span> <span class="mh">0x50</span><span class="p">,</span> <span class="mh">0x19</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0xBE</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xAF</span><span class="p">,</span> <span class="mh">0xC5</span><span class="p">,</span> <span class="mh">0xA0</span><span class="p">,</span> <span class="mh">0x27</span><span class="p">,</span> <span class="mh">0x53</span><span class="p">,</span> <span class="mh">0x05</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">)</span>  <span class="c1"># C3 BD C2</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">utf8_to_latin1_bytes</span><span class="p">(</span><span class="n">utf8_data</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bytes</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    将 UTF-8 编码的字节序列转换为 Latin1 单字节表示。
</span></span></span><span class="line"><span class="cl"><span class="s2">    
</span></span></span><span class="line"><span class="cl"><span class="s2">    原理：
</span></span></span><span class="line"><span class="cl"><span class="s2">    1. decode(&#39;utf-8&#39;) 将 UTF-8 解码为 Unicode 字符串
</span></span></span><span class="line"><span class="cl"><span class="s2">    2. encode(&#39;latin1&#39;) 将 Unicode 字符编码为单字节 Latin1
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">buffer</span><span class="o">=</span><span class="n">utf8_data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;replace&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">converted</span><span class="o">=</span><span class="sa">b</span><span class="s1">&#39;&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">a</span> <span class="ow">in</span> <span class="n">buffer</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">b</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;cp1252&#39;</span><span class="p">,</span> <span class="n">errors</span><span class="o">=</span><span class="s1">&#39;surrogateescape&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">converted</span><span class="o">=</span><span class="n">converted</span><span class="o">+</span><span class="n">b</span>
</span></span><span class="line"><span class="cl">            <span class="nb">print</span><span class="p">(</span><span class="n">converted</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="k">except</span> <span class="ne">UnicodeEncodeError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">            <span class="n">b</span><span class="o">=</span><span class="n">a</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">            <span class="n">converted</span><span class="o">=</span><span class="n">converted</span><span class="o">+</span><span class="n">b</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">:]</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">converted</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 测试示例</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">converted</span> <span class="o">=</span> <span class="n">utf8_to_latin1_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;原始:&#34;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;转换后:&#34;</span><span class="p">,</span> <span class="n">converted</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>根据这个帖子：https://bugs.python.org/issue45120
<a href="https://github.com/python/cpython/issues/89283#issuecomment-1093928525" target="_blank" rel="noopener noreferrer nofollow">https://github.com/python/cpython/issues/89283#issuecomment-1093928525</a>
</p>
<blockquote>
<p>WinAPI WideCharToMultiByte() uses a best-fit encoding unless the flag
WC_NO_BEST_FIT_CHARS is passed.</p>
</blockquote>
<p>用了bestfit1252算法：
<a href="https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit1252.txt" target="_blank" rel="noopener noreferrer nofollow">https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WindowsBestFit/bestfit1252.txt</a>

也可以这样模拟：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">codecs</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 原始字节序列</span>
</span></span><span class="line"><span class="cl"><span class="n">data</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x24</span><span class="p">,</span> <span class="mh">0x59</span><span class="p">,</span> <span class="mh">0x19</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xBD</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xB6</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0x9D</span><span class="p">,</span> <span class="mh">0x27</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x43</span><span class="p">,</span> <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xA8</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xBE</span><span class="p">,</span> <span class="mh">0xC5</span><span class="p">,</span> <span class="mh">0xA0</span><span class="p">,</span> <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0x58</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0x1D</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0x85</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0xBA</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0x8D</span><span class="p">,</span> <span class="mh">0x7B</span><span class="p">,</span> <span class="mh">0x56</span><span class="p">,</span> <span class="mh">0x49</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xA9</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xAC</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span> <span class="mh">0x9D</span><span class="p">,</span> <span class="mh">0x26</span><span class="p">,</span> <span class="mh">0x50</span><span class="p">,</span> <span class="mh">0x19</span><span class="p">,</span> <span class="mh">0xC3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="mh">0xBE</span><span class="p">,</span> <span class="mh">0xC2</span><span class="p">,</span> <span class="mh">0xAF</span><span class="p">,</span> <span class="mh">0xC5</span><span class="p">,</span> <span class="mh">0xA0</span><span class="p">,</span> <span class="mh">0x27</span><span class="p">,</span> <span class="mh">0x53</span><span class="p">,</span> <span class="mh">0x05</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">)</span>  <span class="c1"># C3 BD C2</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">utf8_to_latin1_bytes</span><span class="p">(</span><span class="n">utf8_data</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bytes</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;&#34;&#34;
</span></span></span><span class="line"><span class="cl"><span class="s2">    将 UTF-8 编码的字节序列转换为 Latin1 单字节表示。
</span></span></span><span class="line"><span class="cl"><span class="s2">    
</span></span></span><span class="line"><span class="cl"><span class="s2">    原理：
</span></span></span><span class="line"><span class="cl"><span class="s2">    1. decode(&#39;utf-8&#39;) 将 UTF-8 解码为 Unicode 字符串
</span></span></span><span class="line"><span class="cl"><span class="s2">    2. codecs.code_page_encode 将unicode编码为cp1252字节
</span></span></span><span class="line"><span class="cl"><span class="s2">    &#34;&#34;&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="n">buffer</span><span class="o">=</span><span class="n">utf8_data</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;utf-8&#39;</span><span class="p">,</span><span class="n">errors</span><span class="o">=</span><span class="s1">&#39;replace&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">converted</span><span class="o">=</span><span class="n">codecs</span><span class="o">.</span><span class="n">code_page_encode</span><span class="p">(</span><span class="mi">1252</span><span class="p">,</span> <span class="n">buffer</span><span class="p">,</span> <span class="s1">&#39;replace&#39;</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">converted</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 测试示例</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">converted</span> <span class="o">=</span> <span class="n">utf8_to_latin1_bytes</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;原始:&#34;</span><span class="p">,</span> <span class="n">data</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span><span class="line"><span class="cl"><span class="nb">print</span><span class="p">(</span><span class="s2">&#34;转换后:&#34;</span><span class="p">,</span> <span class="n">converted</span><span class="o">.</span><span class="n">hex</span><span class="p">())</span>
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2025-10-20首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-10-20</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>阿里云服务器单位网络连不上ssh，但ping的通，手机热点却连得上的解决方法</title>
      <link>https://csdn.fjh1997.top/posts/28188.html</link>
      <pubDate>Wed, 17 Sep 2025 14:18:26 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/28188.html</guid>
      <description>
        <![CDATA[<h1>阿里云服务器单位网络连不上ssh，但ping的通，手机热点却连得上的解决方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>ssh数据包被reset了。抓包发现rst数据包的ttl和【syn，ack】的ttl数据包值相同。应该是阿里那边拦截了。</p>
<p><img src="/images/42a96bffaeec43ffa2eb8e7c93a4e004.png#pic_center" alt="在这里插入图片描述"></p>
<p>首先，单位可能有多个出口ip。要双向抓包。服务端和客户端用wireshark抓包。发现真实的出口ip。</p>
<p><img src="/images/414698e84b304eea9748959736c7200a.png" alt="在这里插入图片描述"></p>
<p>之后去登录阿里云云盾安全管控平台管理控制台（https://yundun.console.aliyun.com/?spm=a2c4g.11186623.0.0.769d8da5JMVb3I&amp;p=sc）。
在左侧导航栏，单击白名单管理 &gt; IP白名单。
单击添加单位的出口ip即可。一开始添加无效，原因是通过查询cip.cc得到的ip不一定是访问阿里云的出口ip.</p>

        
        <hr><p>本文2025-09-17首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-09-17</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>starting container process caused: exec: “catalina.sh“: executable file not found in $PATH: unknown</title>
      <link>https://csdn.fjh1997.top/posts/10140.html</link>
      <pubDate>Tue, 16 Sep 2025 20:41:22 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/10140.html</guid>
      <description>
        <![CDATA[<h1>starting container process caused: exec: “catalina.sh“: executable file not found in $PATH: unknown</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>报错为：
docker: Error response from daemon: OCI runtime create failed: container_linux.go:367: starting container process caused: exec: &ldquo;catalina.sh&rdquo;: executable file not found in $PATH: unknown.
文件目录如下：
.
├── 01.png
├── catalina.sh
├── context.xml
├── docker-compose.yml
├── Dockerfile
├── README.zh-cn.md
└── tomcat-users.xml</p>
<p>其中Dockerfile如下：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">FROM vulhub/tomcat:8.5.19
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">LABEL <span class="nv">maintainer</span><span class="o">=</span><span class="s2">&#34;phithon &lt;root@leavesongs.com&gt;&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">RUN <span class="nb">cd</span> /usr/local/tomcat/conf <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="o">&amp;&amp;</span> <span class="nv">LINE</span><span class="o">=</span><span class="k">$(</span>nl -ba web.xml <span class="p">|</span> grep <span class="s1">&#39;&lt;load-on-startup&gt;1&#39;</span> <span class="p">|</span> awk <span class="s1">&#39;{print $1}&#39;</span><span class="k">)</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="o">&amp;&amp;</span> <span class="nv">ADDON</span><span class="o">=</span><span class="s2">&#34;&lt;init-param&gt;&lt;param-name&gt;readonly&lt;/param-name&gt;&lt;param-value&gt;false&lt;/param-value&gt;&lt;/init-param&gt;&#34;</span> <span class="se">\
</span></span></span><span class="line"><span class="cl">    <span class="o">&amp;&amp;</span> sed -i <span class="s2">&#34;</span><span class="nv">$LINE</span><span class="s2"> i </span><span class="nv">$ADDON</span><span class="s2">&#34;</span> web.xml 
</span></span><span class="line"><span class="cl">COPY tomcat-users.xml /usr/local/tomcat/conf/tomcat-users.xml
</span></span><span class="line"><span class="cl">COPY context.xml  /usr/local/tomcat/webapps/manager/META-INF/context.xml
</span></span><span class="line"><span class="cl">COPY catalina.sh /usr/local/tomcat/bin/catalina.sh
</span></span></code></pre></td></tr></table>
</div>
</div><p>通过检查发现catalina.sh的权限为-rw-rw-rw-，这就导致Dockerfile复制进去之后保留了-rw-rw-rw-权限，其中缺少x权限导致终端无法识别catalina.sh命令。
所以修复方法为：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">chmod +x catalina.sh
</span></span><span class="line"><span class="cl">docker compose build --no-cache
</span></span><span class="line"><span class="cl">docker compose up -d
</span></span></code></pre></td></tr></table>
</div>
</div><p>或者在Dockerfile里面配置：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">COPY catalina.sh /usr/local/tomcat/bin/catalina.sh
</span></span><span class="line"><span class="cl">RUN chmod +x catalina.sh
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2025-09-16首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-09-16</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>新版frps配置文件toml配置多个端口的方法</title>
      <link>https://csdn.fjh1997.top/posts/62761.html</link>
      <pubDate>Tue, 06 May 2025 14:00:54 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/62761.html</guid>
      <description>
        <![CDATA[<h1>新版frps配置文件toml配置多个端口的方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>根据<a href="https://github.com/fatedier/frp/blob/6cbb26283c3931766216968975c06e03a58a0941/conf/frpc_full_example.toml" target="_blank" rel="noopener noreferrer nofollow">官方配置文档</a>
，方法为加入多个[[proxies]],如：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nv">serverAddr</span> <span class="o">=</span> <span class="s2">&#34;X.X.X.X&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">serverPort</span> <span class="o">=</span> <span class="m">7000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[[</span>proxies<span class="o">]]</span>
</span></span><span class="line"><span class="cl"><span class="nv">name</span> <span class="o">=</span> <span class="s2">&#34;test-tcp&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">type</span> <span class="o">=</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">localIP</span> <span class="o">=</span> <span class="s2">&#34;127.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">localPort</span> <span class="o">=</span> <span class="m">22</span>
</span></span><span class="line"><span class="cl"><span class="nv">remotePort</span> <span class="o">=</span> <span class="m">6000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[[</span>proxies<span class="o">]]</span>
</span></span><span class="line"><span class="cl"><span class="nv">name</span><span class="o">=</span><span class="s2">&#34;tkctf&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nb">type</span> <span class="o">=</span> <span class="s2">&#34;tcp&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">localIP</span> <span class="o">=</span> <span class="s2">&#34;127.0.0.1&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">localPort</span> <span class="o">=</span> <span class="m">80</span>
</span></span><span class="line"><span class="cl"><span class="nv">remotePort</span> <span class="o">=</span> <span class="m">80</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>警告⚠，frp确实很方便但同时也强烈建议frps配置一下auth-token，不然非常不安全！！！！！！！！！！！！！！！！！</p>
<blockquote>
<p>auth.method = &ldquo;token&rdquo;
auth.token = &ldquo;12345678&rdquo;</p>
</blockquote>

        
        <hr><p>本文2025-05-06首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-05-06</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>docker开放端口出现 curl: (56) Recv failure: Connection reset by peer的原因之一</title>
      <link>https://csdn.fjh1997.top/posts/40977.html</link>
      <pubDate>Wed, 29 Jan 2025 01:21:58 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/40977.html</guid>
      <description>
        <![CDATA[<h1>docker开放端口出现 curl: (56) Recv failure: Connection reset by peer的原因之一</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>docker容器内部服务监听地址为127.0.0.1会出现这种情况，解决方法就是监听到0.0.0.0。</p>

        
        <hr><p>本文2025-01-29首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2025-01-29</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>记一次root无法登录的情况</title>
      <link>https://csdn.fjh1997.top/posts/32126.html</link>
      <pubDate>Wed, 11 Dec 2024 16:48:14 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/32126.html</guid>
      <description>
        <![CDATA[<h1>记一次root无法登录的情况</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>grub里面改了密码也没用，于是关闭quiet开启日志，结果发现/etc/passwd被selinux拦截了，于是去/etc/selinux/config里面关闭即可。类似这样的错误：
audit(1733934483.186:122):avc: denied { open } for pid=814 comme=&ldquo;dbus-dae
mon=&quot;/etc/passwd&rdquo; dev=&ldquo;dm-0&quot;ino=20088836 scontext=system_u:system r:system_dbusd_t:s0-s0:c1023 tcontext=system_u:object _r:unlabeled_t:s0 tclass=file permissive=8
<img src="/images/4c87c24ccc9341cd953286697292c31d.jpeg" alt="在这里插入图片描述">
经过排查，selinux设置错误，正常的是</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">$ ls -Z /etc/passwd 
</span></span><span class="line"><span class="cl">system_u:object_r:passwd_file_t:s0 /etc/passwd
</span></span></code></pre></td></tr></table>
</div>
</div><p>结果变成他变成system_u:object_r:unlabeled_t:s0 /etc/passwd，ext4扩展属性出现问题
<img src="/images/56f13a784c9340548d77538e794ea8f2.jpeg" alt="在这里插入图片描述">
/var/log/secure里面可以看到报错日志：
<img src="/images/3b30aefb20ed4d81bc343a43176fdd86.png" alt="在这里插入图片描述">
结合unix_chkpwd的selinux属性chkpwd_exec_t
<img src="/images/7edbce6eb4a0410fb565943b078d431c.png" alt="在这里插入图片描述">
可能由于passwd_file_t标签丢失导致</p>

        
        <hr><p>本文2024-12-11首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-12-11</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>teec_initializecontext failed with code 0xffff0008</title>
      <link>https://csdn.fjh1997.top/posts/17143.html</link>
      <pubDate>Thu, 28 Nov 2024 09:40:58 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/17143.html</guid>
      <description>
        <![CDATA[<h1>teec_initializecontext failed with code 0xffff0008</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>需要用root运行</p>

        
        <hr><p>本文2024-11-28首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-11-28</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>FTP卡在150 Opening ASCII mode data connection”的解决方法</title>
      <link>https://csdn.fjh1997.top/posts/58558.html</link>
      <pubDate>Tue, 19 Nov 2024 20:40:11 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/58558.html</guid>
      <description>
        <![CDATA[<h1>FTP卡在150 Opening ASCII mode data connection”的解决方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>防火墙都已经开了，但是依然有问题，发现是hyper-v动态端口占用了，设置下即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="n">netsh</span> <span class="n">int</span> <span class="n">ipv4</span> <span class="nb">set </span><span class="n">dynamicport</span> <span class="n">tcp</span> <span class="mf">49152</span> <span class="mf">16383</span> <span class="n">persistent</span>
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2024-11-19首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-11-19</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>解决银河麒麟os上steam&#43;&#43;无法启动加速的问题</title>
      <link>https://csdn.fjh1997.top/posts/37662.html</link>
      <pubDate>Tue, 12 Nov 2024 19:38:07 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/37662.html</guid>
      <description>
        <![CDATA[<h1>解决银河麒麟os上steam++无法启动加速的问题</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>使用steam++加速github，点启动加速会提示/etc/hosts权限问题，修改了权限之后无效，提示无法写入，换做nano手动写入的时候却可以，经过研究，发现strace的openat系统调用参数一致，但是steam++的却提示无法打开写入，权限不足，猜测是系统内核里面有审计系统，毕竟是信创系统嘛。经过查询，发现确实有一个类似的审计系统kysec，大概是实现了selinux的强制访问原则，于是查资料关闭kysec即可</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">setstatus softmode -p
</span></span></code></pre></td></tr></table>
</div>
</div><p>安全中心里面也尽可能关闭。
<img src="/images/aef0f49448794135a764ccaae856d235.png" alt="在这里插入图片描述">
如果用自带的奇安信浏览器github提示证书错误，还需要去浏览器设置里面添加信任证书。</p>

        
        <hr><p>本文2024-11-12首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-11-12</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>如何挂载容器内的非空目录到宿主机，避免覆盖</title>
      <link>https://csdn.fjh1997.top/posts/11357.html</link>
      <pubDate>Thu, 24 Oct 2024 15:23:50 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/11357.html</guid>
      <description>
        <![CDATA[<h1>如何挂载容器内的非空目录到宿主机，避免覆盖</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>一般的docker挂载是需要使用宿主机内的一个目录挂载到容器里面，但是这样会出现一个问题，就是宿主机目录内的文件会覆盖到容器里面的那个目录，如果这个目录是空的，那么容器里面的目录也会被覆盖为空，导致一些异常，之后在网上找到了一个方法：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">version</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;2&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">services</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nt">tomcat</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="nt">build</span><span class="p">:</span><span class="w"> </span><span class="l">.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="s2">&#34;8080:8080&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="s2">&#34;5005:5005&#34;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">   </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">tomcat:/usr/local/tomcat</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">tomcat</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">driver</span><span class="p">:</span><span class="w"> </span><span class="l">local</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">driver_opts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">type</span><span class="p">:</span><span class="w"> </span><span class="l">none</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">device</span><span class="p">:</span><span class="w"> </span><span class="l">/root/tomcat</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">o</span><span class="p">:</span><span class="w"> </span><span class="l">bind</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>其中/root/tomcat可以修改为你要映射的路径
来源：https://stackoverflow.com/a/53200495/10096812</p>

        
        <hr><p>本文2024-10-24首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-10-24</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>通过markdown表格批量生成格式化的word教学单元设计表格</title>
      <link>https://csdn.fjh1997.top/posts/64061.html</link>
      <pubDate>Fri, 20 Sep 2024 00:21:02 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/64061.html</guid>
      <description>
        <![CDATA[<h1>通过markdown表格批量生成格式化的word教学单元设计表格</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>素材：<img src="/images/a75f4e40fec44b07a84a5e65c3024ae2.png" alt="在这里插入图片描述">
模板：
<img src="/images/c997a702fcde4f53a23a0335b67f15ac.png" alt="在这里插入图片描述">
代码：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">pandas</span> <span class="k">as</span> <span class="nn">pd</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">python_docx_replace</span> <span class="kn">import</span> <span class="n">docx_replace</span><span class="p">,</span><span class="n">docx_get_keys</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">docx</span> <span class="kn">import</span> <span class="n">Document</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">docxcompose.composer</span> <span class="kn">import</span> <span class="n">Composer</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">parse_markdown_tables</span><span class="p">(</span><span class="n">file_path</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">file_path</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">file</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">lines</span> <span class="o">=</span> <span class="n">file</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="n">current_table</span> <span class="o">=</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">        <span class="n">current_table</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">line</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;&lt;br&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">&#39;|&#39;</span><span class="p">)[</span><span class="mi">1</span><span class="p">:</span><span class="o">-</span><span class="mi">1</span><span class="p">])</span> 
</span></span><span class="line"><span class="cl">    <span class="n">df</span> <span class="o">=</span> <span class="n">pd</span><span class="o">.</span><span class="n">DataFrame</span><span class="p">(</span><span class="n">current_table</span><span class="p">[</span><span class="mi">1</span><span class="p">:],</span> <span class="n">columns</span><span class="o">=</span><span class="n">current_table</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">df</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">df</span><span class="o">=</span><span class="n">parse_markdown_tables</span><span class="p">(</span><span class="s2">&#34;单元设计.md&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">convert</span><span class="p">(</span><span class="n">num</span><span class="p">,</span><span class="n">df</span><span class="p">):</span>
</span></span><span class="line"><span class="cl">    <span class="nb">print</span><span class="p">(</span><span class="n">num</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">doc</span> <span class="o">=</span> <span class="n">Document</span><span class="p">(</span><span class="s2">&#34;template.docx&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># keys = docx_get_keys(doc) # Let&#39;s suppose the Word document has the keys: ${name} and ${phone}</span>
</span></span><span class="line"><span class="cl">    <span class="c1"># print(keys)  #[&#39;name&#39;, &#39;week&#39;, &#39;problem&#39;, &#39;location&#39;, &#39;test&#39;, &#39;obj&#39;, &#39;book&#39;, &#39;date&#39;, &#39;seq&#39;, &#39;homework&#39;, &#39;review&#39;, &#39;goal&#39;]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">docx_replace</span><span class="p">(</span><span class="n">doc</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">                <span class="n">book</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">8</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">week</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">problem</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">6</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">review</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">11</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">name</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">3</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">location</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">7</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">date</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">homework</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">10</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">seq</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">2</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">test</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">9</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">obj</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">4</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl">                <span class="n">goal</span><span class="o">=</span><span class="n">df</span><span class="o">.</span><span class="n">iloc</span><span class="p">[</span><span class="n">num</span><span class="p">]</span><span class="o">.</span><span class="n">tolist</span><span class="p">()[</span><span class="mi">5</span><span class="p">]</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">doc</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">master</span> <span class="o">=</span> <span class="n">Document</span><span class="p">(</span><span class="s2">&#34;master.docx&#34;</span><span class="p">)</span><span class="c1"># 任意word文档，里面可以包含封面</span>
</span></span><span class="line"><span class="cl"><span class="n">composer</span> <span class="o">=</span> <span class="n">Composer</span><span class="p">(</span><span class="n">master</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">df</span><span class="o">.</span><span class="n">axes</span><span class="p">[</span><span class="mi">0</span><span class="p">])):</span>
</span></span><span class="line"><span class="cl">    <span class="n">unit_doc</span><span class="o">=</span><span class="n">convert</span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="n">df</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="n">composer</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">unit_doc</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">composer</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="s2">&#34;combined.docx&#34;</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>效果，16张表：</p>
<p><img src="/images/478e07790b204ccf8b20a5c57140107c.png" alt="在这里插入图片描述">
项目地址：https://github.com/fjh1997/Unit</p>

        
        <hr><p>本文2024-09-20首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-09-20</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>Fine3399或rk3399\sw799刷armbian创建热点</title>
      <link>https://csdn.fjh1997.top/posts/29032.html</link>
      <pubDate>Wed, 04 Sep 2024 22:55:01 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/29032.html</guid>
      <description>
        <![CDATA[<h1>Fine3399或rk3399\sw799刷armbian创建热点</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span><span class="lnt">70
</span><span class="lnt">71
</span><span class="lnt">72
</span><span class="lnt">73
</span><span class="lnt">74
</span><span class="lnt">75
</span><span class="lnt">76
</span><span class="lnt">77
</span><span class="lnt">78
</span><span class="lnt">79
</span><span class="lnt">80
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo bash
</span></span><span class="line"><span class="cl"><span class="c1">#切换root</span>
</span></span><span class="line"><span class="cl">sudo apt install -y hostapd isc-dhcp-server ifupdown
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 配置 hostapd</span>
</span></span><span class="line"><span class="cl">sudo nano /etc/hostapd/hostapd.conf
</span></span><span class="line"><span class="cl"><span class="nv">interface</span><span class="o">=</span>wlan0
</span></span><span class="line"><span class="cl"><span class="nv">driver</span><span class="o">=</span>nl80211
</span></span><span class="line"><span class="cl"><span class="nv">ssid</span><span class="o">=</span>hostspot-name
</span></span><span class="line"><span class="cl"><span class="nv">macaddr_acl</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="nv">auth_algs</span><span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl"><span class="c1">#auth_algs=3</span>
</span></span><span class="line"><span class="cl"><span class="nv">ignore_broadcast_ssid</span><span class="o">=</span><span class="m">0</span>
</span></span><span class="line"><span class="cl"><span class="nv">hw_mode</span><span class="o">=</span>bgn
</span></span><span class="line"><span class="cl"><span class="nv">channel</span><span class="o">=</span><span class="m">6</span>
</span></span><span class="line"><span class="cl"><span class="nv">wpa</span><span class="o">=</span><span class="m">2</span>
</span></span><span class="line"><span class="cl"><span class="nv">wpa_passphrase</span><span class="o">=</span>password
</span></span><span class="line"><span class="cl"><span class="nv">wpa_key_mgmt</span><span class="o">=</span>WPA-PSK
</span></span><span class="line"><span class="cl"><span class="nv">wpa_pairwise</span><span class="o">=</span>CCMP
</span></span><span class="line"><span class="cl"><span class="c1">#wpa_pairwise=TKIP</span>
</span></span><span class="line"><span class="cl"><span class="c1">#rsn_pairwise=CCMP</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 修改 hostapd 默认配置文件路径</span>
</span></span><span class="line"><span class="cl">sudo nano /etc/default/hostapd
</span></span><span class="line"><span class="cl"><span class="nv">DAEMON_CONF</span><span class="o">=</span>/etc/hostapd/hostapd.conf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 重启 hostapd</span>
</span></span><span class="line"><span class="cl">sudo service hostapd restart
</span></span><span class="line"><span class="cl">sudo service hostapd status
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># dhcp 配置</span>
</span></span><span class="line"><span class="cl">sudo nano /etc/dhcp/dhcpd.conf
</span></span><span class="line"><span class="cl"><span class="c1">#option domain-name &#34;example.org&#34;;</span>
</span></span><span class="line"><span class="cl"><span class="c1">#option domain-name-servers ns1.example.org, ns2.example.org;</span>
</span></span><span class="line"><span class="cl">authoritative<span class="p">;</span>
</span></span><span class="line"><span class="cl">subnet 10.0.0.0 netmask 255.255.255.0 <span class="o">{</span>
</span></span><span class="line"><span class="cl">    range 10.0.0.10 10.0.0.200<span class="p">;</span>
</span></span><span class="line"><span class="cl">    option broadcast-address 10.0.0.255<span class="p">;</span>
</span></span><span class="line"><span class="cl">    option routers 10.0.0.1<span class="p">;</span>
</span></span><span class="line"><span class="cl">    default-lease-time 600<span class="p">;</span>
</span></span><span class="line"><span class="cl">    max-lease-time 7200<span class="p">;</span>
</span></span><span class="line"><span class="cl">    option domain-name <span class="s2">&#34;local&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    option domain-name-servers 223.5.5.5, 8.8.4.4<span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 设置 dhcp 网口</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 不进行操作会出现错误：Not configured to listen on any interfaces!</span>
</span></span><span class="line"><span class="cl">sudo nano /etc/default/isc-dhcp-server
</span></span><span class="line"><span class="cl"><span class="nv">INTERFACESv4</span><span class="o">=</span><span class="s2">&#34;wlan0&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">INTERFACESv6</span><span class="o">=</span><span class="s2">&#34;wlan0&#34;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 设置 wlan0 地址</span>
</span></span><span class="line"><span class="cl"><span class="c1"># 不进行操作会出现错误：Not configured to listen on any interfaces!</span>
</span></span><span class="line"><span class="cl">sudo ip addr add 10.0.0.1/24 dev wlan0
</span></span><span class="line"><span class="cl"><span class="c1"># 设置开机自动设置</span>
</span></span><span class="line"><span class="cl">mkdir /etc/network/interfaces.d/
</span></span><span class="line"><span class="cl"><span class="nb">echo</span> -e <span class="s2">&#34;# armbian NAT hostapd\nallow-hotplug wlan0\niface wlan0 inet static\n \taddress 10.0.0.1\n\tnetmask 255.255.255.0\n\tnetwork 10.0.0.0\n\tbroadcast 10.0.0.255&#34;</span> &gt; /etc/network/interfaces.d/armbian.ap.nat
</span></span><span class="line"><span class="cl"><span class="c1"># 开启转发</span>
</span></span><span class="line"><span class="cl">sudo sysctl -w net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span>
</span></span><span class="line"><span class="cl">sudo iptables -t nat -A POSTROUTING -s 10.0.0.1/24 -o eth0 -j MASQUERADE
</span></span><span class="line"><span class="cl">sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
</span></span><span class="line"><span class="cl">sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
</span></span><span class="line"><span class="cl"><span class="c1">#设置开机启动自动设置</span>
</span></span><span class="line"><span class="cl">sudo iptables-save &gt; /etc/iptables.ipv4.nat
</span></span><span class="line"><span class="cl">cat <span class="s">&lt;&lt;-EOF &gt; /etc/systemd/system/armbian-restore-iptables.service
</span></span></span><span class="line"><span class="cl"><span class="s">[Unit]
</span></span></span><span class="line"><span class="cl"><span class="s">Description=&#34;Restore IP tables&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">[Timer]
</span></span></span><span class="line"><span class="cl"><span class="s">OnBootSec=20Sec
</span></span></span><span class="line"><span class="cl"><span class="s">[Service]
</span></span></span><span class="line"><span class="cl"><span class="s">Type=oneshot
</span></span></span><span class="line"><span class="cl"><span class="s">ExecStart=/sbin/iptables-restore /etc/iptables.ipv4.nat
</span></span></span><span class="line"><span class="cl"><span class="s">[Install]
</span></span></span><span class="line"><span class="cl"><span class="s">WantedBy=sysinit.target
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> armbian-restore-iptables.service
</span></span><span class="line"><span class="cl"><span class="c1"># 启动 dhcp 服务</span>
</span></span><span class="line"><span class="cl">systemctl <span class="nb">enable</span> isc-dhcp-server 
</span></span><span class="line"><span class="cl">systemctl start isc-dhcp-server 
</span></span></code></pre></td></tr></table>
</div>
</div><p>参考：https://gitee.com/xiayang0521/rk3399</p>

        
        <hr><p>本文2024-09-04首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-09-04</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>解决windterm莫名其妙输入ctrl&#43;c的问题</title>
      <link>https://csdn.fjh1997.top/posts/5199.html</link>
      <pubDate>Mon, 02 Sep 2024 21:50:32 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/5199.html</guid>
      <description>
        <![CDATA[<h1>解决windterm莫名其妙输入ctrl+c的问题</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p><img src="/images/3f1b8a566a20444a83cf7e5308bd800e.png" alt="在这里插入图片描述"></p>
<p>原来是钉钉在监控你的鼠标，取消设置即可</p>
<p><img src="/images/3deca683d3184e6cb830bfdb9d5bb2ee.png" alt="在这里插入图片描述">
来源：https://github.com/kingToolbox/WindTerm/issues/2296</p>

        
        <hr><p>本文2024-09-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-09-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>如何从mssql里面导出程序集ASSEMBLY为dll</title>
      <link>https://csdn.fjh1997.top/posts/12500.html</link>
      <pubDate>Mon, 02 Sep 2024 19:22:01 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/12500.html</guid>
      <description>
        <![CDATA[<h1>如何从mssql里面导出程序集ASSEMBLY为dll</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>前段时间服务器被黑客入侵了，发现黑客注入的sql语句是创建了一个程序集ASSEMBLY</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">CREATE</span><span class="w"> </span><span class="n">ASSEMBLY</span><span class="w"> </span><span class="p">[</span><span class="n">SweetShellcodeclr35</span><span class="p">]</span><span class="k">AUTHORIZATION</span><span class="w"> </span><span class="p">[</span><span class="n">dbo</span><span class="p">]</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="mi">0</span><span class="n">xFF</span><span class="err">……</span><span class="n">FFFFF</span><span class="w">  </span><span class="k">WITH</span><span class="w"> </span><span class="n">PERMISSION_SET</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">UNSAFE</span><span class="p">;</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>，但是光凭sql语句无法逆向，之后在stackoverflow找到了一个方法导出程序集为dll文件的方法：
首先查出程序集的编号：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="w"> </span><span class="k">select</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">from</span><span class="w"> </span><span class="n">sys</span><span class="p">.</span><span class="n">assembly_files</span><span class="w"> 
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>之后使用以下方法设置assembly_id 导出</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">DECLARE</span><span class="w"> </span><span class="o">@</span><span class="n">IMG_PATH</span><span class="w"> </span><span class="n">VARBINARY</span><span class="p">(</span><span class="k">MAX</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">DECLARE</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="w"> </span><span class="nb">INT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">SELECT</span><span class="w"> </span><span class="o">@</span><span class="n">IMG_PATH</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">content</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">sys</span><span class="p">.</span><span class="n">assembly_files</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">assembly_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">65536</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OACreate</span><span class="w"> </span><span class="s1">&#39;ADODB.Stream&#39;</span><span class="p">,</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="w"> </span><span class="k">OUTPUT</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OASetProperty</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Type&#39;</span><span class="p">,</span><span class="w"> </span><span class="mi">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OAMethod</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Open&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OAMethod</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Write&#39;</span><span class="p">,</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"> </span><span class="o">@</span><span class="n">IMG_PATH</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OAMethod</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;SaveToFile&#39;</span><span class="p">,</span><span class="w"> </span><span class="k">NULL</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;c:\temp\myassembly.dll&#39;</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OAMethod</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;Close&#39;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="k">EXEC</span><span class="w"> </span><span class="n">sp_OADestroy</span><span class="w"> </span><span class="o">@</span><span class="n">ObjectToken</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>有人问为什么我会去找这个方法，直接16进制转化为dll不就行了，原因是我之前用mysql转化的时候出错了。之后发现不能直接16进制转化为dll的原因是我是使用mysql转化的，而mysql里面<code>select 0x20 into outfile</code>和<code> select 0x20 into dumpfile</code>是不一样的，如果是outfile会重新编码，而dumpfile则不用。
所以其实直接去掉0x然后16进制转化也是可以的。</p>
<p>参考：https://stackoverflow.com/questions/4103406/extracting-a-net-assembly-from-sql-server-2005</p>

        
        <hr><p>本文2024-09-02首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-09-02</p>]]>
      </description>
      
    </item>
    
    

    <item>
      <title>SW799刷armbian之后一段时间自动关机的解决方法</title>
      <link>https://csdn.fjh1997.top/posts/34270.html</link>
      <pubDate>Thu, 29 Aug 2024 12:50:39 &#43;0800</pubDate>
      <author>xxx@example.com (catcatyu)</author>
      <guid>https://csdn.fjh1997.top/posts/34270.html</guid>
      <description>
        <![CDATA[<h1>SW799刷armbian之后一段时间自动关机的解决方法</h1><p>作者：catcatyu（xxx@example.com）</p>
        
          <p>主要原因是进入了休眠模式：使用以下命令关闭休眠即可：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
</span></span></code></pre></td></tr></table>
</div>
</div>
        
        <hr><p>本文2024-08-29首发于<a href='https://csdn.fjh1997.top/'>猫猫鱼的小窝</a>，最后修改于2024-08-29</p>]]>
      </description>
      
    </item>
    
  </channel>
</rss>
