<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>yyhhyyyyyy</title>
        <link>https://iyyh.net/</link>
        <description>yyhhyyyyyy's Blog</description>
        <lastBuildDate>Sat, 04 Apr 2026 12:37:05 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>yyhhyyyyyy</title>
            <url>https://iyyh.net/avatar.webp</url>
            <link>https://iyyh.net/</link>
        </image>
        <copyright>CC BY-NC-SA 4.0 2020 © yyhhyyyyyy</copyright>
        <atom:link href="https://iyyh.net/feed.xml" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Surge For Mac 自用配置]]></title>
            <link>https://iyyh.net/posts/2025/12/surge-for-mac</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/12/surge-for-mac</guid>
            <pubDate>Wed, 31 Dec 2025 07:28:59 GMT</pubDate>
            <description><![CDATA[自用 Surge For Mac 配置文件与思路分享]]></description>
            <content:encoded><![CDATA[<p>上一篇写了 <a href="https://iyyh.net/posts/2025/12/surge-for-ios">Surge For IOS 自用配置</a>，这次趁热打铁，把 <strong>Surge for Mac</strong> 的自用配置思路也补齐。</p>
<p>整体仍然按四块来讲：<strong>[General] / [Proxy Group] / [Rule] / [Proxy]</strong>。<br>
其中与 iOS 完全一致的部分，本篇就不重复解释，直接给对应链接，避免来回翻看浪费时间。</p>
<blockquote>
<p><strong>说明</strong>：下文遇到“重复参数/重复配置”我会直接指路到 iOS 文章对应章节。</p>
</blockquote>
<h2>1.General</h2>
<h3>1.1 Mac 新增参数（Mac 特有）</h3>
<p><code>read-etc-hosts</code>： 让 Surge 读取并遵循系统 <code>/etc/hosts</code> 里的本地 DNS 映射。</p>
<p>当 hosts 命中时，会优先使用该映射结果，避免再走 Surge 的 DNS / DoH 流程。</p>
<blockquote>
<p>适合场景：你在 hosts 里维护了一些内网域名、临时测试域名，或者需要强制覆盖某些解析时。</p>
</blockquote>
<h3>1.2 重复参数</h3>
<p>除 <code>read-etc-hosts</code> 外，其余 General 配置与 iOS 一致。<br>
请直接查看： <a href="https://iyyh.net/posts/2025/12/surge-for-ios#_1-general">Surge For iOS - General</a></p>
<h2>2. Proxy Group</h2>
<p>与 iOS 一致，请移步：<br>
<a href="https://iyyh.net/posts/2025/12/surge-for-ios#_2-proxy-group">Surge For iOS - Proxy Group</a></p>
<h2>3. Rule</h2>
<p>与 iOS 一致，请移步：<br>
<a href="https://iyyh.net/posts/2025/12/surge-for-ios#_3-rule">Surge For iOS - Rule</a></p>
<h2>4. Proxy</h2>
<p>与 iOS 一致，请移步：<br>
<a href="https://iyyh.net/posts/2025/12/surge-for-ios#_4-proxy">Surge For iOS - Proxy</a></p>
<h2>5. 内网外分离</h2>
<p>Surge For Mac 这边我实际上用到的一个非常不错的功能是内外网分离。</p>
<p>我的 MBP 同时在用两张网卡：</p>
<ul>
<li><strong>有线网卡</strong>：接公司内网（访问公司服务/内网域名等）</li>
<li><strong>无线网卡</strong>：日常主用网络（外部流量主要走这张）</li>
</ul>
<p>本质上公司有线也能出网，但出于隐私与习惯，我会把“公司 Wi-Fi 环境”下的某些访问强制走指定路径，从而达到 <strong>内外网更清晰</strong>、行为更可控的效果。</p>
<h3>5.1 在 [Proxy] 里绑定有线网卡（DIRECT + interface）</h3>
<p>先在 <strong>[Proxy]</strong> 定义一个“绑定网卡的直连”：</p>
<pre><code class="language-text">[Proxy]
Wired Network = DIRECT,interface=en7
</code></pre>
<p>这里的关键是 <code>interface</code>：它是你电脑里该网卡对应的接口名。<br>
你需要用 <code>ifconfig</code> 自己确认（不同机型/扩展坞/系统环境，接口名可能不一样，比如 <code>en5</code>/<code>en7</code> 等）。</p>
<h3>5.2 在 [Proxy Group] 用 subnet 根据 Wi-Fi SSID 选择策略</h3>
<p>接着在 <strong>[Proxy Group]</strong> 里定义一个 <code>subnet</code> 策略组：默认走直连，但当连接到公司 Wi-Fi（指定 SSID）时，切到 <code>Wired Network</code>。</p>
<pre><code class="language-text">Wifi = subnet,default=DIRECT,&quot;SSID:[公司 WIFI SSID]&quot;=Wired Network
</code></pre>
<p>举个例子：如果你公司的 Wi-Fi 名称是 <code>test-wifi</code>，那就写成：</p>
<pre><code>Wifi = subnet,default=DIRECT,&quot;SSID:test-wifi&quot;=Wired Network
</code></pre>
<h3>5.3 在 [Rule] 里把公司内网域名丢给 Wifi 这个策略组</h3>
<p>最后在 <strong>[Rule]</strong> 把公司内网域名交给 <code>Wifi</code>：</p>
<pre><code class="language-text">[Rule]
DOMAIN,[你公司的内网域名],Wifi
</code></pre>
<p>这样命中公司内网域名时，就会按 <code>Wifi</code> 的策略做选择：</p>
<h3>5.4 前置条件：网络服务顺序</h3>
<p>请先在 macOS 调整网络服务顺序，确保 <strong>Wi-Fi 在最上方（优先级最高）</strong>：<br>
<strong>系统设置 → 网络 → 右下角「…」→ 设定服务顺序</strong> → 将 <strong>Wi-Fi</strong> 拖到最前。</p>
<p>这样可以避免系统把“默认出网”优先走到其他网络接口，导致 Surge 的分流判断与你预期不一致。</p>
<h2>6. 仓库</h2>
<p>Surge For Mac 的完整配置文件已在 GitHub 上，请<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Surge/Surge-Mac.conf">点击此处访问</a></p>
<p>到这里，Surge 的 <strong>iOS / Mac</strong> 两套自用配置思路就都写完了。<br>
iOS 那篇在这里：<strong><a href="https://iyyh.net/posts/2025/12/surge-for-ios">Surge For iOS 自用配置</a></strong>，如果你是第一次看我的 Surge 系列，建议先从 iOS 那篇开始，很多通用概念（General / 分组 / 规则）我都放在那边统一讲清楚了。</p>
<p>Mac 端这篇更多是补充我日常最常用的“桌面场景”，尤其是 <strong>内外网分离</strong> 这种在 iPhone 上很难完整复刻的玩法。<br>
接下来就是模块的坑需要填咯～敬请期待～</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Surge For IOS 自用配置]]></title>
            <link>https://iyyh.net/posts/2025/12/surge-for-ios</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/12/surge-for-ios</guid>
            <pubDate>Tue, 30 Dec 2025 15:29:59 GMT</pubDate>
            <description><![CDATA[自用 Surge For IOS 配置文件与思路分享]]></description>
            <content:encoded><![CDATA[<p>有段时间没写代理/网络工具相关的文章了。新年将近，正好把我一直在用的 <strong>Surge（iOS）</strong> 配置体系整理成一篇：<strong>能照抄、也能看懂原理</strong>的自用教程。</p>
<p>最近这一年多我基本只在 <strong>Mac + iPhone</strong> 上折腾网络环境，Windows / Android 用得不多了。后续大概也是以 Surge 上的折腾为主。</p>
<blockquote>
<p>说明：本文以 Surge iOS 的配置文件结构为主，按我的理解拆成四块来讲：<br>
<strong>[General] / [Proxy Group] / [Rule] / [Proxy]</strong>。<br>
你也可以按自己习惯调整顺序，但核心逻辑不变。</p>
</blockquote>
<h2>1.General</h2>
<p>General 我更倾向于按「场景」来讲：你关心的不是“Surge 有哪些开关”，而是“我该不该开、什么时候会踩坑”。</p>
<h3>1.1 观测 &amp; 排错相关</h3>
<pre><code class="language-text">loglevel = notify
show-error-page-for-reject = true
</code></pre>
<ul>
<li>
<p><code>loglevel</code>（日志输出等级）<br>
我一般用 <strong>notify</strong>。日常够用。</p>
</li>
<li>
<p><code>show-error-page-for-reject</code>（REJECT 时显示 Surge 错误页）<br>
这个只影响**纯 HTTP（非 HTTPS）**请求：当命中 <code>REJECT</code> 策略时，Surge 会给浏览器返回一张“错误网页”，让你更直观地知道是被规则拒绝了。跟我一致开启就行</p>
</li>
</ul>
<h3>1.2 网络体验相关（Wi-Fi / 蜂窝切换）</h3>
<pre><code class="language-text">wifi-assist = true
all-hybrid = false
</code></pre>
<ul>
<li><code>wifi-assist</code>（“Wi-Fi 助手”）<br>
打开后，Wi-Fi 质量很差时 Surge 会更积极地帮你把连接切到蜂窝，适合家里 Wi-Fi 覆盖不完整、走动容易掉速的场景。</li>
<li><code>all-hybrid</code>（Wi-Fi + 蜂窝双通道并发）<br>
这个更“激进”：不是等 Wi-Fi 差了再切，而是<strong>始终同时</strong>用 Wi-Fi 和蜂窝去建立连接（包括 TCP 连接和 DNS）。<br>
体验会更稳，但代价也更大——<strong>流量消耗会明显增加</strong>，所以除非你流量基本不限，否则不建议开。</li>
</ul>
<h3>1.3 共享代理相关（让别的设备也能用你的 Surge）</h3>
<pre><code class="language-text">allow-wifi-access = true
allow-hotspot-access = true
</code></pre>
<ul>
<li><code>allow-wifi-access</code>（局域网共享）<br>
允许同一局域网里的其他设备访问 Surge 的代理服务（本质就是“把 iPhone 当一个局域网代理服务器”）。</li>
<li><code>allow-hotspot-access</code>（热点共享）<br>
当你开启个人热点时，允许连你热点的设备访问 Surge 的代理服务。</li>
</ul>
<blockquote>
<p>这里容易误会的一点：<br>
<strong>开了共享 ≠ 别人自动Proxy上网。</strong><br>
对方设备仍然需要在 Wi-Fi/系统代理里，把代理地址指向你的 iPhone（以及对应端口），否则它只是“连上热点上网”，并不会自动走 Surge。</p>
</blockquote>
<h3>1.4 IPv6 相关（两个开关的区别）</h3>
<pre><code class="language-text">ipv6 = false
ipv6-vif = disabled
</code></pre>
<p>这两个名字很像，但控制的东西不一样：</p>
<ul>
<li><code>ipv6</code>（DNS 解析是否查询 AAAA）<br>
开启后，Surge 的 DNS 会在解析域名时同时查 <strong>A + AAAA</strong>；关闭则只查 <strong>A（IPv4）</strong>。<br>
我没 V6 需求，所以设为 <code>false</code>。</li>
<li><code>ipv6-vif</code>（Surge VIF 是否承载 IPv6）<br>
这是“更底层”的开关：它决定 Surge 的虚拟网卡（VIF）要不要配置 IPv6，让 Surge 能接管/处理连接到 IPv6 地址的原始 TCP 连接。<br>
我目前同样设为 <code>disabled</code>。</li>
</ul>
<p><strong>一句话总结：</strong><br>
<code>ipv6</code> 更像“DNS 层面要不要解析 IPv6”；<code>ipv6-vif</code> 更像“隧道/接管层面要不要让 VIF 具备 IPv6 能力”。</p>
<h3>1.5 连通性 &amp; 代理测速（URL / UDP）</h3>
<pre><code class="language-text">test-timeout = 2
internet-test-url = http://connectivitycheck.platform.hicloud.com/generate_204
proxy-test-url = http://latency-test.skk.moe/endpoint
proxy-test-udp = www.apple.com@64.6.64.6
</code></pre>
<p>这一组参数我一般归类为「健康检查 + 节点测速」：Surge 会用它们来判断“当前网络有没有网”、以及“某个代理/策略组延迟怎么样”。</p>
<ul>
<li>
<p><code>test-timeout</code>（测试超时，单位：秒）<br>
这是<strong>代理测速等待的最长时间</strong>：超过这个时间还没结果，就会被判定为失败。</p>
</li>
<li>
<p><code>internet-test-url</code>（互联网连通性测试 URL）<br>
用于互联网连接性测试的 URL。同时也是 DIRECT 策略的测试 URL。</p>
</li>
<li>
<p><code>proxy-test-url</code>（默认代理测试 URL）<br>
代理策略的默认测试 URL。没特殊需求跟我一致即可。</p>
</li>
<li>
<p><code>proxy-test-udp</code>（代理默认 UDP 测试参数）<br>
建议直接使用<code>www.apple.com</code></p>
</li>
</ul>
<h3>1.6 DNS</h3>
<pre><code class="language-text">exclude-simple-hostnames = true
dns-server = system
encrypted-dns-server = quic://223.5.5.5, quic://223.6.6.6, https://1.12.12.12/dns-query, https://120.53.53.53/dns-query
hijack-dns = 8.8.8.8:53, 8.8.4.4:53
</code></pre>
<ul>
<li>
<p><code>exclude-simple-hostnames</code>（排除简单主机名）<br>
像 <code>nas</code>、<code>printer</code> 这种不带点的主机名，不走公网 DNS 解析。</p>
</li>
<li>
<p><code>dns-server</code>（DNS 服务器）</p>
<p>这边我写<code>system</code>，是因为我使用加密 DNS。如果配置了加密 DNS，传统 DNS 将仅用作解析 DOH 域名和测试网络连通性。如果你网络环境文明，那么不需要加密 DNS ，那么直接使用 system 即可。</p>
</li>
<li>
<p><code>encrypted-dns-server</code>（加密 DNS 上游）<br>
主要就是让 DNS 走 DoH/DoQ，减少明文污染/劫持风险。按你所在网络稳定性挑上游即可。</p>
</li>
<li>
<p><code>hijack-dns</code>（DNS 劫持）<br>
这边是为了解决 Google 部分产品强制使用 8.8.8.8 和 8.8.4.4，未能使用 Surge DNS 的问题。</p>
</li>
</ul>
<h3>1.7 跳过代理（哪些目标不走代理）</h3>
<pre><code class="language-text">skip-proxy = 127.0.0.0/8, 192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12, 100.64.0.0/10, 162.14.0.0/16, 211.99.96.0/19, 162.159.192.0/24, 162.159.193.0/24, 162.159.195.0/24, fc00::/7, fe80::/10, localhost, *.local, captive.apple.com, passenger.t3go.cn, *.ccb.com, wxh.wo.cn, *.abcchina.com, *.abcchina.com.cn
</code></pre>
<ul>
<li><code>skip-proxy</code>（跳过代理 / 强制直连）<br>
在 <strong>Surge iOS</strong> 里，写进 <code>skip-proxy</code> 的 IP 段和域名会<strong>不走任何 Proxy / Proxy Group</strong>，而是直接由 Surge 的 <strong>VIF 虚拟网卡</strong>按“直连”方式处理（也就是绕过代理链路）。</li>
</ul>
<h3>1.8 Always Real IP</h3>
<p>这部分请直接安装 skk 的<a href="*https://ruleset.skk.moe/Modules/sukka_common_always_realip.sgmodule*">模块</a><br>
当surge 命中列表内的域名，在 DNS 解析时强制返回 Real IP，而不是 Fake IP。</p>
<h3>1.9 UDP 不支持时的处理策略</h3>
<pre><code class="language-text">udp-policy-not-supported-behaviour = REJECT
</code></pre>
<ul>
<li><code>udp-policy-not-supported-behaviour</code>（UDP 不支持时怎么处理）<br>
当<strong>当前选用的策略/节点不支持 UDP 转发</strong>时，直接 <code>REJECT</code>：避免 UDP 流量回落到直连，导致“漏流量 / 暴露真实 IP”。</li>
</ul>
<h3>1.10 远程控制（HTTP API / Web 面板）</h3>
<pre><code class="language-text">http-api = yyhhyyyyyy@0.0.0.0:6171
http-api-web-dashboard = true
</code></pre>
<p>我会使用到小麦的Dashboard，如果没有这方面需求，可以注释。</p>
<h2>2. Proxy Group</h2>
<p>我划分代理组时会先问自己三个问题：</p>
<ul>
<li>
<p>国家分组肯定是需要的，那你实际会用到哪些国家？</p>
</li>
<li>
<p>哪些分流值得单独拎出来（比如 Telegram、AIGC）？</p>
</li>
<li>
<p>有没有“特殊节点”（Emby/低倍/家宽）需要保留一个入口？</p>
</li>
</ul>
<p>理顺这三个问题，Proxy Group 很快就成型了。</p>
<p>开始之前，先说明几个常用参数：</p>
<ul>
<li><code>update-interval</code>：订阅更新间隔，单位<strong>秒</strong><br>
多久从订阅链接拉取一次最新节点。我建议直接<code>-1</code>就是用不更新。当前提是你的订阅足够稳定；不稳定就自己改成合适的周期。</li>
<li><code>policy-regex-filter</code>：正则匹配<br>
这是为了后面划分一些特定分组来使用，比如划分国家分组</li>
<li><code>include-all-proxies</code>：包含 [Proxy] 部分定义的所有代理策略<br>
把[Proxy]里的节点聚合起来了，如果你都是单节点的话，这个非常好用</li>
<li><code>include-other-group</code>：包含[Proxy Group]里的分组<br>
有时候可能需要聚合多个你自己写的[Proxy Group]里的分组，可以使用这个参数</li>
<li><code>policy-path</code>：订阅链接</li>
</ul>
<h3>2.1 订阅入口 / 聚合组</h3>
<pre><code class="language-text"># 订阅链接
🚀 我的节点 = select,policy-path=https://sub.store/download/my,update-interval=-1
# 聚合[Proxy]
🚀 ALL-Proxy = select,include-all-proxies=1
# 只要[Proxy]里的部分节点
🚀 Select-Proxy = select,Proxy A,Proxy B...
</code></pre>
<p>一般对于绝大多数人，以上的三种写法应该就够用了。</p>
<p>有订阅就用 <code>policy-path</code></p>
<p>有手写节点就用 <code>include-all-proxies</code></p>
<p>只想挑几个固定节点就写 <code>select, A, B, C</code></p>
<h3>2.2 国家分组（推荐用 smart）</h3>
<p>节点里国家这么多，分流的时候肯定是需要有特定的国家需求，我的做法是：<strong>国家分组只负责“筛选”</strong>，策略组再负责“选择”。</p>
<p>这边无非通过正则筛选分组<code>policy-regex-filter</code>，以及一个小小的<code>include-other-group</code>指向上面的<strong>外部订阅组</strong>即可</p>
<p>一般我涉及到的场景会用到的国家其实就3个🇭🇰、🇯🇵、🇺🇸 其他我基本都不会使用到，不过为了让大家有一些感觉，我把3个扩展成5个，具体如下：</p>
<pre><code class="language-text">🇭🇰 香港 = smart,include-other-group=🚀 我的节点,policy-regex-filter=(🇭🇰|香港|[Hh][Kk])
🇨🇳 台湾 = smart,include-other-group=🚀 我的节点,policy-regex-filter=(🇨🇳|台湾|[Tt][Ww])
🇺🇸 美国 = smart,include-other-group=🚀 我的节点,policy-regex-filter=(🇺🇸|美国|[Uu][Ss])
🇯🇵 日本 = smart,include-other-group=🚀 我的节点,policy-regex-filter=(🇯🇵|日本|[Jj][Pp])
🇸🇬 新加坡 = smart,include-other-group=🚀 我的节点,policy-regex-filter=(🇸🇬|新加坡|[Ss][Gg])
</code></pre>
<p>我这里国家分组用的是 <strong>smart</strong>（Surge 的智能策略组）：<br>
日常不用纠结选哪条，Surge 会自动挑一个相对稳定且延迟舒服的。</p>
<blockquote>
<p>备注：正则尽量“够用就好”。只要能覆盖你订阅里的命名习惯即可，不需要写到很复杂。</p>
</blockquote>
<h3>2.3 分流策略组（推荐用 select）</h3>
<p>分流策略组我更建议 <code>select</code>：<strong>明确、可控、需要时随时手动切换</strong>。</p>
<pre><code class="language-text">🎯 节点选择 = select,🇭🇰 香港,🇺🇸 美国,🇯🇵 日本,🇨🇳 台湾,🇸🇬 新加坡,DIRECT
✈️ 电报信息 = select,🎯 节点选择,🇭🇰 香港,🇯🇵 日本,🇸🇬 新加坡,🇺🇸 美国
🤖 AIGC = select,🇺🇸 美国,🇯🇵 日本
Ⓜ️ 微软服务 = select,DIRECT,🎯 节点选择,🇭🇰 香港,🇺🇸 美国,🇯🇵 日本,🇨🇳 台湾,🇸🇬 新加坡
🍎 苹果服务 = select,DIRECT,🎯 节点选择,🇭🇰 香港,🇯🇵 日本,🇺🇸 美国,🇨🇳 台湾,🇸🇬 新加坡
🚀 Speedtest = select,DIRECT,&quot;🚀 我的节点&quot;
</code></pre>
<p><code>🎯 节点选择</code>可以理解成“<strong>兜底出口</strong>”：凡是规则没明确指定的海外流量，最终会落到这里。</p>
<p>其他策略组（Telegram / AIGC / Apple / Microsoft）则是“明确单独管理”，偶尔需要切换国家时就很舒服 —— 不用改配置文件，直接在 Surge 面板里点一下就行。</p>
<h3>2.4 特需节点（留一个口子）</h3>
<p>我一般会额外留一个“ALL/全集合”的入口：<br>
用于极少数情况下需要用到“没在国家分组里覆盖”的节点（比如某个很冷门地区、某条特殊落地等）。<br>
这个口子也方便后续做测速/诊断。</p>
<h2>3. Rule</h2>
<p>我以前很爱折腾去广告规则，但各种 App 的兼容问题实在太多，后来就转向：<strong>去广告交给模块，规则集专注分流。</strong><br>
比如微博就装微博去广告模块，不要拿“大而全”的规则集硬刚。</p>
<p>一个老生常谈但很关键的点：<br>
<strong>非 IP 类规则一定放在 IP 类规则之前。</strong><br>
尤其在 Surge iOS 的 Enhanced Mode（Fake-IP）下，这样能尽量避免为了匹配 IP 规则而在本机做额外 DNS 解析。</p>
<p>我这里的规则集直接采用 skk 整理的，大体我用到的就这些：</p>
<ul>
<li>非 IP 类</li>
</ul>
<p>具体<code>非 IP 类</code>配置规则如下：</p>
<pre><code class="language-text">### 非 IP 类规则
# 测速网站及其测速点域名
DOMAIN-SET,https://ruleset.skk.moe/List/domainset/speedtest.conf, 🚀 Speedtest,extended-matching
# &gt; 静态 CDN 域名
DOMAIN-SET,https://ruleset.skk.moe/List/domainset/cdn.conf, 🎯 节点选择,extended-matching
RULE-SET,https://ruleset.skk.moe/List/non_ip/cdn.conf, 🎯 节点选择,extended-matching
# &gt; 流媒体域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/stream.conf, 🇺🇸 美国,extended-matching
# &gt; Telegram 域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/telegram.conf, ✈️ 电报信息,extended-matching
# &gt; Apple &amp; Microsoft 国内 CDN 域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/apple_cdn.conf, DIRECT
RULE-SET,https://ruleset.skk.moe/List/non_ip/microsoft_cdn.conf, DIRECT
# &gt; Apple CN 域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/apple_cn.conf, DIRECT
# &gt; 苹果和微软服务域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/apple_services.conf, 🍎 苹果服务,extended-matching
RULE-SET,https://ruleset.skk.moe/List/non_ip/microsoft.conf, Ⓜ️ 微软服务,extended-matching
# &gt; AIGC 类服务域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/ai.conf, 🤖 AIGC,extended-matching
# &gt; 常见海外域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/global.conf, 🎯 节点选择,extended-matching
# &gt; 国内常见域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/domestic.conf, DIRECT,extended-matching
# &gt; 内网域名
RULE-SET,https://ruleset.skk.moe/List/non_ip/lan.conf, DIRECT
</code></pre>
<p>这里的 <code>extended-matching</code> 作用是：<br>
除了匹配 Fake-IP ↔ 域名映射外，还会参考 <strong>TLS SNI / HTTP Host</strong> 来校正少数 App 的“域名错绑”场景，分流会更稳。</p>
<ul>
<li>IP 类</li>
</ul>
<p>具体<code>IP 类</code>配置规则如下：</p>
<pre><code class="language-text">### IP 类规则
# &gt; Telegram IP 规则
RULE-SET,https://ruleset.skk.moe/List/ip/telegram.conf, ✈️ 电报信息
# &gt; 流媒体 IP
RULE-SET,https://ruleset.skk.moe/List/ip/stream.conf, 🇺🇸 美国
# &gt; 局域网 IP
RULE-SET,https://ruleset.skk.moe/List/ip/lan.conf, DIRECT
# &gt; 国内 IP 段
RULE-SET,https://ruleset.skk.moe/List/ip/domestic.conf, DIRECT
RULE-SET,https://ruleset.skk.moe/List/ip/china_ip.conf, DIRECT
</code></pre>
<ul>
<li>兜底</li>
</ul>
<pre><code class="language-text">FINAL,🎯 节点选择,dns-failed
</code></pre>
<p>当所有规则都没命中时，走 <code>🎯 节点选择</code>。<br>
<code>dns-failed</code> 的意义是：遇到 DNS 失败等异常时也能按策略做兜底处理。</p>
<p>以上就是我所用到的常用类型规则，当然还有一些自己所配置的其他规则，不方便一并说明。大伙参考以上方式逐步添加即可。</p>
<h2>4. Proxy</h2>
<p><code>[Proxy]</code> 用来<strong>一行一个代理</strong>。当你只有少量自建节点、没有订阅可拉取，或者临时想加一条测试节点时，就适合放这里。</p>
<blockquote>
<p>如果你平时主要用 Sub-Store / 订阅管理，那 <code>[Proxy]</code> 可能用得不多；但它依然是“最基础、最直给”的写法：写一行就能用。</p>
</blockquote>
<p>一个简单的例子：</p>
<pre><code>🇭🇰 HK=ss,[url],[port],encrypt-method=2022-blake3-aes-128-gcm,password=&quot;[password]&quot;,udp-relay=true
</code></pre>
<p>代理类型/参数非常多，建议直接看官方文档：<br>
<a href="https://manual.nssurge.com/policy/proxy.html">https://manual.nssurge.com/policy/proxy.html</a></p>
<p>如果你是“家宽 + 落地”这类代理链场景，还可以用 <code>underlying-proxy</code>（建议指向一个稳定的 smart 分组）：</p>
<pre><code class="language-text">🇭🇰 HK=ss,[url],[port],encrypt-method=2022-blake3-aes-128-gcm,password=&quot;[password]&quot;,udp-relay=true,underlying-proxy=[最好指向 smart 的分组]
</code></pre>
<h2>5. 模块</h2>
<p>模块（sgmodule）这块我准备单独写一篇文章展开：包括我常用的模块、以及哪些模块容易踩坑。这里先留个坑，后续补齐并把链接挂回本文。</p>
<h2>6. 仓库</h2>
<p>Surge For iOS 的完整配置文件已在 GitHub 上，请<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Surge/Surge-iOS.conf">点击此处访问</a></p>
<p>至此，<strong>Surge For iOS 自用配置</strong>就完整了。后续如果我对规则、策略组、模块有新的取舍，也会继续在这篇文章里同步更新。</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Mac小企鹅输入法+雾凇拼音配置指南：从安装到同步]]></title>
            <link>https://iyyh.net/posts/2025/04/mac-fcitx5-rime-ice-sync</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/04/mac-fcitx5-rime-ice-sync</guid>
            <pubDate>Sun, 06 Apr 2025 02:06:50 GMT</pubDate>
            <content:encoded><![CDATA[<h2><strong>1. 缘由</strong></h2>
<p>在<strong>iOS</strong>上我用的就是<strong>仓输入法</strong>了，个人认为这是一款<strong>rime</strong>输入法在ios上的<strong>最佳</strong>应用。最近用上mac了，经过推荐，选择小企鹅输入法作为主输入法。结合我之前在仓上使用的方案<strong>雾凇拼音</strong>，就写一篇这方面的简易教程。避免自己后续也忘了哈哈。rime确实久久不配置的话，很多东西都会遗忘，还是有必要记录下来。</p>
<h2><strong>2. 小企鹅输入法</strong></h2>
<h3><strong>2.1 下载</strong></h3>
<ol>
<li>访问官方<a href="https://github.com/fcitx-contrib/fcitx5-macos-installer/blob/master/README.zh-CN.md">下载页面</a></li>
<li>选择<strong>中州韵版</strong>下载</li>
<li>下载完正常安装即可(安装过程就忽略了哈)</li>
<li><a href="https://fcitx-contrib.github.io/docs/">小企鹅输入法官方文档</a></li>
</ol>
<h3><strong>2.2 重要概念</strong></h3>
<p>Rime通过两个目录管理配置：</p>
<table>
<thead>
<tr>
<th><strong>目录类型</strong></th>
<th><strong>路径</strong></th>
<th><strong>作用</strong></th>
<th><strong>操作建议</strong></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>共享目录</strong></td>
<td><code>~/Library/fcitx5/share/rime-data</code></td>
<td>存放默认输入方案（如朙月拼音）</td>
<td>❌ 不要修改</td>
</tr>
<tr>
<td><strong>用户目录</strong></td>
<td><code>~/.local/share/fcitx5/rime</code></td>
<td>存放个性化配置</td>
<td>✅ 主要操作区域</td>
</tr>
</tbody>
</table>
<blockquote>
<p>🛑 重要提醒：所有自定义配置都应在用户目录完成，避免改动共享目录</p>
</blockquote>
<h2><strong>3. 雾凇拼音</strong></h2>
<p>作为当前Rime拼音方案的标杆，<a href="https://dvel.me/posts/rime-ice/">雾凇拼音</a>提供流畅的输入体验。下面介绍最安全的配置方法：</p>
<h3><strong>3.1 一键部署方案</strong></h3>
<p>打开终端（Terminal），逐行执行以下命令：</p>
<pre><code class="language-bash"># 进入用户目录
cd ~/.local/share/fcitx5
# 清理默认的用户配置
rm -rf rime
# 获取最新雾凇拼音方案
git clone https://github.com/iDvel/rime-ice.git rime/ --depth 1
</code></pre>
<p><strong>后续更新</strong>只需执行：</p>
<pre><code class="language-bash">git pull
</code></pre>
<blockquote>
<p>⚠️ 注意：直接修改仓库文件会导致更新冲突，正确做法是使用补丁文件</p>
</blockquote>
<h3><strong>3.2 个性化设置技巧</strong></h3>
<p>补丁文件（<code>.custom.yaml</code>）是安全定制的关键：</p>
<ol>
<li><strong>创建补丁文件</strong> 在用户目录新建对应名称的文件，例如：
<ul>
<li><code>default.custom.yaml</code></li>
<li><code>rime_ice.custom.yaml</code></li>
</ul>
</li>
<li><strong>标准格式模板</strong>：</li>
</ol>
<pre><code class="language-yaml"># 必须以此开头
patch:
  # 精简输入方案示例
  schema_list:
    - schema: rime_ice # 全拼方案
    - schema: double_pinyin_flypy # 小鹤双拼

  # 调整候选词数量
  menu:
    page_size: 8

  # 自定义翻页键（改为方括号）
  key_binder/bindings/+:
    - {when: paging, accept: bracketleft, send: Page_Up}
    - {when: has_menu, send: Page_Down}
</code></pre>
<ol>
<li><strong>推荐配置参考</strong>：
<ul>
<li><a href="https://dvel.me/posts/rime-ice/">雾凇拼音官方文档</a></li>
<li><a href="https://github.com/rime/home/wiki/CustomizationGuide">Rime定制指南</a></li>
</ul>
</li>
</ol>
<h2><strong>4. 多设备同步方案</strong></h2>
<p>通过iCloud同步用户词库，实现跨设备统一体验：</p>
<ol>
<li><strong>修改配置文件</strong> 编辑<code>installation.yaml</code>：</li>
</ol>
<pre><code class="language-yaml"># 设备标识（建议用简短名称）
installation_id: mbp
# iCloud同步路径（需替换实际用户名）
sync_dir: /Users/你的用户名/Library/Mobile Documents/iCloud~dev~fuxiao~app~hamsterapp/Documents/RIME/Rime/sync
</code></pre>
<ol>
<li><strong>同步操作</strong> 在仓输入法和小企鹅中分别点击「同步」按钮，并<strong>重新部署</strong></li>
<li><strong>效果验证</strong> 新设备输入时会自动加载历史词频</li>
</ol>
<h2>5. 强烈建议查看<a href="https://dvel.me/posts/rime-ice/">雾凇拼音官方文档</a>！</h2>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Winodws 双网卡实现内外网分流]]></title>
            <link>https://iyyh.net/posts/2025/03/windows-dual-nic-routing</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/03/windows-dual-nic-routing</guid>
            <pubDate>Thu, 20 Mar 2025 02:53:51 GMT</pubDate>
            <content:encoded><![CDATA[<h2>1. 缘由</h2>
<p>公司在网络方面做了些许限制，因此有了这次的探索。刚好电脑有两张网卡。就通过<code>路由表</code>简单做一下分流即可实现一定突破。</p>
<h2>2. 前置条件</h2>
<ul>
<li>有线网卡(专门用来连通<strong>内网</strong>)</li>
<li>无线网卡(专门用来连通<strong>外网</strong>)</li>
</ul>
<h2>3. 操作过程</h2>
<p>Windows默认的流量出口优先级始终是 <strong>有线网卡</strong> 优先于 <strong>无线网卡</strong> 。因此呢，我们要尝试破坏这个优先级。</p>
<h3>3.1 获取网卡ip及网关</h3>
<p>打开<code>cmd</code> (<code>Win + R</code> input <code>cmd</code>)</p>
<pre><code class="language-bat">ipconfig
</code></pre>
<p>输出结果大致如下:</p>
<pre><code class="language-text">以太网适配器 以太网:

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . :
   IPv4 地址 . . . . . . . . . . . . : 192.168.1.8
   子网掩码  . . . . . . . . . . . . : 255.255.255.0
   默认网关. . . . . . . . . . . . . : 192.168.1.254

无线局域网适配器 WLAN:

   连接特定的 DNS 后缀 . . . . . . . :
   本地链接 IPv6 地址. . . . . . . . :
   IPv4 地址 . . . . . . . . . . . . : 10.0.4.6
   子网掩码  . . . . . . . . . . . . : 255.255.248.0
   默认网关. . . . . . . . . . . . . : 10.0.0.254
</code></pre>
<p><strong>核心信息：</strong></p>
<p>需要拿到 <strong>IP地址 以及 网关</strong> 后续做路由表需要用到</p>
<h3>3.2 修改路由表</h3>
<p><code>cmd</code>执行：</p>
<pre><code class="language-bat">route print -4
</code></pre>
<p>输出结果大致如下：</p>
<pre><code class="language-text">IPv4 路由表
===========================================================================
活动路由:
网络目标        网络掩码          网关       接口   跃点数
          0.0.0.0          0.0.0.0     192.168.1.254    192.168.1.8     25
          0.0.0.0          0.0.0.0         10.0.0.254       10.0.4.6     30
         10.0.0.0    255.255.248.0            在链路上        10.0.4.213    286
       10.0.4.231  255.255.255.255            在链路上        10.0.4.213    286
===========================================================================
永久路由:
  无
</code></pre>
<p>重点其实就是看最上方的 <code>0.0.0.0</code> ， 可以看到路由表优先让 <strong>有线网卡排在无线网卡之前</strong> (看跃点数 <strong>越小越优先</strong>)</p>
<p>因此我们需要在这里做下修改。</p>
<ol>
<li>
<p>删除默认路由</p>
<pre><code class="language-nginx">route delete 0.0.0.0
</code></pre>
</li>
<li>
<p>添加外网路由(走无线网卡)</p>
<pre><code class="language-apache">route add 0.0.0.0 mask 0.0.0.0 10.0.0.254 metric 10
</code></pre>
<p>metric指代跃点数(优先级)</p>
</li>
<li>
<p>添加内网路由(走有线网卡)</p>
<pre><code class="language-apache"># 以192.168.0.0/16为例
route add 192.168.0.0 mask 255.255.0.0 192.168.1.254 metric 5 -p
</code></pre>
<p><code>-p</code>指代<strong>永久路由</strong>，也就是重启也不会修改这份自己配置的路由表</p>
<p>具体还有哪些内网需要走内网网卡的，请自行根据以上例子进行补充。</p>
</li>
</ol>
<p>至此，就可以实现内外网分离了。但是如果每次都要输入这么一大坨命令，那可实在是太累了，因此贴一份<code>bat</code>脚本</p>
<p>请根据自己的<strong>实际网络环境</strong>进行修改！</p>
<pre><code class="language-prolog">@echo off
echo ============================================
echo     Windows内外网分流配置工具
echo     author：iyyh.net
echo     时间：%date% %time%
echo ============================================
echo.

:: 检查管理员权限
net session &gt;nul 2&gt;&amp;1
if %errorlevel% neq 0 (
    echo 错误: 请以管理员身份运行此批处理！
    echo 请右键点击此文件，选择&quot;以管理员身份运行&quot;。
    echo.
    pause
    exit /b 1
)

:: 确保备份目录存在
if not exist &quot;D:\network\network_route_print&quot; (
    echo [信息] 创建备份目录...
    mkdir &quot;D:\network\network_route_print&quot;
)

echo [信息] 开始配置内外网分流...
echo [信息] 正在备份当前路由表...
route print &gt; &quot;D:\network\network_route_print\route_backup_%date:~0,4%%date:~5,2%%date:~8,2%_%time:~0,2%%time:~3,2%%time:~6,2%.txt&quot;
echo [信息] 路由表已备份到 D:\network\network_route_print

echo.
echo [步骤1] 删除现有默认路由...
route delete 0.0.0.0
if %errorlevel% equ 0 (
    echo [成功] 默认路由已删除
) else (
    echo [警告] 删除默认路由可能出现问题，继续执行...
)

echo.
echo [步骤2] 添加外网默认路由（走无线网卡）...
route add 0.0.0.0 mask 0.0.0.0 10.0.0.254 metric 10
if %errorlevel% equ 0 (
    echo [成功] 外网默认路由已添加
) else (
    echo [错误] 添加外网默认路由失败！
    goto error
)

echo.
echo [步骤3] 添加内网路由（走有线网卡）...
echo [信息] 添加192.168网段路由...
route add 192.168.0.0 mask 255.255.0.0 192.168.1.254 metric 5 -p
if %errorlevel% equ 0 (
    echo [成功] 192.168网段路由已添加
) else (
    echo [错误] 添加192.168网段路由失败！
    goto error
)

echo.
echo [步骤4] 验证路由配置...
echo [信息] 当前路由表配置如下：
echo.
route print | findstr /C:&quot;0.0.0.0&quot; /C:&quot;192.168&quot;
echo.
echo ============================================
echo [成功] 内外网分流配置已完成！
echo ============================================
goto end

:error
echo.
echo [错误] 配置过程中出现错误，请检查网络连接和账户权限！
echo [建议] 请确保有线网卡和无线网卡正常工作，并以管理员身份运行此批处理。

:end
echo.
echo 按任意键退出...
pause &gt; nul
</code></pre>
<p>最后，请注意数据<strong>安全</strong>！</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[VSCode 配置Ruff]]></title>
            <link>https://iyyh.net/posts/2025/02/vscode-ruff-config</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/02/vscode-ruff-config</guid>
            <pubDate>Tue, 11 Feb 2025 03:00:41 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1. 为什么选择Ruff</h3>
<p>引用<a href="https://github.com/astral-sh/ruff">官方</a>原话： <code>An extremely fast Python linter and code formatter, written in Rust.</code></p>
<p>一个用Rust编写的<strong>极速Python代码检查器</strong>和<strong>格式化</strong>工具</p>
<p>官方的一张测试图：</p>
<p><img src="https://image.iyyh.net/image-xvqj.png" alt="ruff 截图"></p>
<p>因此选择<strong>Ruff</strong></p>
<h3>2. VS Code/Cursor 具体配置</h3>
<h4>2.1 setting.json</h4>
<p>快捷键： <code>Ctrl+Shift+P</code></p>
<p>键入： <code>setting.json</code></p>
<p><img src="https://image.iyyh.net/image-eddu.png" alt="settings"></p>
<p>选<code>打开用户设置</code></p>
<h4>2.2 配置</h4>
<p>在适当的位置加入下方代码</p>
<pre><code class="language-jsonc">{
  // jupyter配置
  &quot;notebook.formatOnSave.enabled&quot;: true,
  &quot;notebook.codeActionsOnSave&quot;: {
    &quot;notebook.source.fixAll&quot;: &quot;explicit&quot;,
    &quot;notebook.source.organizeImports&quot;: &quot;explicit&quot;
  },
  // Python配置
  &quot;[python]&quot;: {
    &quot;editor.formatOnSave&quot;: true,
    &quot;editor.codeActionsOnSave&quot;: {
      &quot;source.fixAll&quot;: &quot;explicit&quot;,
      &quot;source.organizeImports&quot;: &quot;explicit&quot;
    },
    &quot;editor.defaultFormatter&quot;: &quot;charliermarsh.ruff&quot;
  }
}
</code></pre>
<p>这样配置后即可通过 <code>Ctrl+S</code> 保存文件的同时，自动进行<strong>格式化代码</strong>的操作~</p>
<p>同样适配<code>cursor</code>等根据 vscode 进行二开的编辑器</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Cursor修改垂直布局]]></title>
            <link>https://iyyh.net/posts/2025/02/cursor-modify-vertical-layout</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2025/02/cursor-modify-vertical-layout</guid>
            <pubDate>Tue, 11 Feb 2025 02:50:06 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1. 起因</h3>
<p>相信有一部分尝鲜的小伙伴已经使 <code>Cursor</code> 很长一段时间了，但是在从<code>VSCode</code> 迁移到 <code>Cursor</code> 的时候发现迎面而来的布局非常不适应，想修改成原来 <code>VSCode</code> 的垂直布局。解决方案如下</p>
<h3>2. 解决方案</h3>
<p>快捷键： <code>Ctrl + , </code> 打开设置页面</p>
<p>搜索框输入： <code>workbench.activityBar.orientation</code></p>
<p>根据图片 选择 <code>vertical</code></p>
<p><img src="https://image.iyyh.net/image-atlm.png" alt="cursor setting"></p>
<p>最后根据提示重启 <code>Cursor</code> 即可恢复同 <code>VSCode</code> 相同布局</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Clash Party/Clash Verge Rev/Sparkle 覆写与扩展脚本指南]]></title>
            <link>https://iyyh.net/posts/2024/10/mihomo-extension-script</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/10/mihomo-extension-script</guid>
            <pubDate>Tue, 29 Oct 2024 01:14:10 GMT</pubDate>
            <description><![CDATA[详细介绍 Mihomo Party（现 Clash Party）、Clash Verge Rev 与 Sparkle 的覆写与扩展脚本设置方法，含规则优化、DNS覆写、代理组配置等完整教程。]]></description>
            <content:encoded><![CDATA[<p>再开始阅读本篇文章之前，强烈建议各位同学优先看这篇文章：<a href="https://iyyh.net/posts/2024/09/mihomo-self-config">Mihomo 配置：自用配置文件与思路分享</a> 再观看以下内容，理解起来可能更为顺畅！</p>
<h2>1. 缘起</h2>
<p>大部分同学接触 Clash 都是从客户端开始的，比如 Clash for Windows。发展至今，几乎所有主流客户端都支持了 <strong>覆写脚本/扩展脚本</strong> 功能，例如 Clash Party、Sparkle、FLClash、Clash Verge Rev 等，这也给了我们更多自定义的空间。</p>
<p>本文分享一下我的覆写思路与脚本，跟上篇一样，不想看碎碎念的可以直接去仓库取用：</p>
<ul>
<li>仓库：<a href="https://github.com/yyhhyyyyyy/selfproxy">https://github.com/yyhhyyyyyy/selfproxy</a></li>
<li>覆写/扩展脚本：<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/Extension_Script/script.js">https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/Extension_Script/script.js</a></li>
</ul>
<p>接下来分三个部分讲解：<code>覆写内容</code>、<code>Mihomo Party 覆写</code>、<code>Clash Verge Rev 扩展脚本</code></p>
<p>⚠️ 我主要使用的是布丁狗还在担任 core dev 时期的 Mihomo Party，Sparkle 只短暂体验过，因此文中统一以 Mihomo Party 为例进行说明，同样适用于上述其他客户端。</p>
<h2>2.覆写内容</h2>
<h3>2.1 覆写规则</h3>
<p>规则是 Mihomo 中最核心的部分，所以放在最前面讲。</p>
<p>我的整体规则组成很简单 ，大体分成两个部分且请遵循我写的先后顺序：<code>nonip(非ip类)</code>&gt;<code>ip(ip类)</code> 原因请看 <a href="https://iyyh.net/posts/2024/09/mihomo-self-config#_7-mihomo-%E5%88%86%E6%B5%81%E8%A7%84%E5%88%99%E9%85%8D%E7%BD%AE">Mihomo 分流规则配置</a></p>
<ul>
<li>
<p>nonip</p>
<p><code>customRules</code>&gt;<code>nonipRules</code></p>
<p>最早，我支持在 rules 里补充去广告规则的，但随着使用加深，总会带来一些体验上的不便，因此<strong>不再主张在 rules 中补充去广告规则</strong>。</p>
<p>整体顺序是：先放自定义规则集（<code>customRules</code>，用于保证特定规则的优先级，nonip 和 ip 类都可以放），再放非 ip 类规则集即可。</p>
</li>
<li>
<p>ip</p>
<p>直接放入 <code>ipRules</code> 即可</p>
<p>最后的顺序也就是 <code>customRules</code>&gt;<code>nonipRules</code>&gt;<code>ipRules</code></p>
</li>
</ul>
<pre><code class="language-javascript">// 覆写规则
function overwriteRules(params) {
  const customRules = [
    // 在此添加自定义规则，比如对于百度这个域名使用直连：
    // &quot;DOMAIN,baidu.com,DIRECT&quot;,
  ]

  const nonipRules = [
    'RULE-SET,cdn_domainset,🎯 节点选择',
    // ... 此处省略更多非 IP 规则项，具体请到仓库查看覆写脚本
  ]

  const allNonipRules = [
    ...customRules,
    ...nonipRules
  ]

  const ipRules = [
    // 依据 ip 类规则顺序添加即可，具体请到仓库查看覆写脚本
  ]

  const rules = [
    // 非ip类规则
    ...allNonipRules,
    // ip类规则
    ...ipRules
  ]
}
</code></pre>
<h3>2.2 覆写代理组</h3>
<p>思路如下：</p>
<ol>
<li>
<p>写好<code>包含正则</code>以及<code>排除正则</code>两者合并构造<code>总的国家正则</code></p>
</li>
<li>
<p>写个找正则的函数</p>
<pre><code class="language-javascript">function getProxiesByRegex(params, regex) {
  const matchedProxies = params.proxies.filter (e =&gt; regex.test (e.name)).map (e =&gt; e.name)
  return matchedProxies.length &gt; 0 ? matchedProxies : ['COMPATIBLE']
}
</code></pre>
</li>
<li>
<p>生成自动选择代理组</p>
<pre><code class="language-javascript">const autoProxyGroups = autoProxyGroupRegexs
  .map (item =&gt; ({
    name: item.name,
    type: 'url-test',
    url: 'https://cp.cloudflare.com',
    interval: 300,
    tolerance: 50,
    proxies: getProxiesByRegex (params, item.regex),
    hidden: true,
  }))
  .filter (item =&gt; item.proxies.length &gt; 0)
</code></pre>
</li>
<li>
<p>手动选择代理组类似，不过这边加入了图标icon，以显示的更佳美观~具体请看仓库，代码其实差不多</p>
</li>
<li>
<p>划分不同的代理组</p>
<p>贴个最后出来的效果图：<br>
<code>mihomo party</code>:</p>
<p><img src="https://image.iyyh.net/20251106085723549.png" alt="party"></p>
<p><code>clash verge rev</code>:<br>
<img src="https://image.iyyh.net/20251106085812097.png" alt="verge rev"></p>
</li>
</ol>
<h3>2.3 覆写DNS</h3>
<p>DNS老生长谈了，这边就带过吧，如果还有疑问，可以看上篇文章 <a href="https://iyyh.net/posts/2024/09/mihomo-self-config">Mihomo自用配置</a></p>
<p>再简单说下我的观点，还是依旧，如果网络环境文明，那么直接使用运营商提供的DNS，如果网络环境不文明再用公共DNS。这边每个人都有每个人的见解，按照你自己的习惯想法来吧，我只不过是赞同我所理解的观点。</p>
<p>配置如下：</p>
<pre><code class="language-javascript">// 覆写DNS
function overwriteDns(params) {
  const dnsList = [
    'https://223.5.5.5/dns-query',
    'https://doh.pub/dns-query',
  ]

  const proxyDnsList = [
    'https://223.5.5.5/dns-query',
    'https://doh.pub/dns-query',
  ]

  const dnsOptions = {
    'enable': true,
    'ipv6': false,
    'prefer-h3': true, // 如果 DNS 服务器支持 DoH3 会优先使用 h3
    'respect-rules': true, // 仅对符合规则的请求使用 DNS
    'enhanced-mode': 'fake-ip', // 伪装 IP
    'fake-ip-range': '28.0.0.1/8',
    'nameserver': dnsList, // 其他网络请求都归他管
    'proxy-server-nameserver': proxyDnsList, // 代理服务器的 DNS
  }
  params.dns = { ...dnsOptions }
}
</code></pre>
<p>还需要补充一下其中的 <code>fake-ip-filter</code></p>
<p>这个我留个坑，后面有空写个action自动同步<a href="https://ruleset.skk.moe/Internal/clash_fake_ip_filter.yaml">上游</a>的<code>fake-ip-filter</code> 然后更新整份覆写脚本</p>
<p>目前就先硬编码写死 具体看仓库</p>
<h3>2.4 覆写基本配置项</h3>
<p>这边就没啥好讲的了直接贴上来吧</p>
<pre><code class="language-javascript">// 覆写Basic Options
function overwriteBasicOptions(params) {
  const otherOptions = {
    'mixed-port': 7890,
    'allow-lan': true,
    'unified-delay': true,
    'tcp-concurrent': true,
    'find-process-mode': 'strict',
    'global-client-fingerprint': 'chrome',
    'profile': {
      'store-selected': true,
      'store-fake-ip': true,
    },
    'ipv6': false,
    'mode': 'rule',
    'log-level': 'warning',
    'udp': true,
    'sniffer': {
      'enable': true,
      'sniff': {
        HTTP: {
          'ports': [80, '8080-8880'],
          'override-destination': true,
        },
        TLS: {
          ports: [443, 8443],
        },
        QUIC: {
          ports: [443, 8443],
        },
      },
      'skip-domain': ['Mijia Cloud', '+.push.apple.com']
    },
  }
  Object.keys (otherOptions).forEach ((key) =&gt; {
    params[key] = otherOptions[key]
  })
}
</code></pre>
<p>这部份就是覆写的内容咯，具体脚本还是建议去我<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/Extension_Script/script.js">仓库</a>看看，接下来就是如何在mihomo party上使用了。</p>
<h3>2.5 覆写Tunnel</h3>
<p>我个人还是比较推崇Tunnel模式的，也建议大伙使用Tunnel模式，比系统代理香不少~</p>
<p>还是老生长谈，stack的选择请看这边文章<a href="https://iyyh.net/posts/2024/08/tunnel-difference#_4-%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9">tunnel stack如何选择</a> 不想看也没事 结论就是 一个个测试过去 测试顺序 <code>system</code>&gt;<code>mixed</code>&gt;<code>gvisor</code> 哪个最先能用 用哪个。</p>
<pre><code class="language-csharp">// 覆写Tunnel
function overwriteTunnel (params) {
    const tunnelOptions = {
        enable: true,
        stack: &quot;system&quot;,
        device: &quot;tun0&quot;,
        &quot;dns-hijack&quot;: [&quot;any:53&quot;, &quot;tcp://any:53&quot;],
        &quot;auto-route&quot;: true,
        &quot;auto-detect-interface&quot;: true,
        &quot;strict-route&quot;: true,
    };
    params.tun = { ...tunnelOptions };
}
</code></pre>
<p><strong>PS:Tunnel目前在mihomo party中没法覆写，只能通过GUI面板配置，留个占位坑，后续如果可以覆写了，直接用就行</strong></p>
<p><strong>但是在clash verge rev中是可以使用的</strong></p>
<h3>2.6 覆写FakeIpFilter</h3>
<p>这部分就是对这些地址，不使用fakeip的解析方式，而直接使用realip进行解析。</p>
<p>该部分已经实现了<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/.github/workflows/update_mihomo_config.yml">github action</a>的自动更新<a href="https://ruleset.skk.moe/Internal/clash_fake_ip_filter.yaml">上游</a>的方式。具体是搭配仓库内的<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/Extension_Script/auto_update.py">python脚本</a>。有兴趣的同学可以去仓库里看看。</p>
<pre><code class="language-javascript">// 覆写DNS.Fake IP Filter
function overwriteFakeIpFilter(params) {
  const fakeIpFilter = [
    // 具体有哪些地址，请看上游，或者去仓库直接copy脚本使用即可
  ]
  params.dns['fake-ip-filter'] = fakeIpFilter
}
</code></pre>
<h3>2.7 覆写NameserverPolicy</h3>
<p>实际上就是DNS分流，通俗易懂一些，你是阿里的域名，我就用阿里的DNS服务器解析自家的域名，这样更友好。</p>
<pre><code class="language-javascript">// 覆写DNS.Nameserver Policy
function overwriteNameserverPolicy(params) {
  const nameserverPolicy = {
    // 很多，具体映射看仓库脚本
  }
  params.dns['nameserver-policy'] = nameserverPolicy
}
</code></pre>
<h3>2.8 覆写hosts</h3>
<p>搭配上面的覆写NameserverPolicy。</p>
<pre><code class="language-javascript">// 覆写hosts
function overwriteHosts(params) {
  const hosts = {
    'dns.alidns.com': ['223.5.5.5', '223.6.6.6', '2400:3200:baba::1', '2400:3200::1'],
    'doh.pub': ['120.53.53.53', '1.12.12.12'],
    'localhost': ['127.0.0.1']
  }
  params.hosts = hosts
}
</code></pre>
<h2>3. Mihomo Party 覆写</h2>
<h3>3.0 基本设置</h3>
<p>请先参考我的设置页进行一次基础设置，否则可能覆写脚本不一定完全生效！</p>
<p><img src="https://image.iyyh.net/20251106090319530.png" alt="party 基本设置"></p>
<p><img src="https://image.iyyh.net/20251106090352614.png" alt="party subsotre"></p>
<p><img src="https://image.iyyh.net/image-dwly.png" alt="party 图标"></p>
<p><img src="https://image.iyyh.net/image-bwgg.png" alt="party 接管 dns"></p>
<h3>3.1 Sub-Store订阅节点</h3>
<p>mihomo party很好的其中一个点就是在集成了 sub-store 这是非常好用的工具，我在surge上也是必装的， 怎么添加节点具体看接下来的图</p>
<p><img src="https://image.iyyh.net/image-20241029095133530.png" alt="substore 添加节点"></p>
<p><img src="https://image.iyyh.net/image-20241029095351223.png" alt="substore 添加节点 2"></p>
<p><img src="https://image.iyyh.net/image-20241029095607167.png" alt="substore 添加节点 3"></p>
<p>如果有多个节点一个个添加单条订阅进来就行。</p>
<p>因为我有多节点，所以我会用到组合订阅，组合订阅请继续看</p>
<p><img src="https://image.iyyh.net/image-20241029095803156.png" alt="substore 组合订阅"></p>
<h3>3.2 导入覆写</h3>
<ol>
<li>如果能与github连通，那么可以使用远程导入</li>
</ol>
<p><img src="https://image.iyyh.net/image-20241029100126408.png" alt="party 链接导入覆写"></p>
<ol>
<li>如果不能连通，就直接本地导入</li>
</ol>
<p><img src="https://image.iyyh.net/image-20241029100209728.png" alt="party 覆写本地导入"></p>
<p><img src="https://image.iyyh.net/image-20241029100233935.png" alt="party 覆写本地导入 2"></p>
<p>把仓库里的脚本全部复制进来就行</p>
<h3>3.3 订阅管理</h3>
<p><img src="https://image.iyyh.net/image-20241029095927328.png" alt="party 导入订阅"></p>
<p><img src="https://image.iyyh.net/image-20241029100350672.png" alt="party 配置覆写"></p>
<p><img src="https://image.iyyh.net/image-20241029100422580.png" alt="party 配置覆写 2"></p>
<p>选择刚刚导入或者新建的覆写文件，然后保存即可。</p>
<h3>3.4 补充Tunnel面板设置</h3>
<p><img src="https://image.iyyh.net/image-zdwc.png" alt="party tunnel 配置"><br>
可以参照我的设置打开开关以及填写内容即可</p>
<h2>4. Clash Verge Rev 扩展脚本</h2>
<h3>4.1 订阅</h3>
<p>把订阅链接放进来就行，点击下导入<br>
<img src="https://image.iyyh.net/image-gcmt.png" alt="verge rev 导入订阅"></p>
<p>如果有自己的本地yaml配置文件，新建个本地配置即可</p>
<p><img src="https://image.iyyh.net/image-gnth.png" alt="verge rev 导入本地配置文件"></p>
<h3>4.2 编辑全局扩展脚本</h3>
<p><img src="https://image.iyyh.net/image-fwyt.png" alt="verge rev 配置全局扩展脚本 1"></p>
<p><img src="https://image.iyyh.net/image-uglw.png" alt="verge rev 配置全局扩展脚本 2"></p>
<p>从<a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/Mihomo_Party/party.js">仓库</a>中复制脚本进来就行。</p>
<h3>4.3 开启Tunnel即可</h3>
<p>我自己是常用Tunnel，可根据自己需求而来</p>
<p><img src="https://image.iyyh.net/image-twrh.png" alt="rev tunnel 开启"></p>
<h2>5. 交流</h2>
<p>TG： <a href="https://t.me/iyyhchannel">Channel</a></p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[解决 WSL2 与 Tunnel 模式网络冲突：MTU 设置妙招]]></title>
            <link>https://iyyh.net/posts/2024/09/wsl2-tunnel-mtu-fix</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/09/wsl2-tunnel-mtu-fix</guid>
            <pubDate>Thu, 26 Sep 2024 02:20:14 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1. 起因</h3>
<p>最近由于条件问题，没法使用公司服务器，但是部署dify的最佳条件是在Linux上，本来想继续沿用我以前的做法，装VMware。后面了解到有WSL这一虚拟机，因此决定使用其作为部署dify的设备。且dify又得内网都能使用，这边参考了一篇<a href="https://www.sxrhhh.top/blog/2023/12/14/connect-to-wsl/">blog</a>，因此只能使用WSL2的镜像模式了。附上<code>.wslconfig</code>配置:</p>
<pre><code class="language-ini">[experimental]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true
hostAddressLoopback=true
</code></pre>
<h3>2. 具体问题</h3>
<p>我的Windows本机是常年开启mihomo的，并且我也经常使用的是tunnel模式。但是我发现，一旦我开启tunnel模式，WSL2里面的网络环境就会异常，基本上就是处于无法上网的情形。看了不少文章，说改<code>stack</code>成<code>gVisor</code>就行，然而实际测试下来是不行的。</p>
<h3>3. 解决方案</h3>
<p>只需要在mihomo中的<code>tun</code>部分的<code>mtu</code>改成<code>1500</code>即可</p>
<pre><code class="language-yaml">tun:
  enable: true
  stack: system
  device: utunmiho
  dns-hijack:
    - any:53
    - 'tcp://any:53'
  auto-route: true
  auto-detect-interface: true
  strict-route: true
  mtu: 1500
</code></pre>
<p>至此 问题直接迎刃而解，具体缘由不太清楚，后续如果有深入再做补充，也请有相关经验的朋友给予帮助~</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Mihomo 配置：自用配置文件与思路分享]]></title>
            <link>https://iyyh.net/posts/2024/09/mihomo-self-config</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/09/mihomo-self-config</guid>
            <pubDate>Tue, 03 Sep 2024 13:04:48 GMT</pubDate>
            <content:encoded><![CDATA[<blockquote>
<p>这是一篇关于 <strong>Mihomo</strong>（原 Clash Meta，基于 Clash 二次开发）<strong>配置</strong>的详细教程，分享我的自用配置文件、配置思路与最佳实践。</p>
</blockquote>
<h2>1. 缘由</h2>
<p>clash系列算是自己接触代理最早的内核了，虽然期间也有接触过v2ray，不过有很长一段时间我都是以clash为主用。直到 23 年换成 iPhone 后，我才开始使用 Surge，因为其在ios/mac上确实有更好的体验（且配置写起来也相对容易一些）。后面有一段时间又折腾了sing-box了（不过由于一些客观原因，后续不会再折腾 sing-box 了），最近闲下来，觉得有必要写一个关于mihomo的配置以及想法。</p>
<p>对于一些用户想直接看全部配置文件的(不想看我碎碎念的)可以直接到<a href="https://github.com/yyhhyyyyyy/selfproxy">仓库</a>中查看。</p>
<p>以下都以仓库中的 <a href="https://github.com/yyhhyyyyyy/selfproxy/blob/main/Mihomo/mihomo_single.yaml"><strong>mihomo_single.yaml</strong></a> 为例。</p>
<h2>2. Mihomo 全局配置</h2>
<p>先贴配置：</p>
<pre><code class="language-yaml">mixed-port: 7897
allow-lan: true
mode: rule
log-level: warning
ipv6: false
find-process-mode: strict
unified-delay: true
tcp-concurrent: true
global-client-fingerprint: chrome

# ## 如果使用的是裸核，需要将下面的注释去掉，方便ui界面的使用
# external-controller: 0.0.0.0:9988
# external-ui: ui
# external-ui-url: 'https://github.com/Zephyruso/zashboard/releases/latest/download/dist.zip'
# secret: &quot;yyhhyyyyyy&quot;

profile:
  store-selected: true
  store-fake-ip: true
</code></pre>
<p>解释：</p>
<p><code>mixed-port</code> : 混合代理端口。如：http或者socks代理时，直接用这个端口就行</p>
<p><code>allow-lan</code> : 允许局域网连接。如：允许其他设备经过 Mihomo的代理端口访问互联网</p>
<p><code>mode</code> : 选用什么模式运行mihomo。可选值: <code>rule</code> 、 <code>global</code> 、 <code>direct</code> 大部分情况下我们都用 <code>rule</code> 即规则模式，根据我们的分流配置来使用</p>
<p><code>log-level</code> : 日志输出级别。</p>
<p><code>ipv6</code> : 非刚需就不开。(目前的网络环境还是推荐在ipv4环境下，避免产生一些奇怪的问题，如果有需求可以开启)</p>
<p><code>find-process-mode</code> : 控制 Mihomo 是否识别连接所属的进程，并按进程维度进行规则匹配。使用默认即可。</p>
<p><code>unified-delay</code> : 统一延迟。测出来的结果“是你希望看到的，也就是时延会更快”</p>
<p><code>tcp-concurrent</code> : TCP并发，当有多个 dns 时，会解析出所有 IP 地址进行连接，默认使用第一个解析成功的 IP。</p>
<p><code>external-controller</code> : ui界面访问端口。</p>
<p><code>external-ui</code> : ui界面在本地文件夹的命名</p>
<p><code>external-ui-url</code> : 使用的ui界面的url地址</p>
<p><code>secret</code> : api的密钥，建议都设置上</p>
<p><code>profile</code> : 缓存 分别：1. 储存 API 对策略组的选择，以供下次启动时使用 2. 储存 fakeip 映射表，域名再次发生连接时，使用原有映射地址</p>
<p><strong>这部分如果不知道你想要的效果是什么，请与我一致不做修改</strong></p>
<h2>3. Mihomo DNS 配置</h2>
<p>在开始之前，大家可以先看一下Sukka的[《是什么，为什么，怎么做 —— 谈谈 DNS 泄漏、CDN 访问优化与 Fake IP》]这篇文章(<a href="https://blog.skk.moe/post/lets-talk-about-dns-cdn-fake-ip/">https://blog.skk.moe/post/lets-talk-about-dns-cdn-fake-ip/</a>)</p>
<h3>3.1 DNS 泄露？</h3>
<p>说到DNS，肯定就得说到 <strong>DNS泄露</strong> 了。</p>
<p>其实我自己也有一段时间陷入过 <strong>DNS泄露</strong> 这个名词的”恐怖折腾“中，现在想想其实真的有点笨。为什么呢？</p>
<p>首先先简单解释下什么是 <strong>DNS泄露</strong> 简单理解，当你在访问一个需要代理才能访问的域名，比如<code>google.com</code>；我们在获取其ip的过程中，不是使用的代理的服务器的dns去解析 <code>google.com</code> 这个域名 ，而是使用你当前所用的网络环境的DNS，对<code>google.com</code>这个域名进行解析。那么这个过程就是所谓的 <strong>DNS泄露</strong> 。</p>
<p>再者还有一部分人会说，会用 <strong>DNS解析</strong> 来让网站来描绘用户的画像？这点更是天方夜谈了，除了 <code>google</code> 的DNS节点能基本遍布全世界，其他家的DNS节点 不是这个国家缺，就是那个国家缺的。如果你是网站的运营者，那么你会用这个来描绘用户的画像吗？ 比如你在一个很偏僻的国家 A 这个国家 <code>google</code> 没有DNS节点 ，那你如果用<code>google</code>的DNS来进行DNS解析，一般会给你找邻国附近 B 国的DNS节点，那么网站的运营者就会以此来判断你是 B 国的人吗？ 肯定不会的，这太扯了。</p>
<p>他有什么危害，其实看了这么多文章，都在说可能会 &quot;导致用户的真实IP地址和网络活动可能被泄露给第三方&quot;。 但是试问现在的网民全世界有大，有必要说盯着“您”的网络活动吗？ 应该不至于吧哈哈 。再者，其实当规则写好，遵循后文我描述的方式，那么 DNS 泄露既能最大程度上规避。</p>
<p>再来个简单的例子，你会说闽南语，但是我可以直接判断你是会讲闽南语地区的人吗？ 也肯定不会，因为有可能你是后天学习的。因此，这是同理的。</p>
<p>因此 <strong>DNS泄露</strong> 其实是有一定危言耸听的成分在里面的， 正确的叫法 应该是 <strong>DNS 出口查询</strong>。</p>
<p>本质上来说，你DNS的出口的IP和你网络的出口IP的<strong>地理位置</strong>是否一致，可以很大程度的决定，你的CDN解析是不是最优解。 也就是说你与你访问的那个网站，能否有更好的网络通信效果。</p>
<p>综上，<strong>DNS泄露</strong> 这个名词相信已经有了更好的认识，看到这里，你还会觉得它的问题特别大吗？还会很膈应你么？</p>
<p>当然，这是我自己认可的观点，如果你有自己认可的观点，那按照你所认可的观点来理解就好了。我只是将我自己认可的观点讲述出来罢了。说到底，在世界巨大的网络池子中，其实最上游一定会有日志记录的。比如你使用的机场，那机场是有日志记录的；你说你自建，那对应的 vps 厂商也是会有日志记录的。哪天真的需要溯源你的网络日志的话，那其实你也是躲避不过的。</p>
<h3>3.2 DNS选择</h3>
<p>能看到这里，说明已经对 <strong>DNS泄露</strong> 已经没那么排斥了。接下来，有这么多的 DNS 服务厂商要怎么选择？ 相信大家头也大，为什么选择阿里，为什么选择腾讯，为什么选择 cloudflare 等等，接下来简单阐述下。</p>
<p>在开始前，希望你能明白一件事，运营商的DNS服务，<strong>蛮不错</strong>，延迟一定是所有厂商里，排名top的！（有点绝对哈，但是绝大多数都是排top是肯定的）。但是，有前提，<strong>分流必须写好</strong>，且国内相对文明的网络环境下走运营商DNS一点问题都没，但是国外或者不文明的网络环境的就有问题了。</p>
<p>这里要提一嘴运营商的DNS在一定情形下，蛮不讨人喜的，比如<strong>DNS拦截</strong>，偷偷给你上广告等。但是正常国内域名使用自家运营商的DNS进行解析效果还是很不错的（主要是真的很快），因此做推荐。当然，如果为了省事，那肯定直接用公共DNS即可，当然推荐使用<strong>加密DNS</strong>。</p>
<p>至于公共DNS，国内的阿里或者腾讯直接用就好，如果硬要说谁稳定点，那阿里肯定是稍胜一筹的，毕竟做这块很久了，老大哥了。但是如果用这种公共DNS遇到特殊时期的时候，可能不同的DNS厂商会“打架”，会出现阿里解析阿里家的没有问题，但是解析别家的就有问题了。这方面，运营商提供的 DNS 就没这个问题，还是相对公平公正的。这就是运营商 DNS 服务 为什么好的其中一个原因。</p>
<p>至于国外比较权威的就是cloudflare和google咯，一般这两家也会比较公平公正，我一般如果要用的话这两家都会放在配置里（不过我一般不用，因为我用 fake-ip）。</p>
<p>加密 DNS 额外提一嘴，阿里和腾讯都有各自的付费加密 DNS，但是每个月都有免费额度。对于个人用户而言一般是够用，我是使用的付费加密 DNS 服务，没有使用他们的公共加密 DNS 服务。</p>
<h3>3.3 DNS配置</h3>
<p>说了这么多，先贴配置</p>
<pre><code class="language-yaml">dns:
  enable: true
  prefer-h3: true
  ipv6: false
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  # fake-ip-filter 这部分内容相对较长，请看仓库
  nameserver:
    # 网络环境文明的话推荐直接使用运营商的DNS服务器 或者 如果知道自己上游就是运营商DNS的情形下就使用
    - system
    - https://223.5.5.5/dns-query
    - https://doh.pub/dns-query
  proxy-server-nameserver:
    - https://223.5.5.5/dns-query
    - https://doh.pub/dns-query
</code></pre>
<p>简单说一下重点的几个配置的作用吧</p>
<p><code>nameserver</code> ：默认的域名解析服务器。</p>
<p>默认都用他来解析域名。 这边我是放了一个自己系统的DNS服务（一般都是拨号的路由/光猫下发的运营商 DNS，不排除部分路由自己修改了），外加一个阿里的doh及一个腾讯的doh。为什么不两个都写运营商的DNS服务呢，因为我当地就一个DNS服务，所以只能拿个阿里来备选。不过一般也是会走入运营商DNS解析的。因为他最先返回解析结果，这样子就会优先使用。</p>
<p>这里需要额外提一点，如果是在公司等公共场合下，建议不要使用<code>system</code> (也就是上游下发的DNS)或者非加密的DNS。这种场合下以加密DNS的使用为主。</p>
<p>说到这里还需要简单解释下mihomo的DNS解析原理，mihomo收到一个域名后，会并发的把需要解析的域名同时向你填写的所有上游DNS服务器发送请求，最后看谁最先返回结果就用谁的结果。那只要你用的是当地的运营商的DNS，那么大概率是比较快的。因此绝大多数优先返回的是使用的运营商返回的DNS。</p>
<p><code>proxy-server-nameserver</code> ：代理节点域名解析服务器，仅用于解析代理节点的域名。有且只会用在解析代理节点的域名。</p>
<p>这边最好就是使用国内的公共DNS，避免你节点的域名被污染了，使用运营商DNS解析的结果不准确（虽然域名污染后，公共 DNS 也不一定准确）。</p>
<p>贴一张Mihomo的<strong>DNS解析流程</strong></p>
<p><img src="https://image.iyyh.net/CleanShot%202025-11-04%20at%2016.48.18%402x.png" alt="DNS 解析流程"></p>
<p>我的方案只写到了nameserver 和 proxy-server-nameserve，那这边简单介绍下 <code>nameserver-policy</code> 和 <code>fallback</code> 的作用吧</p>
<p><code>nameserver-policy</code> 这个其实就是dns的分流规则</p>
<p>比如 <code>'rule-set:TENCENT': https://doh.pub/dns-query</code> 也就是你规则集中，是腾讯的域名都走腾讯自家的DNS服务</p>
<p>这个实际上就是一个道理 <strong>自家人不会伤害自家人</strong> 也就是用自家的DNS来解析自家的域名，出来的结果肯定不会有啥大问题</p>
<p>也可以把阿里等厂商的 DNS mapping放进来 这样的话就可以确保 <strong>自家人不会伤害自家人</strong> ，但是我觉得没必要就是（</p>
<p><code>fallback</code> 和 <code>fallback-filter</code> ：这两个是一起用的就拿来一起讲了。</p>
<p>先给定一份yaml吧</p>
<pre><code class="language-yaml">nameserver:
  - 运营商DNS（如果确定上游是运营商DNS的话 直接用 system）
  - https://223.5.5.5/dns-query
fallback:
  - tls://8.8.4.4
  - tls://1.1.1.1
fallback-filter:
  geoip: true
  geoip-code: CN
</code></pre>
<p>解释下Mihomo的解析过程（直接从nameserver-policy没匹配到开始）：</p>
<p>域名在 <code>ns-policy</code> 没匹配到后，会并发去向 <code>nameserver</code> 和 <code>fallback</code> 获取DNS解析结果， <code>nameserver</code> 一般都是国内的DNS服务，所以一般都会优先获取到结果， <code>fallback</code> 会稍微晚一些，但是一旦填写了 <code>fallback</code> 后，一定会等待 <code>fallback</code> 解析返回出来IP的结果，并且会走入 <code>fallback-filter</code> 进行判断，这边的例子就是开启geoip检测，且geoip-code也就是国家是CN。也就是会拿 <code>nameserver</code> 解析出来的ip结果与geoip数据库进行匹配，如果解析的是CN的ip，那么就直接用 <code>nameserver</code> 解析出来的结果，如果<code>nameserver</code> 解析出来的ip结果不是CN，那么就会用 <code>fallback</code> 的解析结果。</p>
<p>这边要特别注意一个地方，就是如果开启了 <code>fallback</code> 哪怕 <code>nameserver</code> 解析的再快都需要等待 <code>fallback</code> 的解析结果。并且 <code>fallback-filter</code> 比较依赖geo这个数据库（但是看了一些文章觉得其中的<code>geosite</code>应该是有一定的问题的）具体问题如下（该来源为 <a href="https://blog.skk.moe/post/i-have-my-unique-surge-setup/">Sukka</a>）：</p>
<pre><code>因为 dnsmasq-china-list 设计之初是为国内域名的 DNS 解析优化、完全不适用于流量分流（dnsmasq-china-list 只检查域名的权威 DNS 服务器，因此有部分海外域名、因为 DNS 服务器位于中国大陆、依然被包含在 accelerated-domains.china.conf 中）。因此，Loyalsoldier/v2ray-rules-dat 和 MetaCubeX/meta-rules-dat 项目的 GEOSITE 规则使用 dnsmasq-china-list 作为上游数据来源 是大错特错的。
</code></pre>
<p>因此学习 Sukka 的文章后，我不是很喜欢用这个系列(</p>
<p>所以 <code>fallback</code> 在现有的环境下我是<strong>不会</strong>去使用他的。</p>
<p><code>nameserver-policy</code>：</p>
<p>举例下，就是阿里的域名或者服务器，全部走阿里的DNS；同理腾讯等其他厂商也是如此。</p>
<p>请到 以下<a href="https://ruleset.skk.moe/Internal/clash_nameserver_policy.yaml">链接</a> 自行复制内容 粘贴到 自己的 配置文件中使用即可。</p>
<p>另外，有自动的代码，但是由于时间有限没有写到action中，请有能力的同学自行运行python脚本。代码以及说明在我的<a href="https://github.com/yyhhyyyyyy/selfproxy/tree/main/Mihomo">仓库</a>中。</p>
<p>至此，DNS部分我认为已经足够了</p>
<h2>4. Mihomo 域名嗅探（Sniffer）</h2>
<p>配置：</p>
<pre><code class="language-yaml">sniffer:
  enable: true
  sniff:
    HTTP:
      ports: [80, 8080-8880]
      override-destination: true
    TLS:
      ports: [443, 8443]
    QUIC:
      ports: [443, 8443]
  skip-domain:
    - Mijia Cloud
    - '+.push.apple.com'
</code></pre>
<p>简易理解如下图（只是场景描述，核心为拿 SNI 使得分流更精确）：</p>
<pre><code class="language-text">用户在 App 里访问：youtube.com
        │
        ▼
App 发起连接
        │
        ├─ 情况 A：Mihomo 一开始就拿到了域名
        │          例如：DNS / 连接信息里已有 youtube.com
        │
        └─ 情况 B：Mihomo 一开始只看到 IP
                   例如：142.250.xx.xx:443
                   或者拿到的“原始域名”不够准
        │
        ▼
这时进入 Sniffer（域名嗅探）
        │
        ├─ HTTP：看请求里的 Host
        ├─ TLS：看 ClientHello 里的 SNI
        └─ QUIC：看初始握手里可识别出的主机名信息
        │
        ▼
Sniffer 得到更接近真实目标的域名
例如：youtube.com
        │
        ▼
Mihomo 用这个域名继续做判断
        │
        ├─ 规则匹配
        │   DOMAIN-SUFFIX,youtube.com,PROXY
        │
        └─ 如开启 override-destination
            还可以直接把“实际访问目标”改成嗅探结果
        │
        ▼
最终决定：DIRECT / PROXY / REJECT / 指定策略组
</code></pre>
<p>总而言之，可以把域名嗅探理解成“补全目标信息”的过程：当 Mihomo 只看到 IP，或者现有目标信息不够准确时，它会再从连接内容里提取主机名，让后续分流尽可能按真实目标进行。</p>
<h2>5. Mihomo Tunnel 配置</h2>
<pre><code class="language-yaml">tun:
  enable: true
  stack: system
  device: Ethernet99
  auto-route: true
  auto-detect-interface: true
  dns-hijack:
    - any:53
    - tcp://any:53
  strict-route: true
  mtu: 1500
  # 如果有使用zerotier或者headscale等，需要自己配置排除自己的网段
  # route-exclude-address: [&quot;192.168.110.0/24&quot;]
</code></pre>
<p>其中就我觉得只需要注意下 <code>stack</code> 这个参数即可</p>
<p>具体看我之前写的文章<a href="https://iyyh.net/posts/2024/08/tunnel-difference">Tunnel三种模式的区别</a>就可以了。结论如下：在确保能正常使用的前提下遵循这个顺序： <strong>system &gt; mixed &gt; gvisor</strong></p>
<h2>6. Mihomo 节点配置（Proxy Providers）</h2>
<pre><code class="language-yaml"># ## 订阅基础配置 [每天更新一次订阅节点，每 300 秒一次健康检查]
NodeParam: &amp;NodeParam {type: http, interval: 86400, health-check: {enable: true, url: 'http://connectivitycheck.platform.hicloud.com/generate_204', interval: 300}}

# 订阅合集
proxy-providers:
  Node:
    url: 替换订阅链接
    &lt;&lt;: *NodeParam
    path: ./proxy_provider/providers.yaml

# 单节点(如果你是自建节点，那么请直接在下面的proxies里添加节点配置，具体节点写法请参考 mihomo 官方文档)
# proxies:
#   - {name: &quot;示例节点&quot;, type: ss, server: example.com, port: 443, cipher: aes-256-gcm, password: &quot;password&quot;, udp: true}

# 节点筛选
# 按地区筛选
FilterHK: &amp;FilterHK '(🇭🇰|香港|[Hh][Kk]|Hong\s*Kong)'
FilterTW: &amp;FilterTW '(🇹🇼|台[湾灣]|[Tt][Ww]|Taiwan)'
FilterUS: &amp;FilterUS '(🇺🇸|美[国國]|America|United\s*States|[Uu][Ss])'
FilterJP: &amp;FilterJP '(🇯🇵|日本|东京|大阪|[Jj][Pp]|Japan)'
FilterSG: &amp;FilterSG '(🇸🇬|新加坡|狮城|[Ss][Gg]|Singapore)'

# ## 策略组基础配置
# 手动选择
Select: &amp;Select {type: select, url: 'http://connectivitycheck.platform.hicloud.com/generate_204', disable-udp: false, hidden: false, include-all: true}
# 自动选择 [每 300 秒一次惰性健康检查，容差 50ms，时延超过 2 秒判定为失败，失败 3 次自动触发健康检查]
UrlTest: &amp;UrlTest {type: url-test, url: 'http://connectivitycheck.platform.hicloud.com/generate_204', interval: 300, lazy: true, tolerance: 50, timeout: 2000, disable-udp: false, max-failed-times: 3, hidden: true, include-all: true}
# 自动回退 [每 300 秒一次惰性健康检查，时延超过 2 秒判定为失败，失败 3 次自动触发健康检查]
FallBack: &amp;FallBack {type: fallback, url: 'http://connectivitycheck.platform.hicloud.com/generate_204', interval: 300, lazy: true, timeout: 2000, disable-udp: false, max-failed-times: 3, hidden: true, include-all: true}
# 负载均衡 [每 300 秒一次惰性健康检查，时延超过 2 秒判定为失败，失败 3 次则自动触发健康检查]
LoadBalance: &amp;LoadBalance {type: load-balance, url: 'http://connectivitycheck.platform.hicloud.com/generate_204', interval: 300, lazy: true, disable-udp: false, strategy: consistent-hashing, timeout: 2000, max-failed-times: 3, hidden: true, include-all: true}

# 策略组
proxy-groups:
  # 主选择组
  - {name: 🎯节点选择, type: select, proxies: [智能选择, 手动选择, 全部节点, DIRECT], url: http://connectivitycheck.platform.hicloud.com/generate_204, icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Static.png}

  # 手动/Auto
  - {name: 手动选择, type: select, proxies: [🇭🇰-手动选择, 🇯🇵-手动选择, 🇸🇬-手动选择, 🇺🇸-手动选择, 🇹🇼-手动选择], url: http://connectivitycheck.platform.hicloud.com/generate_204, icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Cylink.png}
  - {name: 智能选择, type: select, proxies: [🇭🇰-Auto, 🇯🇵-Auto, 🇸🇬-Auto, 🇺🇸-Auto, 🇹🇼-Auto], url: http://connectivitycheck.platform.hicloud.com/generate_204, icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Urltest.png}

  # 应用分组
  - {name: ✈️电报信息, type: select, proxies: [🎯节点选择, 🇭🇰-Auto, 🇯🇵-Auto, 🇸🇬-Auto, 🇺🇸-Auto], icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Telegram.png}
  - {name: 🤖AIGC, type: select, proxies: [🇺🇸-Auto, 🎯节点选择, 🇭🇰-Auto, 🇯🇵-Auto, 🇸🇬-Auto], icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/OpenAI.png}
  - {name: 🍎苹果服务, type: select, proxies: [DIRECT, 🎯节点选择, 🇭🇰-Auto, 🇺🇸-Auto], icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Apple.png}
  - {name: Ⓜ️微软服务, type: select, proxies: [DIRECT, 🎯节点选择, 🇭🇰-Auto, 🇺🇸-Auto], icon: https://raw.githubusercontent.com/Orz-3/mini/master/Color/Microsoft.png}

  # Auto
  - {name: 🇭🇰-Auto, type: select, proxies: [🇭🇰-自动选择, 🇭🇰-自动回退, 🇭🇰-负载均衡]}
  - {name: 🇯🇵-Auto, type: select, proxies: [🇯🇵-自动选择, 🇯🇵-自动回退, 🇯🇵-负载均衡]}
  - {name: 🇸🇬-Auto, type: select, proxies: [🇸🇬-自动选择, 🇸🇬-自动回退, 🇸🇬-负载均衡]}
  - {name: 🇺🇸-Auto, type: select, proxies: [🇺🇸-自动选择, 🇺🇸-自动回退, 🇺🇸-负载均衡]}
  - {name: 🇹🇼-Auto, type: select, proxies: [🇹🇼-自动选择, 🇹🇼-自动回退, 🇹🇼-负载均衡]}

  # 自动选择 - 按地区
  - {name: 🇭🇰-自动选择, &lt;&lt;: *UrlTest, filter: *FilterHK}
  - {name: 🇯🇵-自动选择, &lt;&lt;: *UrlTest, filter: *FilterJP}
  - {name: 🇸🇬-自动选择, &lt;&lt;: *UrlTest, filter: *FilterSG}
  - {name: 🇺🇸-自动选择, &lt;&lt;: *UrlTest, filter: *FilterUS}
  - {name: 🇹🇼-自动选择, &lt;&lt;: *UrlTest, filter: *FilterTW}

  # 自动回退 - 按地区
  - {name: 🇭🇰-自动回退, &lt;&lt;: *FallBack, filter: *FilterHK}
  - {name: 🇯🇵-自动回退, &lt;&lt;: *FallBack, filter: *FilterJP}
  - {name: 🇸🇬-自动回退, &lt;&lt;: *FallBack, filter: *FilterSG}
  - {name: 🇺🇸-自动回退, &lt;&lt;: *FallBack, filter: *FilterUS}
  - {name: 🇹🇼-自动回退, &lt;&lt;: *FallBack, filter: *FilterTW}

  # 负载均衡 - 按地区
  - {name: 🇭🇰-负载均衡, &lt;&lt;: *LoadBalance, filter: *FilterHK}
  - {name: 🇯🇵-负载均衡, &lt;&lt;: *LoadBalance, filter: *FilterJP}
  - {name: 🇸🇬-负载均衡, &lt;&lt;: *LoadBalance, filter: *FilterSG}
  - {name: 🇺🇸-负载均衡, &lt;&lt;: *LoadBalance, filter: *FilterUS}
  - {name: 🇹🇼-负载均衡, &lt;&lt;: *LoadBalance, filter: *FilterTW}

  # 手动选择 - 按地区
  - {name: 🇭🇰-手动选择, &lt;&lt;: *Select, filter: *FilterHK}
  - {name: 🇯🇵-手动选择, &lt;&lt;: *Select, filter: *FilterJP}
  - {name: 🇸🇬-手动选择, &lt;&lt;: *Select, filter: *FilterSG}
  - {name: 🇺🇸-手动选择, &lt;&lt;: *Select, filter: *FilterUS}
  - {name: 🇹🇼-手动选择, &lt;&lt;: *Select, filter: *FilterTW}

  - {name: 全部节点, &lt;&lt;: *Select}
</code></pre>
<p>这部分改动的地方就是订阅链接以及如果是自建节点，补充一下自建节点的信息即可，具体使用的协议可以查看<a href="https://wiki.metacubex.one/config/proxies/">Mihomo 出站代理</a>进行补充信息。这边给大家一个建议，如果有能力部署/折腾<a href="https://github.com/sub-store-org/Sub-Store">Sub-Store</a>的同学，欢迎使用该工具，能解决非常多订阅/单节点上的问题。</p>
<p>需要简单解释下 测试链接 最好不用直接用google的因为容易引起 Google 对 IP 的风控。</p>
<h2>7. Mihomo 分流规则配置</h2>
<p>首先，请注意，把所有<strong>非IP类规则写在 IP类规则之前</strong>，这是最没有问题的！前提你使用的模式跟我一样都是 <strong>fake-ip</strong></p>
<p>避免 DNS 污染和 DNS 泄漏最有效的办法就是永远不在本地进行 DNS 解析，而 Mihomo 能且只能通过 Fake IP 和域名规则匹配的方式实现非直连域一定不在本地本机进行任何 DNS 解析。在 Mihomo 中，规则自上而下匹配，只有当遇到 IP 类规则（如 IP-CIDR、IP-CIDR6、GEOIP 和 IP-ASN）时才会发起 DNS 解析。因此，在 Mihomo 中，将会触发 DNS 解析的规则放在域名和 URL 匹配规则后面非常重要。[<a href="https://blog.skk.moe/post/i-have-my-unique-surge-setup/">引用来自 sukka</a>]</p>
<p>十分推荐大家先去看看 Sukka 的规则仓库以及文章再来写，会有不少收获。</p>
<pre><code class="language-yaml"># ## 规则配置
RuleSet_classical: &amp;RuleSet_classical {type: http, behavior: classical, interval: 43200, format: text, proxy: 🎯节点选择}
RuleSet_domain: &amp;RuleSet_domain {type: http, behavior: domain, interval: 43200, format: text, proxy: 🎯节点选择}
RuleSet_ipcidr: &amp;RuleSet_ipcidr {type: http, behavior: ipcidr, interval: 43200, format: text, proxy: 🎯节点选择}

# 订阅规则
rule-providers:
  cdn_domainset:
    &lt;&lt;: *RuleSet_domain
    url: https://ruleset.skk.moe/Clash/domainset/cdn.txt
    path: ./rule_set/sukkaw_ruleset/cdn_domainset.txt

  cdn_non_ip:
    &lt;&lt;: *RuleSet_domain
    url: https://ruleset.skk.moe/Clash/non_ip/cdn.txt
    path: ./rule_set/sukkaw_ruleset/cdn_non_ip.txt

  stream_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/stream.txt
    path: ./rule_set/sukkaw_ruleset/stream_non_ip.txt

  stream_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/ip/stream.txt
    path: ./rule_set/sukkaw_ruleset/stream_ip.txt

  ai_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/ai.txt
    path: ./rule_set/sukkaw_ruleset/ai_non_ip.txt

  telegram_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/telegram.txt
    path: ./rule_set/sukkaw_ruleset/telegram_non_ip.txt

  telegram_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/ip/telegram.txt
    path: ./rule_set/sukkaw_ruleset/telegram_ip.txt

  apple_cdn:
    &lt;&lt;: *RuleSet_domain
    url: https://ruleset.skk.moe/Clash/domainset/apple_cdn.txt
    path: ./rule_set/sukkaw_ruleset/apple_cdn.txt

  apple_services:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/apple_services.txt
    path: ./rule_set/sukkaw_ruleset/apple_services.txt

  apple_cn_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/apple_cn.txt
    path: ./rule_set/sukkaw_ruleset/apple_cn_non_ip.txt

  microsoft_cdn_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/microsoft_cdn.txt
    path: ./rule_set/sukkaw_ruleset/microsoft_cdn_non_ip.txt

  microsoft_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/microsoft.txt
    path: ./rule_set/sukkaw_ruleset/microsoft_non_ip.txt

  download_domainset:
    &lt;&lt;: *RuleSet_domain
    url: https://ruleset.skk.moe/Clash/domainset/download.txt
    path: ./rule_set/sukkaw_ruleset/download_domainset.txt

  download_non_ip:
    &lt;&lt;: *RuleSet_domain
    url: https://ruleset.skk.moe/Clash/non_ip/download.txt
    path: ./rule_set/sukkaw_ruleset/download_non_ip.txt

  lan_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/lan.txt
    path: ./rule_set/sukkaw_ruleset/lan_non_ip.txt

  lan_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/ip/lan.txt
    path: ./rule_set/sukkaw_ruleset/lan_ip.txt

  domestic_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/domestic.txt
    path: ./rule_set/sukkaw_ruleset/domestic_non_ip.txt

  direct_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/direct.txt
    path: ./rule_set/sukkaw_ruleset/direct_non_ip.txt

  global_non_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/non_ip/global.txt
    path: ./rule_set/sukkaw_ruleset/global_non_ip.txt

  domestic_ip:
    &lt;&lt;: *RuleSet_classical
    url: https://ruleset.skk.moe/Clash/ip/domestic.txt
    path: ./rule_set/sukkaw_ruleset/domestic_ip.txt

  china_ip:
    &lt;&lt;: *RuleSet_ipcidr
    url: https://ruleset.skk.moe/Clash/ip/china_ip.txt
    path: ./rule_set/sukkaw_ruleset/china_ip.txt

# 分流规则
rules:
  # ## 非 IP 类规则
  - RULE-SET,cdn_domainset,🎯节点选择
  - RULE-SET,cdn_non_ip,🎯节点选择
  - RULE-SET,stream_non_ip,🇺🇸-自动选择
  - RULE-SET,telegram_non_ip,✈️电报信息
  - RULE-SET,apple_cdn,DIRECT
  - RULE-SET,download_domainset,🎯节点选择
  - RULE-SET,download_non_ip,🎯节点选择
  - RULE-SET,microsoft_cdn_non_ip,DIRECT
  - RULE-SET,apple_cn_non_ip,DIRECT
  - RULE-SET,apple_services,🍎苹果服务
  - RULE-SET,microsoft_non_ip,Ⓜ️微软服务
  - RULE-SET,ai_non_ip,🤖AIGC
  - RULE-SET,global_non_ip,🎯节点选择
  - RULE-SET,domestic_non_ip,DIRECT
  - RULE-SET,direct_non_ip,DIRECT
  - RULE-SET,lan_non_ip,DIRECT

  # ## IP 类规则
  - RULE-SET,telegram_ip,✈️电报信息
  - RULE-SET,stream_ip,🇺🇸-自动选择
  - RULE-SET,lan_ip,DIRECT
  - RULE-SET,domestic_ip,DIRECT
  - RULE-SET,china_ip,DIRECT
  - MATCH,🎯节点选择
</code></pre>
<h2>8. 仓库及推荐</h2>
<p><strong>仓库</strong>：自己目前在用且持续更新的配置仓库 <strong><a href="https://github.com/yyhhyyyyyy/selfproxy">selfproxy</a></strong> 欢迎各位同学帮忙点个star🌟，访问后点击进入<code>Mihomo</code>目录即可。</p>
<p><strong>机场推荐（AFF）</strong>：<a href="https://s.iyyh.net/flower">FlowerCloud</a>，花云是我用的很久的一家机场了，一线机场里算性价比拉满的一家，大家可以按需订购。</p>
<h2>9. 参考</h2>
<p><a href="https://blog.skk.moe/tags/DNS/"><strong>Sukka</strong></a></p>
<p><a href="https://github.com/Rabbit-Spec/Clash/blob/Master/Yaml/Clash_Pro.yaml"><strong>Rabbit-Spec</strong></a></p>
<p><a href="https://wiki.metacubex.one/"><strong>metacubex</strong></a></p>
<h2>10. Mihomo 可视化客户端</h2>
<ol>
<li><a href="https://github.com/mihomo-party-org/clash-party">clash-party</a> <s>我自己Windows端本来使用的是裸核，不过近期也是换成mihomoparty了 推荐大家使用下（最近party可能发生了一些事情，貌似不再维护更新了）</s> <strong>party我有参与过PR</strong></li>
<li><a href="https://github.com/xishang0128/sparkle">sparkle</a> Party 的分支版本，由于Party发生了一些事情，现在只在这个分支进行更新，更推荐大家用这个版本</li>
<li><a href="https://github.com/clash-verge-rev/clash-verge-rev">clash-verge-rev</a> verge-rev 也很不错 <strong>我也有参与verge-rev的PR</strong></li>
<li><a href="https://github.com/chen08209/FlClash">FlClash</a> 如果想一劳永逸，不怎么折腾客户端的话，更推荐 FlClash。</li>
</ol>
<p>客户端使用请结合一下我的这篇文章 <a href="https://www.iyyh.net/archives/f51e9150-160f-4de4-9be8-3c9efc6618df"><strong>Mihomo Party 覆写/Clash Verge Rev 扩展脚本</strong></a>，能帮助大家更快上手。</p>
<p>覆写仓库在<a href="https://github.com/yyhhyyyyyy/selfproxy/tree/main/Mihomo/Extension_Script">这里</a>！</p>
<p><strong>建议</strong>：有能力还是裸核+<code>external-ui</code>吧！</p>
<h2>11. 交流</h2>
<p>TG： <a href="https://t.me/iyyhchannel">Channel</a></p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[TUN(Tunnel)三种模式的区别]]></title>
            <link>https://iyyh.net/posts/2024/08/tunnel-difference</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/08/tunnel-difference</guid>
            <pubDate>Wed, 21 Aug 2024 12:38:26 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1. 起源</h3>
<p>TUN 模式（即 Tunnel 模式）是 Mihomo、Clash、sing-box 等代理工具中常用的透明代理方式。配置文件中的 <code>tun</code> 字段实际上就是 tunnel 的缩写。自从了解到 TUN 模式的优势后，它已经成为许多人替代传统 system proxy 的首选。然而，TUN 模式有三种不同的网络堆栈实现，每种都有其特点和适用场景。</p>
<h3>2. TUN (Tunnel) 模式概述</h3>
<p>TUN 模式在网络层（第三层）接收流量，主要处理的是 TCP 和 UDP 协议的数据（虽然 ICMP 也是第三层协议，但通常不会去实现对它的处理）。接收到这些流量后，需要对可能被分割的数据包进行重组，以恢复完整的数据。</p>
<h3>3. 三种网络堆栈</h3>
<h4>3.1 System</h4>
<ul>
<li>解释：使用操作系统内核（kernelspace）创建 TCP 连接。</li>
<li>优点：<strong>效率最高</strong>，直接利用系统内核的网络栈。</li>
<li>缺点：兼容性可能受限于特定操作系统。</li>
</ul>
<h4>3.2 gVisor</h4>
<ul>
<li>解释：在用户空间（userspace）实现的轻量级 IP 协议栈（lwIP）。</li>
<li>优点：<strong>兼容性最佳</strong>，可在各种环境中运行。</li>
<li>缺点：效率相对较低，因为在用户空间运行。</li>
</ul>
<p>举个例子，在ios设备上用sing-box的tunnel模式，堆栈选择system不能在ios上正常启动，但是使用gVisor即可正常启动。这个实际上就是兼容性问题了。</p>
<h4>3.3 mixed</h4>
<ul>
<li>解释：TCP 使用 system 模式，UDP 使用 gVisor 模式。</li>
<li>优点：平衡了效率和兼容性。</li>
<li>缺点：实现复杂度增加，可能在某些特殊情况下表现不一致。</li>
</ul>
<h3>4.如何选择</h3>
<p>个人建议，不管在什么环境下，TUN 模式的堆栈都按照 <strong>system&gt;mixed&gt;gvisor</strong> 这个顺序进行尝试。</p>
<p>这样能保证性能最优，使用起来效果最佳。</p>
<p>也推荐大家结合我的 <a href="https://iyyh.net/posts/2024/09/mihomo-self-config">Mihomo 配置文件</a> 进行使用，其中包含了 TUN 模式的完整配置示例。</p>
<h3>5.鸣谢</h3>
<p><a href="https://blog.skk.moe/">Sukka</a></p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[解决MoviePy保存视频时的视频质量降低问题]]></title>
            <link>https://iyyh.net/posts/2024/08/fix-moviepy-quality-loss</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/08/fix-moviepy-quality-loss</guid>
            <pubDate>Wed, 14 Aug 2024 03:06:39 GMT</pubDate>
            <content:encoded><![CDATA[<h2>1. 起源</h2>
<p>最近在折腾自动化剪辑视频的时候，发现我原视频视频质量看起来还ok，至少肉眼看过去还好，但是经过moviepy处理后保存下来的视频却质量降低了很多，会有很多噪点的产生。其实最直观的就是，传进去的视频大小是100MB，出来的视频就只有不到10MB，很明显就是被压缩了。</p>
<h2>2. 解决方案</h2>
<p>moviepy导出时的编码需要指定，且文件后缀也有一定要求。</p>
<p>先简单阐述下：</p>
<p>不同的编码器支持不同的容器格式（也称为封装格式）。以下是一些常见的编码器及其通常支持的容器格式：</p>
<ol>
<li><strong>H.264 无损模式</strong> ：通常使用 <code>.mp4</code> 或 <code>.mkv</code> 容器。</li>
<li><strong>H.265/HEVC 无损模式</strong> ：通常使用 <code>.mp4</code> 或 <code>.mkv</code> 容器。</li>
<li><strong>ProRes</strong>：通常使用 <code>.mov</code> 容器。</li>
<li><strong>DNxHD/DNxHR</strong>：通常使用 <code>.mov</code> 容器。</li>
</ol>
<p>代码附上：</p>
<h3><strong>H.264 无损模式（.mp4 容器）</strong></h3>
<pre><code class="language-python">video_clip.write_videofile(
    output_file + &quot;.mp4&quot;,
    audio_codec=&quot;aac&quot;,
    temp_audiofile_path=output_dir,
    threads=params.n_threads or 2,
    logger=None,
    codec=&quot;libx264&quot;,
    ffmpeg_params=[&quot;-qp&quot;, &quot;0&quot;],  # 无损模式
    fps=video_clip.fps
)
</code></pre>
<h3><strong>H.264 无损模式（.mkv 容器）</strong></h3>
<pre><code class="language-python">video_clip.write_videofile(
    output_file + &quot;.mkv&quot;,
    audio_codec=&quot;aac&quot;,
    temp_audiofile_path=output_dir,
    threads=params.n_threads or 2,
    logger=None,
    codec=&quot;libx264&quot;,
    ffmpeg_params=[&quot;-qp&quot;, &quot;0&quot;],  # 无损模式
    fps=video_clip.fps
)
</code></pre>
<h3><strong>H.265/HEVC 无损模式（.mp4 容器）</strong></h3>
<pre><code class="language-python">video_clip.write_videofile(
    output_file + &quot;.mp4&quot;,
    audio_codec=&quot;aac&quot;,
    temp_audiofile_path=output_dir,
    threads=params.n_threads or 2,
    logger=None,
    codec=&quot;libx265&quot;,
    ffmpeg_params=[&quot;-qp&quot;, &quot;0&quot;],  # 无损模式
    fps=video_clip.fps
)
</code></pre>
<h3><strong>H.265/HEVC 无损模式（.mkv 容器）</strong></h3>
<pre><code class="language-python">video_clip.write_videofile(
    output_file + &quot;.mkv&quot;,
    audio_codec=&quot;aac&quot;,
    temp_audiofile_path=output_dir,
    threads=params.n_threads or 2,
    logger=None,
    codec=&quot;libx265&quot;,
    ffmpeg_params=[&quot;-qp&quot;, &quot;0&quot;],  # 无损模式
    fps=video_clip.fps
)
</code></pre>
<h3><strong>ProRes（.mov 容器）</strong></h3>
<pre><code class="language-python">video_clip.write_videofile(
    output_file + &quot;.mov&quot;,
    audio_codec=&quot;aac&quot;,
    temp_audiofile_path=output_dir,
    threads=params.n_threads or 2,
    logger=None,
    codec=&quot;prores&quot;,
    fps=video_clip.fps
)
</code></pre>
<p>请根据自己的需求选择合适的编码器和容器格式。当然也可以考虑使用 <code>.mp4</code> 容器，因为它是常见的格式，并且大多数编码器都支持。(不过偶尔mp4不太好用，moviepy没法直接保存</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Tailscale+Headscale+自建Derp踩坑记录]]></title>
            <link>https://iyyh.net/posts/2024/08/tailscale-headscale-self-hosted-derp-troubleshooting-record</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/08/tailscale-headscale-self-hosted-derp-troubleshooting-record</guid>
            <pubDate>Wed, 07 Aug 2024 01:45:26 GMT</pubDate>
            <content:encoded><![CDATA[<h2>1. 缘由</h2>
<p>最近想拉通家里网络（组网），先是用的wg，因为我自己用的ios surge 只支持wg（不然我应该会直接上Tailscale），然后就先拉通了wg回家，但是吧，感觉wg好麻烦，每次都得进wg服务端生成个密钥才能授权认证等，相对繁琐。因此有了本次折腾。</p>
<h2>2. 什么是Tailscale</h2>
<p>Tailscale 是一种基于 WireGuard 的虚拟组网工具，WG的势头目前确实越来越好。那Tailscale相比WG有什么优势呢？</p>
<ul>
<li>装个客户端就能用了
<ul>
<li>无需配置防火墙</li>
<li>没有额外的配置</li>
</ul>
</li>
<li>高安全性/私密性
<ul>
<li>自动密钥轮换</li>
<li>点对点连接</li>
<li>支持用户审查端到端的访问记录</li>
</ul>
</li>
<li>在原有的 ICE、STUN 等 UDP 协议外，实现了 DERP TCP 协议来实现 NAT 穿透</li>
</ul>
<p>但是相比于WG还是有一定缺点的，Tailscale 相比于内核态 WireGuard <strong>性能会有所损失</strong>。</p>
<p>其次的话就是 Tailscale 并不是完全免费</p>
<p>对于免费账户，他携带<strong>100个免费设备</strong>的资格 如果个人使用 完全足够咯</p>
<p>(这里就不探讨开源不开源了问题啦 个人是觉得 都ok 只不过 Tailscale的<strong>控制服务</strong>没开源罢了</p>
<p>当然如果不想经过Tailscale这层审计的话 自建Headscale是一个不错的选择 而我也选择这个方式</p>
<h2>3. 什么是Headscale</h2>
<p>Headscale 是一个由 Juan Font 开发的开源项目，它使用 Go 语言编写并在 BSD 许可下发布。它旨在实现 Tailscale 控制服务器的所有主要功能，并可以在企业内部进行部署。以下是一些关于 Headscale 的关键点：</p>
<ol>
<li><strong>功能实现</strong>：Headscale 实现了 Tailscale 控制服务器的主要功能，允许用户创建和管理虚拟网络，使设备之间能够安全地通信。</li>
<li><strong>内部部署</strong>：与 Tailscale 不同，Headscale 可以在企业内部部署，不需要依赖外部的控制服务器。这意味着企业可以完全控制自己的网络基础设施。</li>
<li><strong>无限设备支持</strong>：Headscale 不限制设备的数量，可以根据需要扩展网络，这对大型组织特别有利。</li>
<li><strong>网络流量控制</strong>：所有的网络流量都由用户自己控制，不经过第三方服务器，这增强了隐私性和安全性。</li>
<li><strong>开源和许可</strong>：Headscale 是开源的，在 BSD 许可下发布，这意味着任何人都可以自由地使用、修改和分发该软件。</li>
<li><strong>使用场景</strong>：Headscale 适用于需要高度控制和安全性的环境，例如企业内部网络、私有云基础设施或任何不希望将网络流量通过第三方的情景。</li>
</ol>
<p>通过这些特性，Headscale 提供了一个强大的、灵活的解决方案，使用户能够享受 Tailscale 的便利，同时保持对其网络的完全控制。</p>
<h2>4. Headscale部署</h2>
<p>网上很多不同方式的部署教程，这边只记录自己总结以及在自己的Debian服务器的折腾记录。</p>
<p>官网提供了两种不同的文档，一种是目前沿用的新版本的采用 <code>.dev</code> 的方式<a href="https://headscale.net/running-headscale-linux/">一键安装</a>的形式，不过此版本有一定的坑，具体也是在后续启动headscale的时候没法启动（针对我自己的环境而言，因此我使用了二进制的安装方式）</p>
<p>这边罗列几篇部署参考的教程文档：</p>
<ul>
<li>
<p><a href="https://headscale.net/running-headscale-linux-manual/">官方文档</a></p>
</li>
<li>
<p><a href="https://icloudnative.io/posts/how-to-set-up-or-migrate-headscale/">Tailscale 基础教程：Headscale 的部署方法和使用教程</a></p>
</li>
<li>
<p>[<a href="https://zhangguanzhang.github.io/2024/07/25/headscale/">持续更新] - headscale 搭建和应用场景</a></p>
</li>
</ul>
<p>而我也是根据这几篇教程慢慢踩坑过来的。</p>
<p>截止到 <code>2024/8/7</code> 官网releases版本是 <code>0.22.3</code> ，因此接下来都是以该版本进行</p>
<p>首先下载二进制文件</p>
<pre><code class="language-bash"># 下载需要代理 自行解决
wget -O /usr/local/bin/headscale https://github.com/juanfont/headscale/releases/download/v0.22.3/headscale_0.22.3_linux_amd64
</code></pre>
<p>给予二进制文件可执行权限</p>
<pre><code class="language-bash"># 简单声明下为什么要a all_user 只是偷个懒 因为启动的时候不以root权限执行
chmod a+x /usr/local/bin/headscale
</code></pre>
<p>创建需要用到的文件夹</p>
<pre><code class="language-bash"># 用来存放headscale的配置文件，以及后续自建derp也放这里(derp没说必须放这里 只是放一起好找)
mkdir /etc/headscale/
# 用于存放 Headscale 服务在运行时需要的临时文件，如 UNIX 域套接字文件 headscale.sock。
mkdir -p /var/run/headscale/
</code></pre>
<p>下载二进制同版本的示例配置文件</p>
<pre><code class="language-bash">wget -O /etc/headscale/config.yaml https://raw.githubusercontent.com/juanfont/headscale/v0.22.3/config-example.yaml
</code></pre>
<p>创建 SystemD service 配置文件（简单理解就是后台运行的配置文件）</p>
<pre><code class="language-bash">cat &gt; /etc/systemd/system/headscale.service &lt;&lt; EOF
[Unit]
Description=headscale controller
After=syslog.target
After=network.target

[Service]
Type=simple
User=headscale
Group=headscale
ExecStart=/usr/local/bin/headscale serve
Restart=always
RestartSec=5

# Optional security enhancements
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
WorkingDirectory=/var/lib/headscale
ReadWritePaths=/var/lib/headscale /var/run/headscale
AmbientCapabilities=CAP_NET_BIND_SERVICE
RuntimeDirectory=headscale

[Install]
WantedBy=multi-user.target
EOF
</code></pre>
<p>Headscale本身的作用实际就是取代Tailscale的<strong>控制中心</strong>的作用，因此不需要root权限</p>
<p>这边有个<strong>坑</strong>，我直接用root用户启动的时候各种报错，哪怕修改了 <code>headscale.service</code> 中的 <code>User</code> 也是报错，因此我不建议使用root用户，而是采用专门建立的 <code>headscale</code> 用户来进行下一步操作。</p>
<p>创建 <code>headscale</code> 用户</p>
<pre><code class="language-bash"># 创建一个系统用户 &quot;headscale&quot;
useradd \
  --create-home \  # 如果主目录不存在，则创建主目录
  --home-dir /var/lib/headscale/ \  # 指定用户的主目录为 /var/lib/headscale/
  --system \  # 创建一个系统账户
  --user-group \  # 为用户创建一个同名的用户组
  --shell /usr/sbin/nologin \  # 禁止用户登录
  headscale
</code></pre>
<p>创建空的 SQLite 数据库文件和 derp配置文件，并给予 <code>headscale</code> 用户有这些文件夹/文件的权限</p>
<pre><code class="language-bash">touch /var/lib/headscale/db.sqlite /etc/headscale/derp.yaml
chown -R headscale:headscale /var/run/headscale/ /var/lib/headscale
chmod a+r /etc/headscale/config.yaml /etc/headscale/derp.yaml
</code></pre>
<p>修改headscale的配置文件 <code>/etc/headscale/config.yaml</code> 这边只罗列需要修改的部分</p>
<pre><code class="language-yaml">server_url: http://&lt;公网ip 或者ddns的域名&gt;:8080

# 0.0.0.0才能监听到  当然可以用公网ip  或者  网卡的ip
listen_addr: 0.0.0.0:8080

# ip段范围（我用不到v6 所以注释）
ip_prefixes:
  # - fd7a:115c:a1e0::/48
  - 100.64.0.0/10

dns_config:
  # 改为 false 不覆盖本地 DNS
  override_local_dns: false
  # 关闭 magic_dns
  magic_dns: false
  # 设置为你自己的标识，否则后续 tailscale 端连接上显示是 user@example.com
  # 比如我的域名是 ddns.cn 那客户端显示就的就是 user@ddns.cn  这里可改可不改  我是顺手改了
  base_domain: ddns.cn
# 随机端口要打开， tailscale 客户端会使用41641 端口建立 wireguard 链接，这个端口会被中间网络设备阻止
randomize_client_port: true
</code></pre>
<p>启动 headscale daemon 进程</p>
<pre><code class="language-bash"># 测试文件 看看输出是否正常
headscale configtest

# 测试启动一次
headscale serve
# 这边需要注意  ctrl + c 的时候  请耐心等待自己结束进程  不然会出现很奇怪的问题  将会导致后续 systemd启动失败
# 配置文件没问题就 ctrl + c 取消掉使用 systemd 启动（后台静默运行）
systemctl daemon-reload
systemctl enable --now headscale
# 查看运行状态是否正常启动
systemctl status headscale
</code></pre>
<h2>5. 客户端接入</h2>
<h4>5.1 创建用户</h4>
<pre><code class="language-bash"># default 自己取
headscale user create default
</code></pre>
<h4>5.2 生成 pre-authkey 的 key</h4>
<pre><code class="language-bash"># 生成一个过期时间 365d 且可以重复使用的 authkey (因为我是自用  所以创建天数多点 方便) 不然正常24h就很多了  安全
headscale preauthkeys --user default create --reusable --expiration 365d
# 查看下创建的authkey
headscale preauthkeys --user default list
ID | Key                                              | Reusable | Ephemeral | Used | Expiration          | Created             | Tags
1  | 4fe241dxxxxxxxxx | true     | false     | true | 2025-08-06 06:30:50 | 2024-08-06 06:30:50 |
</code></pre>
<h4>5.3 Windows接入</h4>
<p>下面是 tailscale up 时候一些常用通用选项：</p>
<ul>
<li><code>--login-server</code>: 指定使用的中央服务器地址(必填)</li>
<li><code>--advertise-routes</code>: 向中央服务器报告当前客户端处于哪个内网网段下, 便于中央服务器让同内网设备直接内网直连(可选的)或者将其他设备指定流量路由到当前内网(可选)，多条路由英文逗号隔开</li>
<li><code>--accept-routes</code>: 是否接受中央服务器下发的用于路由到其他客户端内网的路由规则(可选)</li>
<li><code>--accept-dns</code>: 是否使用中央服务器下发的 DNS 相关配置(可选, 推荐关闭)</li>
<li><code>--hostname</code>: 设置 machine name，否则默认会以 hostname 注册上去，特别安卓的 hostname 无法修改</li>
</ul>
<p>tailscale cli 官方文档 <a href="https://tailscale.com/kb/1080/cli%EF%BC%8C%E4%B9%9F%E5%8F%AF%E4%BB%A5%E8%87%AA%E5%B7%B1">https://tailscale.com/kb/1080/cli</a>，也可以自己 <code>tailscale --help</code> 看命令帮助。</p>
<p>执行 <code>tailscale up</code> 需要 在 Tailscale 的安装目录 比如 <code>D:\software\Tailscale</code> 进行cmd</p>
<p>贴一个自用的命令</p>
<pre><code class="language-bash">tailscale up --login-server &lt;server_url&gt; --hostname &lt;自己取 需要英文&gt; --accept-routes=true --accept-dns=false --authkey &lt;就是刚刚生成的 authkey&gt;
</code></pre>
<p>还有一些简单的命令 这些命令都需要在 安装目录下的cmd 进行 使用 不然就得加个 <code>path</code> 环境变量</p>
<pre><code class="language-bash"># 这个可以看derp服务 用的哪条  哪些
tailscale netcheck

# 这个可以看状态  可以看看是否打洞成功还是走的derp服务等
tailscale status

# 用来ping测试
tailscale ping &lt;headscale 分配的ip&gt;
</code></pre>
<p>至此 headscale 部署就完成了 并且也能够接入不同的客户端了 但是但是 有个很严重的问题 由于 Tailscale和Headscale在国内都没有derp服务，而且说句实话，用人家的也觉得不是很安全，且使用的时候很卡ping测试都是上1000ms的 因此，我们需要自建derp中继服务</p>
<h2>6. Derp部署</h2>
<h4>6.1 使用域名容器（推荐）</h4>
<p>这种方案需要满足以下几个条件：</p>
<ul>
<li>要有自己的域名，并且申请了 SSL 证书</li>
<li>需要准备一台或多台云主机</li>
<li>如果服务器在国内，域名需要备案</li>
</ul>
<p>如果以上条件都俱备，就可以按照下面的步骤开始部署了。</p>
<p>使用 <code>yangchuansheng</code> 构建的docker进行部署</p>
<pre><code class="language-bash">docker run --restart always \
  --name derper -p 12345:12345 -p 3478:3478/udp \
  -v /root/.acme.sh/xxxx/:/app/certs \  # 这边并不需要用acme 自己申请证书 放到目录用来映射就行了 比如 /root/cert/ddns.cn/
  -e DERP_CERT_MODE=manual \
  -e DERP_ADDR=:12345 \
  -e DERP_DOMAIN=xxxx \
  -d ghcr.io/yangchuansheng/derper:latest
</code></pre>
<p>注意点：</p>
<ul>
<li>默认情况下也会开启 STUN 服务，UDP 端口是 <code>3478</code>；</li>
<li>防火墙需要放行端口 12345 和 3478；</li>
<li>准备好 SSL 证书；</li>
<li>域名部分我打了码，请换成你自己的域名。就是把 xxxx 替换成形如 <a href="http://ddns.cn">ddns.cn</a></li>
</ul>
<p>证书的话命名有严格要求的：</p>
<p>假设你的域名是 <code>ddns.cn</code>，那么证书的名称必须是 <code>ddns.cn.crt</code>，<strong>一个字符都不能错</strong>！同理，私钥名称必须是 <code>ddns.cn.key</code>，<strong>一个字符都不能错</strong>！</p>
<p>查看docker日志</p>
<pre><code class="language-bash">docker logs -f derper
2024/08/06 12:50:07 no config path specified; using /var/lib/derper/derper.key
2024/08/06 12:50:07 derper: serving on :12345 with TLS
2024/08/06 12:50:07 running STUN server on [::]:3478
</code></pre>
<p>部署好 derper 之后，就可以修改 Headscale 的配置来使用自定义的 DERP 服务器了。Headscale 可以通过两种形式的配置来使用自定义 DERP：</p>
<ul>
<li>一种是在线 URL，格式是 <code>JSON</code>，与 Tailscale 官方控制服务器使用的格式和语法相同。</li>
<li>另一种是本地文件，格式是 <code>YAML</code>。</li>
</ul>
<pre><code class="language-yaml"># /etc/headscale/derp.yaml
regions:
  901:
    regionid: 901
    regioncode: home
    regionname: Home XX
    nodes:
      - name: 901a
        regionid: 901
        hostname: &lt;就是上面的域名&gt;
        ipv4: &lt;公网ip  如果你跟我一样是ddns  那就写ddns的域名就行&gt;
        stunport: 3478
        stunonly: false
        derpport: 12345
</code></pre>
<p>配置说明：</p>
<ul>
<li><code>regions</code> 是 YAML 中的<strong>对象</strong>，下面的每一个对象表示一个<strong>可用区</strong>，每个<strong>可用区</strong>里面可设置多个 DERP 节点，即 <code>nodes</code>。</li>
<li>每个可用区的 <code>regionid</code> 不能重复。</li>
<li>每个 <code>node</code> 的 <code>name</code> 不能重复。</li>
<li><code>regionname</code> 一般用来描述可用区，<code>regioncode</code> 一般设置成可用区的缩写。</li>
<li><code>ipv4</code> 字段不是必须的，如果你的域名可以通过公网解析到你的 DERP 服务器地址，这里可以不填。如果你使用了一个二级域名，而这个域名你并没有在公共 DNS server 中添加相关的解析记录，那么这里就需要指定 IP（前提是你的证书包含了这个二级域名，这个很好支持，搞个泛域名证书就行了）。</li>
<li><code>stunonly: false</code> 表示除了使用 STUN 服务，还可以使用 DERP 服务。</li>
</ul>
<p>接下来还需要修改 Headscale 的配置文件，引用上面的自定义 DERP 配置文件。需要修改的配置项如下（只粘贴了需要修改的地方！！！）：</p>
<pre><code class="language-yaml"># /etc/headscale/config.yaml
derp:
  server:
    # 不启用官网自带的derp
    enabled: false
  urls:
  # - https://controlplane.tailscale.com/derpmap/defaul
  paths:
    - /etc/headscale/derp.yaml
  # paths: []
</code></pre>
<p>修改完这两份配置后 需要重启headscale服务 （一般重启比较慢 慢慢等就行 ）</p>
<pre><code class="language-bash">systemctl restart headscale
</code></pre>
<p>之后在客户端执行 <code>tailscale netcheck</code> 就可以看到自己目前使用的DERP服务了</p>
<pre><code class="language-shell">tailscale netcheck

Report:
        * UDP: true
        * IPv4: yes, xxxxx:11874
        * IPv6: no, but OS has support
        * MappingVariesByDestIP:
        * PortMapping:
        * Nearest DERP: Home xxx
        * DERP latency:
                - home: 31.8ms  (Home xxx)
</code></pre>
<p>输出类似以上。</p>
<p>这个命令实际上只检测了 <code>3478/udp</code> 的端口， 就算 netcheck 显示能连，也不一定代表 12345 端口可以转发流量。最简单的办法是直接打开 DERP 服务器的 URL：<a href="https://xxxx:12345">https://xxxx:12345</a>，如果看到如下页面，且地址栏的 SSL 证书标签显示正常可用，那才是真没问题了。</p>
<p><img src="https://iyyh.net/upload/image-kybp.png" alt="img"></p>
<h4>6.2 使用纯IP容器</h4>
<p>其实大部分人都有域名，但是呢都没备案，这点就很头疼了，只能用IP（针对国内服务器）。</p>
<p>但是但是但是，使用纯IP容器部署的话，有一个天坑，就是derper容器和headscale服务，<strong>不能处于同一台服务器中</strong>，用了一个下午才踩完的坑= = 这点一定要切记！！！！！！ 如果你只有一台公网服务器，那么已经可以不用往下看了！！！！！！</p>
<p>使用 <code>yangchuansheng</code> 构建的纯IP docker进行部署</p>
<pre><code class="language-bash">docker run --restart always --name derper -d -p 59443:443 -p 3478:3478 -p 3478:3478/udp ghcr.io/yangchuansheng/ip_derper
</code></pre>
<p>记得放行 <code>59443</code> 和 <code>3478</code> 这两个端口</p>
<p>这里贴一个作者的docker日志（懒得再新建一个容器了）</p>
<pre><code class="language-bash">docker logs -f derper
Generating a RSA private key
.......................................+++++
..............+++++
writing new private key to '/app/certs//127.0.0.1.key'
-----
2022/03/26 14:30:31 no config path specified; using /var/lib/derper/derper.key
2022/03/26 14:30:31 derper: serving on :443 with TLS
2022/03/26 14:30:31 running STUN server on [::]:3478
</code></pre>
<p>接下来就是配置Derp的配置文件咯。</p>
<p>Headscale 的本地 YAML 文件目前还不支持这个配置项，所以没办法，目前只能使用在线 URL 了。（这点我没有验证，沿用作者的说法，不想在折腾这个纯IP了= =）</p>
<pre><code class="language-json">{
  &quot;Regions&quot;: {
    &quot;901&quot;: {
      &quot;RegionID&quot;: 901,
      &quot;RegionCode&quot;: &quot;ali-sh&quot;,
      &quot;RegionName&quot;: &quot;Aliyun Shanghai&quot;,
      &quot;Nodes&quot;: [
        {
          &quot;Name&quot;: &quot;901a&quot;,
          &quot;RegionID&quot;: 901,
          &quot;DERPPort&quot;: 443,
          &quot;HostName&quot;: &quot;xxxx&quot;,
          &quot;IPv4&quot;: &quot;xxxx&quot;,
          &quot;InsecureForTests&quot;: true
        }
      ]
    }
  }
}
</code></pre>
<p>配置说明：</p>
<ul>
<li><code>HostName</code> 直接填 derper 的公网 IP，即和 <code>IPv4</code> 的值相同。</li>
<li><code>InsecureForTests</code> 一定要设置为 true，以跳过域名验证。</li>
</ul>
<p>需要把这个 JSON 文件变成 Headscale 服务器可以访问的 URL，比如在 Headscale 主机上搭个 Nginx，或者上传到对象存储（比如阿里云 OSS）。</p>
<p>一样的修改Headscale 的配置文件</p>
<pre><code class="language-yaml"># /etc/headscale/config.yaml
derp:
  server:
    # 不启用官网自带的derp
    enabled: false
  urls:
    - https://xxxxx/derp.json
  paths:
  # - /etc/headscale/derp.yaml
  # paths: []
</code></pre>
<p>修改完这两份配置后 需要重启headscale服务 （一般重启比较慢 慢慢等就行 ）</p>
<pre><code class="language-bash">systemctl restart headscale
</code></pre>
<p>之后在客户端执行 <code>tailscale netcheck</code> 就可以看到自己目前使用的DERP服务了</p>
<pre><code class="language-shell">tailscale netcheck

Report:
        * UDP: true
        * IPv4: yes, xxxxx:11874
        * IPv6: no, but OS has support
        * MappingVariesByDestIP:
        * PortMapping:
        * Nearest DERP: Home xxx
        * DERP latency:
                - home: 31.8ms  (Home xxx)
</code></pre>
<p>输出类似以上。</p>
<p>这个命令实际上只检测了 <code>3478/udp</code> 的端口， 就算 netcheck 显示能连，也不一定代表 12345 端口可以转发流量。最简单的办法是直接打开 DERP 服务器的 URL：<a href="https://xxxx:12345">https://xxxx:12345</a>，如果看到如下页面，且地址栏的 SSL 证书标签显示正常可用，那才是真没问题了。</p>
<p><img src="https://image.iyyh.net/image-kybp.png" alt="DERP 成功启动页"></p>
<h2>7. 踩坑总结</h2>
<ol>
<li>建议不要用root 直接运行 headscale 否则会有很多奇奇怪怪的问题 <strong>用一上午的踩坑经验出来的</strong></li>
<li>使用纯IP 一定要把derper建在非headscale服务所在的服务，否则大大的问题 <strong>用一下午的踩坑经验出来的</strong></li>
</ol>
<p>至此，教程结束，希望能够在本文的经验下，能够帮助到大家！</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[解决Moviepy剪辑视频画面卡帧，但有声的问题]]></title>
            <link>https://iyyh.net/posts/2024/08/fix-moviepy-video-freeze</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/08/fix-moviepy-video-freeze</guid>
            <pubDate>Thu, 01 Aug 2024 03:17:43 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1. 起因</h3>
<p>最近在做视频批量化处理，调研要么用moviepy，要么用ffmpeg。后面选择用moviepy，因为上手更简单一点。</p>
<p>但是在根据逻辑（删除视频的前两秒和后两秒，只保留中间部分）进行裁剪时，发现只要经过裁剪的视频，都会出现一个问题： <strong>前1s左右的画面能而动，但是后面的视频画面不动，但是声音继续播放</strong></p>
<p>这是非常致命的，这相当于就是把整个视频毁了，因此需要排查解决。</p>
<h3>2. 思考过程</h3>
<p>先简单看一下我写的代码</p>
<pre><code class="language-python">        # 根据逻辑裁剪视频
        if duration &gt;= 6:
            logger.info(f&quot;视频 {video_file} 大于6秒，前后裁剪2秒。&quot;)
            # 计算裁剪的起始和结束时间
            start_time = 2
            end_time = duration - 2
            new_clip = clip.subclip(start_time, end_time)
            # 处理裁剪后还是大于10s的视频
            if new_clip.duration &gt;= 10:
                print(f&quot;视频 {video_file} 大于10秒，加速1.2倍。&quot;)
                new_clip = speedx(new_clip, factor=1.2)

        else:
            # 小于6秒的视频不进行裁剪
            new_clip = clip

        # 保存裁剪后的视频
        new_clip.write_videofile(video_file, remove_temp=True, fps=clip.fps)
</code></pre>
<p>可以看到 有两个地方会涉及到视频的处理：</p>
<ol>
<li>视频时长 <code>duration &gt;= 6</code> 大于等于6s</li>
<li>裁剪后的时长 <code>new.clip.duration &gt;= 10</code> 还是大于等于10s，那么就对视频进行加速处理</li>
</ol>
<h4>2.1 思考一</h4>
<p>因为出现“卡帧”的情况最早是挺随机的，只在后面<strong>加速视频</strong>的时候出现，我就先删除这部分逻辑，也就仅保留</p>
<pre><code class="language-python">         # 根据逻辑裁剪视频
        if duration &gt;= 6:
            logger.info(f&quot;视频 {video_file} 大于6秒，前后裁剪2秒。&quot;)
            # 计算裁剪的起始和结束时间
            start_time = 2
            end_time = duration - 2
            new_clip = clip.subclip(start_time, end_time)

        else:
            # 小于6秒的视频不进行裁剪
            new_clip = clip

        # 保存裁剪后的视频
        new_clip.write_videofile(video_file, remove_temp=True, fps=clip.fps)
</code></pre>
<p>但是发现，我这么改了以后，之前裁剪的视频，也一样会出现“卡帧”的情况。</p>
<p>因此，这部分肯定不是问题所在。</p>
<h4>2.2 思考二</h4>
<p>后面我就在想，是不是moviepy这个库的的问题，于是我就想，直接换成ffmpeg来处理</p>
<pre><code class="language-python">        cmd = [
            &quot;ffmpeg&quot;,
            &quot;-y&quot;,  # 自动确认覆盖输出文件
            &quot;-i&quot;,
            input_file,
            &quot;-ss&quot;,
            str(2),  # 起始时间
            &quot;-t&quot;,
            str(duration - 4),  # 持续时间
            &quot;-c:v&quot;,
            &quot;-c:a&quot;,
            &quot;-strict&quot;,
            output_file,
        ]
</code></pre>
<p>此时，我以为解决了，满怀信心的运行，发现出来的视频还是一样的卡帧= =</p>
<p>至此，陷入了一个死循环，本身我是知道moviepy底层其实调用的也是ffmpeg，我以为是moviepy封装ffmpeg的时候导致的一些问题，但是现在看来不是，因为我直接使用ffmpeg，还是一样的问题。因此，可以断定，问题出在ffmpeg上面。</p>
<p>开始寻找解决方案，功夫不负有心人，终于看到了一篇<a href="https://blog.csdn.net/weixin_38443388/article/details/126375297">blog</a>！并且其附带了一个<a href="https://www.bilibili.com/video/BV1ts411C7sN?spm_id_from=333.337.search-card.all.click&amp;vd_source=b1fee33b8eac09fb7c96674a0b2399bb">视频</a>~ 因此，在看了blog和视频后，终于终于解决方案出来了！</p>
<h3>3.解决方案</h3>
<p>重点如下：</p>
<pre><code class="language-text">因为I帧的关系，视频解码时从I帧开始的，如果你的开始时间点不是I帧，则只先解码音频，等到下一个I帧时间点时，开始播放视频，之前卡的那个画面也是下一个I帧。可以用aegisub看I帧，知道前后I帧的位置，决定从哪个I帧开始截取，或者把-ss写在-i前面，但此时不能用-to，只能用-t。
</code></pre>
<p>讲这么多，其实我也不懂前半段句是什么意思。后面简单看了看文档，总结概括如下：</p>
<pre><code class="language-text">视频帧类型：
在视频压缩中，帧被分为不同类型，主要有三种：I帧（关键帧）、P帧（预测帧）和B帧（双向预测帧）。
I帧是自包含的帧，不依赖于其他帧的信息，是视频解码的起点和参考点。P帧和B帧则依赖于其他帧的信息。

视频解码的开始：
当解码器开始解码视频流时，它必须从一个I帧开始。如果你指定的起始时间点不是一个I帧，解码器会等待直到下一个I帧出现才开始解码视频部分。
在等待期间，音频部分会继续解码和播放，这会导致画面停滞在上一个I帧的图像。
</code></pre>
<p>简单来说 I帧非常重要 裁剪必须是他起手，但是在我这种设定下，很明显 不好实现。</p>
<p>再看后半句，总结了一下：</p>
<pre><code class="language-text">要避免卡帧，需要确保 -ss 参数指定的时间点正好是一个I帧的位置。
可以通过使用 aegisub 或者查阅视频信息来确定合适的起始时间点。
如果无法确保，可以通过调整 -ss 和 -t 参数的组合来控制视频裁剪的时长，以确保视频从一个完整的I帧开始解码。
</code></pre>
<p>我并不想去确认关键帧的位置，因为他相对来说 比较麻烦。</p>
<p>一开始的指令就是 把 -ss 放在 -t 前面 发现其实并不管用，因此 这个方法只能算放弃了= =</p>
<p>但是但是，在这个方法的启发下，我突然意识到，<strong>如果保存的时候，我重新编码，是不是就能解决</strong>！</p>
<p>因此，最终的解决方案如下：</p>
<pre><code class="language-python">        # 导出处理后的视频（重新编码）
        new_clip.write_videofile(
            output_file,
            codec=&quot;libx264&quot;,
            audio_codec=&quot;aac&quot;,
            temp_audiofile=&quot;temp-audio.m4a&quot;,
            remove_temp=True,
            fps=clip.fps,
            preset=&quot;medium&quot;,  # 可以根据需要调整，如 &quot;fast&quot;, &quot;slow&quot; 等
            ffmpeg_params=[&quot;-crf&quot;, &quot;0&quot;],  # 控制质量，值越低质量越高，0表示完整保留视频画质，不压缩
        )
</code></pre>
<p>终于终于，解决了！！！！</p>
<p>其实核心在</p>
<ol>
<li><code>crf</code> 是ffmpeg中控制视频编码质量的参数，0 表示无损编码。当设置为0时，每一帧都会被认为是关键帧（I帧），因为无损编码要求每一帧都能独立解码，不依赖于其他帧的信息。</li>
<li>当调用 <code>write_videofile</code> 并指定 <code>codec=&quot;libx264&quot;</code> 和 <code>audio_codec=&quot;aac&quot;</code> 时，<code>moviepy</code> 将使用 <code>libx264</code> 编码器重新对视频进行编码，同时将音频编码为 AAC 格式。</li>
<li>在重新编码过程中，ffmpeg会生成新的关键帧序列，确保新输出的视频从一个I帧开始，避免了旧视频中可能存在的不完整的关键帧问题。</li>
</ol>
<p>到这里所有问题都解决啦，但是其中还有需要注意点</p>
<p>虽然这种方法解决了卡帧问题，但重新编码可能会导致一定的质量损失，并且会消耗更多的处理时间和计算资源。因此，建议在选择重新编码作为解决方案时，权衡好输出质量和性能需求。</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Surge Or Mihomo通过WireGuard回家]]></title>
            <link>https://iyyh.net/posts/2024/07/surge-or-mihomo-uses-WireGuard-to-connect-backhome</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/07/surge-or-mihomo-uses-WireGuard-to-connect-backhome</guid>
            <pubDate>Tue, 30 Jul 2024 01:56:59 GMT</pubDate>
            <content:encoded><![CDATA[<h2>1.起因</h2>
<p>家里一直有一台软路由，且一直都携带着公网V4，之前有装openwrt的时候，都会开个ss用来回家用，但是现在不是很想装openwrt。于是有了以下的一些折腾。</p>
<p>因为我使用的是ios，也购买了Surge，同时其支持WireGuard协议，最后再去看了下mihomo，也支持WireGuard那么使用WireGuard回家将是最好的选择啦~</p>
<p>最后简单介绍下自己的设备吧。</p>
<p>软路由：5105 (ikuai 主路由、 Debian 、Windows10) -- <strong>all in boom</strong></p>
<p>Debian - &gt; <strong>服务端</strong></p>
<p>装有ios的Surge - &gt; <strong>客户端</strong></p>
<h2>2.安装</h2>
<p>为了保证系统的稳定性，将WireGuard安装在Debian上。使用root权限执行以下命令：</p>
<pre><code class="language-bash">apt install wireguard
</code></pre>
<h2>3.生成公钥私钥</h2>
<p>所有的公钥私钥 <strong>都是从服务端来生成的</strong> 这点是重中之重</p>
<h3>3.1 服务端公钥私钥生成</h3>
<p>先生成服务端的公钥私钥</p>
<pre><code class="language-bash">cd /etc/wireguard
wg genkey | tee server_private.key | wg pubkey &gt; server_public.key
</code></pre>
<h3>3.2 客户端公钥私钥生成</h3>
<p>其实就看你有多少个客户端，比如你想用一台装有surege的iphone 和 一台装有mihomo的windows 那就是生成2对公钥私钥</p>
<p>简单理解 <strong>几个设备 -&gt; 几对公私钥对</strong></p>
<p>同样的命令 也是 在 <code>/etc/wireguard</code> 这个目录下 执行</p>
<pre><code class="language-bash">wg genkey | tee ios_private.key | wg pubkey &gt; ios_public.key
</code></pre>
<h2>4.编写wg*.conf</h2>
<p>wg的conf 必须在 <code>/etc/wireguard</code> 下，且命名必须是 wg*.conf 的形式 * 放数字就行，比如 <code>wg0.conf</code></p>
<pre><code class="language-ini">[Interface]
# 服务端的IP地址和子网掩码，定义了WireGuard接口的网络范围
Address = 192.168.63.1/24
# WireGuard服务器监听的UDP端口（注意 端口需要放行）
ListenPort = 22334
# 服务器的私钥，用于加密和身份验证
PrivateKey = &lt;服务端私钥 也就是 server_private.key 的值&gt;

# ens18是网卡 需要自己查看
# 在WireGuard启动时执行的命令，设置防火墙规则以允许流量转发和NAT
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
# 在WireGuard关闭时执行的命令，移除之前添加的防火墙规则
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE

# 以一台装有surge的iphone为例
[Peer]
# 客户端的公钥，用于验证客户端身份
PublicKey = &lt;ios公钥 也就是 ios_public.key 的值&gt;
# 允许此客户端使用的IP地址，/32表示单个特定IP
AllowedIPs = 192.168.63.2/32

# 以一台装有mihomo的windows为例
[Peer]
# 客户端的公钥，用于验证客户端身份
PublicKey = &lt;windows公钥 也就是 windows_public.key 的值&gt;
# 允许此客户端使用的IP地址，/32表示单个特定IP
AllowedIPs = 192.168.63.3/32
</code></pre>
<p>接下来说说自己的踩坑点</p>
<h3>4.1 注意点</h3>
<ol>
<li>端口一定要放行，只需要放行udp就行了</li>
<li>密钥的一些交互，一定不要错了，简单理解<br>
服务端的conf只需要放 <strong>服务端自己的私钥</strong> 和 <strong>其他客户端的公钥</strong> 即可</li>
<li><strong>网卡</strong> 一定要看自己出口的是哪张网卡，一般不能照抄！！！</li>
<li>如果对子网掩码有疑问，简单理解就是，服务端包含整个网段，所以是24；客户端因为指代的就是一个设备，所以是32</li>
</ol>
<p>至此 wg0.conf 配置完毕</p>
<h2>5. 服务端启动</h2>
<pre><code class="language-bash">cd /etc/wireguard
wg-quick up wg0
</code></pre>
<p>启动完可以 输入 <code>wg</code> 看下是否确实启动了</p>
<h2>6. 配置Surge</h2>
<p>一共有三个地方需要配置，具体如下：</p>
<pre><code class="language-stylus">[Proxy]
Home = wireguard, section-name = Home

[Rule]
IP-CIDR,192.168.88.0/24,Home,no-resolve

[WireGuard Home]
private-key = &lt;ios私钥 也就是 ios_private.key 的值&gt;
self-ip = 192.168.63.2
mtu = 1280
peer = (public-key = &lt;服务端公钥 也就是 server_public.key 的值&gt;, allowed-ips = &quot;0.0.0.0/0, ::0/0&quot;, endpoint = ddns.cn:22334, keepalive = 25)
</code></pre>
<h3>6.1 注意点</h3>
<ol>
<li>因为我实现的是通过wg就能访问家里所有设备 我家里是88网段，所以[Rule]是88网段 （这点很重要 我之前把 Interface 的网段也写进来了 但是 不能访问家里所有设备）</li>
<li>self-ip 需要与 Interface 同一个网段</li>
<li>endpoint 家里公网ip的 <code>ddns:端口</code> 即可</li>
</ol>
<h2>7.1 配置mihomo</h2>
<p>参考的官方的 与 surge 其实类似</p>
<pre><code class="language-yaml">proxies:
  - name: wg
    type: wireguard
    ip: 192.168.63.3
    # 我不用V6 所以不开
    # ipv6: fd01:5ca1:ab1e:80fa:ab85:6eea:213f:f4a5
    private-key: &lt;windows私钥 也就是 windows_private.key 的值&gt;
    peers:
      - server: ddns.cn
        port: 22334
        public-key: &lt;服务端公钥 也就是 server_public.key 的值&gt;
        allowed-ips: [0.0.0.0/0]
      # pre-shared-key: 31aIhAPwktDGpH4JDhA8GNvjFXEf/a6+UaQRyOAiyfM=
      # reserved: [209,98,59]  # 字符串格式也是合法的，如&quot;U4An&quot;
    udp: true
  # mtu: 1408
  # dialer-proxy: &quot;ss1&quot;  # 一个出站代理的标识。当值不为空时，将使用指定的 proxy/proxy-group 发出连接
  # remote-dns-resolve: true # 强制dns远程解析，默认值为false
  # dns: [ 1.1.1.1, 8.8.8.8 ] # 仅在remote-dns-resolve为true时生效
</code></pre>
<p>至此教程结束</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[重装系统 -- Windows11]]></title>
            <link>https://iyyh.net/posts/2024/07/reinstalling-windows11-made-simple</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/07/reinstalling-windows11-made-simple</guid>
            <pubDate>Sun, 28 Jul 2024 03:26:05 GMT</pubDate>
            <content:encoded><![CDATA[<h2>1.起因</h2>
<p>吻妻的<a href="https://iwin10.net/">专注于win10</a> ，这个系统自己用了4年了，确实很不错，还是很推荐吻妻做的镜像的。</p>
<p>但是使用了一个礼拜，发现有大大小小的问题，比如：任务栏偶尔卡住，需要等半天才有响应；没启动什么应用，风扇偶尔莫名狂转等。后面调研了一下13 14代的CPU，有大小核设计，目前只有Windows11支持，所以被迫换Windows11（之前是有使用过的，简直是一坨，所以第一时间没装win11）</p>
<p>因此，就更换了windows11，在使用了一两个礼拜，发现还挺不错的，跟之前我体验装的win11相比，进步实在是太多了。又被安利了一款浏览器 <a href="https://arc.net/">Arc</a> 体验了一个礼拜下来，非常不错（个人感觉确实可以替代chrome了~），但是有个弊端，目前只能在win11上使用，但是自己笔记本又是win10，因此权衡利弊下，决定把我四年前买的笔记本，升级win11。 因此就有了以下的内容咯~</p>
<p>但是用久了发现。windows 上到的 Arc，其实没那么理想，还是推荐 mac 使用</p>
<h2><a href="http://2.PE">2.PE</a></h2>
<p>市面上的PE非常多，比如：</p>
<ul>
<li><a href="https://www.wepe.com.cn/">WePe</a></li>
<li><a href="https://www.firpe.cn/">FirPe</a></li>
<li><a href="https://www.hotpe.top/">HotPE</a></li>
<li><a href="https://rufus.ie/zh/">Rufus</a></li>
<li><a href="https://ventoy.net/cn/index.html">Ventory</a></li>
<li><a href="https://www.uqitong.top/">优启通</a></li>
</ul>
<p>顺便说说自己装机用的PE的使用阶段吧。</p>
<p>刚开始学习重装系统的时候使用的是Wepe以及优启通，后面这两个用腻了，跑去用FirPe了。</p>
<p>但是这次想换个思路，做了一圈调研。</p>
<p><strong>决定拿Ventory做Pe，而后把WePe的镜像文件放里面，最后再放不同的系统镜像</strong></p>
<p>形如：</p>
<p><img src="https://image.iyyh.net/image-xkmk.png" alt="u 盘"></p>
<p>为什么这么做呢，原因如下Pe其实多多少少都会带点东西，不够“净“（这个每个人都有自己的理解，不过多阐述），Ventory呢，“很干净”，因此拿他来做Pe层；之后为什么要放WePe，因为他相对来说小了一点，我只需要用到分区工具，就是每次重装前格盘等操作，因此放一个，挺好的，还有就是如果有时候想换镜像WIM或者GHO镜像的时候，Ventory只能识别ISO的镜像，刚好拿WePe顶顶。格完盘分完区之后就重启，再进Ventory，而后选择Windows11的ISO镜像进行下一步咯。</p>
<h2>3.系统镜像</h2>
<p>Windows10：如果要纯净版本（也相对来说更推荐）</p>
<p><a href="https://iwin10.net/">吻妻-专注于Win10</a></p>
<p>其次，Windows11或者Windows10官方镜像 （建议直接微软官方进行下载）</p>
<p><a href="https://msdl.gravesoft.dev/">Microsoft Software Download Listing</a> （这是整合站点 出出也是微软方法下载地址）</p>
<h2>4.解决部分系统Ventory进不去问题</h2>
<p>问题如下：</p>
<p><img src="https://image.iyyh.net/image-uuvc.png" alt="error"></p>
<p>进入Ventory启动盘发现蓝屏，报错这个，这个安装下Ventory的证书就行</p>
<ol>
<li>回车 OK</li>
<li>选中 Enroll key from disk<br>
<img src="https://image.iyyh.net/image-saoc.png" alt="error1"></li>
<li>选中Ventory<br>
<img src="https://image.iyyh.net/image-qwfu.png" alt="error2"></li>
<li>选中.cer文件<br>
<img src="https://image.iyyh.net/image-yhsj.png" alt="error4"></li>
<li>然后 continue - yes - reboot 即可正常进入Ventory</li>
</ol>
<p>具体细致的步骤就不写啦，需要有一定动手能力~</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Win10/11配置fnm：解决PowerShell脚本运行受限问题]]></title>
            <link>https://iyyh.net/posts/2024/07/fnm-setup-fix-windows</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/07/fnm-setup-fix-windows</guid>
            <pubDate>Wed, 03 Jul 2024 02:57:08 GMT</pubDate>
            <content:encoded><![CDATA[<h2>一、 Windows 10</h2>
<h4>1. 问题</h4>
<p>这两天装了个 <code>fnm</code> 然而在Win10如果要体验完整的 <code>fnm</code> 需要对 <code>PowerSherll</code> 进行一些设置。</p>
<p>具体目录在 <code>C:\Users\Administrator\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1</code></p>
<p>一般是没有这个文件 需要自己新建这个文件 同时 请看下自己的用户名是啥 这个就是用户目录。</p>
<p>在这个文件里放入以下代码：</p>
<pre><code>fnm env --use-on-cd | Out-String | Invoke-Expression
</code></pre>
<p>然后就行了。</p>
<p>但是当你打开PowerShell后 出现以下报错：</p>
<pre><code>“无法加载文件……profile.ps1，因为在此系统上禁止运行脚本”
</code></pre>
<p><img src="https://image.iyyh.net/1720015082733.jpg.jpeg" alt="报错信息"></p>
<p>图片引用他处。</p>
<h4>2. 解决</h4>
<p>解决过程如下：</p>
<ul>
<li>以管理员权限打开PowerShell</li>
<li>输入 <code>Set-ExecutionPolicy -ExecutionPolicy RemoteSigned</code></li>
</ul>
<p><img src="https://image.iyyh.net/image-qtor.png" alt="powershell"></p>
<ul>
<li>输入： <code>y</code> 确认修改安全策略</li>
</ul>
<p>即可解决。</p>
<h2>二、 Windows 11</h2>
<p>win11与win10有些许不同，不再是 <code>WindowsPowerShell</code> 这个目录。因此需要先使用 <code>$profile</code> 这个命令看看是哪个目录</p>
<p>基本上的返回是 <code>C:\Users\Administrator\Documents\PowerShell\Microsoft.PowerShell_profile.ps1</code></p>
<p>可以看到 不同点是 <code>PowerShell</code> 因此 只需要 在这个目录下创建 <code>Microsoft.PowerShell_profile.ps1</code> 这个文件就能解决</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Ai 原画系统]]></title>
            <link>https://iyyh.net/posts/2024/06/ai-illustration-system</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/06/ai-illustration-system</guid>
            <pubDate>Sun, 16 Jun 2024 06:19:52 GMT</pubDate>
            <content:encoded><![CDATA[<p>项目演示视频如下：</p>
<video controls width="100%" style="border-radius:10px;">
  <source src="https://blog-r2.iyyh.net/488126.mp4" type="video/mp4">
</video>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[基于社交媒体大数据的智慧政务系统]]></title>
            <link>https://iyyh.net/posts/2024/06/smart-gov-social-data</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/06/smart-gov-social-data</guid>
            <pubDate>Sun, 16 Jun 2024 06:11:02 GMT</pubDate>
            <content:encoded><![CDATA[<p>项目演示视频如下：</p>
<video controls width="100%" style="border-radius:10px;">
  <source src="https://blog-r2.iyyh.net/基于社交媒体大数据的智慧政务系统.mp4" type="video/mp4">
</video>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Miniconda安装教程]]></title>
            <link>https://iyyh.net/posts/2024/06/miniconda-installation-tutorial</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/06/miniconda-installation-tutorial</guid>
            <pubDate>Sun, 16 Jun 2024 02:36:04 GMT</pubDate>
            <content:encoded><![CDATA[<h3>1.起因</h3>
<p>从开始学习 python一直以来都是用的Anaconda，直到前不久实习公司里都是用的Miniconda，仔细了解了下发现Miniconda更加适合我。又刚好重装了自己的笔记本，就把Anaconda换成Miniconda了。</p>
<p>这里大概总结了下二者的区别：</p>
<ul>
<li>选择<strong>Anaconda</strong>：
<ul>
<li>需要一个开箱即用的环境。</li>
<li>适合数据科学或机器学习的新手。</li>
<li>需要一个包含众多预装库的环境。</li>
</ul>
</li>
<li>选择<strong>Miniconda</strong>：
<ul>
<li>想要一个轻量级的安装。</li>
<li>具有一定的Python和环境管理经验。</li>
<li>需要一个高度定制的Python环境。</li>
</ul>
</li>
</ul>
<p>那我是觉得安装环境什么的自己来比较舒服，就不用“大而全”的Anaconda了</p>
<h3>2.Window安装</h3>
<p>自从接触国内源以来，换来换去，最终还是觉得清华源是真正的“大而全”，因此，接下来都会使用<a href="https://mirrors.tuna.tsinghua.edu.cn/">清华源</a>。<code>https://mirrors.tuna.tsinghua.edu.cn/</code></p>
<h4>2.1 访问<a href="https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/">Miniconda清华源url</a></h4>
<h4>2.2 点击Date旁的小箭头</h4>
<p><img src="https://image.iyyh.net/image-rlej.png" alt="清华源"></p>
<p>该操作是为了获取当前最新版本的Miniconda安装包</p>
<h4>2.3 选择安装包</h4>
<p>Miniconda3-py311_24.4.0-0-Windows-x86_64.exe</p>
<p>文件名解读：py311就是指安装完后他的base环境是python3.11版本的（这个我推荐截止到文本所写时间都装py311吧，具体原因的话，我觉得相对较新，但是又不是最新，像现在的大模型都是基于py3.10+进行了，所以我是觉得如果对环境管理不是那么强的话，以3.11作为base挺好的）</p>
<h4>2.4 下载安装</h4>
<p>这边就只需要注意一个点，安装的目录环境，别的就是无脑下一步就行了。</p>
<p>这个我有个习惯可以跟大家分享：我的电脑有两个盘，一个C、一个D，我安装环境一般都是放在D盘下，并且会新建一个文件夹，名为<code>Envs</code> ，这样我会把所有开发环境都放在这个文件夹里，比如jdk8，Miniconda等。</p>
<h4>2.5 系统环境变量</h4>
<p>我的电脑--右键--属性--高级系统设置--环境变量--系统变量下的Path（建议用系统变量，当然你用用户变量也可以，但是只有在这个登录用户下生效）--加入以下内容</p>
<pre><code class="language-bash">D:\Envs\miniconda3
D:\Envs\miniconda3\Library\bin
D:\Envs\miniconda3\Scripts
</code></pre>
<p><strong>注意</strong> 请自行更改你的安装目录，这里是我自己的目录</p>
<p><img src="https://image.iyyh.net/image-kuti.png" alt="windows path"></p>
<p>之后，一路确定点完就行。</p>
<h4>2.6 验证</h4>
<p>打开 <code>cmd</code> 窗口 输出</p>
<pre><code class="language-bash">conda -V
</code></pre>
<p><img src="https://image.iyyh.net/image-xpfy.png" alt="version check"></p>
<p>输出对应conda版本即可</p>
<h3>3.Linux安装</h3>
<h4>3.1 下载</h4>
<pre><code class="language-bash">wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/Miniconda3-py311_24.4.0-0-Linux-x86_64.sh
</code></pre>
<p>这里注意看自己Linux是什么架构的 <code>x86_64</code> 就是对应的架构 还有以下一些架构</p>
<p><img src="https://image.iyyh.net/image-dmth.png" alt="linux 清华源"></p>
<h4>3.2 执行脚本安装</h4>
<pre><code class="language-bash">./Miniconda3-py311_24.4.0-0-Linux-x86_64.sh
或者
bash Miniconda3-py311_24.4.0-0-Linux-x86_64.sh
</code></pre>
<p>具体包名根据你自己下载的版本修改</p>
<p>脚本需要手动输入的时候输入 <code>yes</code> 就行，这样会自动添加环境变量</p>
<h3>4.换源</h3>
<h4>4.1 conda换清华源</h4>
<p>先执行 <code>conda config --set show_channel_urls yes</code></p>
<p>然后到用户目录下，找到 <code>.condarc</code> 文件，像我就是 <code>C:\Users\Administrator</code> 这个目录下 <code>Administrator</code> 改成你自己对应的用户名</p>
<p>编辑 <code>.condarc</code> 文件</p>
<pre><code class="language-bash">channels:
  - defaults
show_channel_urls: true
default_channels:
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r
  - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2
custom_channels:
  conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  pytorch-lts: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
  deepmodeling: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/
</code></pre>
<p>复制粘贴以下内容，保存</p>
<p>运行 <code>conda clean -i</code> 清除索引缓存</p>
<p>这样接下来的一系列 <code>conda create/install</code> 就是用的清华源了</p>
<h4>4.2 pip换清华源</h4>
<p><code>cmd</code> 执行以下命令即可</p>
<pre><code class="language-bash">pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
</code></pre>
<p><strong>PS</strong>：后面我都拥抱 <code>pdm</code>和 <code>uv</code> 啦，这个就当做归档吧，毕竟用了非常久的 conda～</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[Doker-compose 网络互通]]></title>
            <link>https://iyyh.net/posts/2024/05/docker-compose-networking</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2024/05/docker-compose-networking</guid>
            <pubDate>Thu, 02 May 2024 03:12:11 GMT</pubDate>
            <content:encoded><![CDATA[<p>这两天由于购入halo pro，关注到飞致云旗下还有个<strong>1Panel</strong>，因此打算将服务也全部迁到<strong>1Panel</strong>，刚好有个可视化面板。</p>
<h3>踩坑1：</h3>
<p>1Panel默认开启了WAF（哪怕没有购入1Panel专业版也开启），会导致halo有一系列不正常现象。因此，第一件事情，需要将WAF关闭。</p>
<p>具体配置如下：</p>
<p><img src="https://image.iyyh.net/image-hcsw.png" alt="waf"></p>
<h3>踩坑2：</h3>
<p>接下来就是迁移服务咯，迁移one-api的时候出现了个问题，就是容器之间网络不互通。</p>
<p>查看1Panel-容器-网络</p>
<p><img src="https://image.iyyh.net/image-saxg.png" alt="docker"></p>
<p>可以看到1panel的docker网络信息，采用的是bridge的形式。</p>
<p>因为one-api需要使用到mysql、redis，因此，先提前在1panel-数据库下进行相关数据库安装：</p>
<p><img src="https://image.iyyh.net/image-fwhp.png" alt="network"></p>
<p>安装完成后查看下这两个数据库容器的信息：</p>
<p><img src="https://image.iyyh.net/image-yras.png" alt="docker-network"></p>
<p>可以看到，其网段都在 <code>192.168.96.0/20</code> 这个网段下，并且其映射的地址为 <code>127.0.0.1</code>，也就是只能在这个网段下进行访问，其他网段是不可以进行访问的</p>
<p>开始编写 compose，只写需要网络信息的地方</p>
<pre><code class="language-yaml">environment:
  - SQL_DSN=aaa:123@tcp(db:3306)/one-api
  - REDIS_CONN_STRING=redis://redis:6379
  - SESSION_SECRET=yyhhyy
  - TZ=Asia/Shanghai
</code></pre>
<p>可以看到，上面的连接都是用指代的 <code>db</code> <code>redis</code> 用来指代服务器的ip地址。</p>
<p>我先后尝试用 <code>localhost</code> 以及他们分别对应的 <code>容器ip</code>进行编写都不行</p>
<p>最后学习了一套写法，仅供参考（以下为完整、可解析的 compose 片段）：</p>
<pre><code class="language-yaml">services:
  one-api:
    environment:
      - SQL_DSN=aaa:123@tcp(1Panel-mysql-X3XP:3306)/one-api # 将 db 修改成 mysql 容器名称
      - REDIS_CONN_STRING=redis://1Panel-redis-QTio:6379 # 将 redis 修改成 redis 容器名称
      - SESSION_SECRET=yyhhyy
      - TZ=Asia/Shanghai
    networks:
      - 1panel-network # 将 one-api 放入与数据库相同的网络
networks:
  1panel-network:
    external: true # 使用已存在的网络
</code></pre>
<p>解释：</p>
<ol>
<li>
<p><strong>网络配置</strong>：<code>one-api</code>服务现在使用 <code>1panel-network</code>网络，这个网络需要是一个已经存在的网络，通过 <code>external: true</code>指明。</p>
</li>
<li>
<p><strong>环境变量中的连接字符串</strong>：</p>
<ul>
<li><code>SQL_DSN</code>现在使用 <code>1Panel-mysql-X3XP</code>这个服务名称进行连接。</li>
<li><code>REDIS_CONN_STRING</code>同样使用 <code>1Panel-redis-QTio</code>作为服务名称。</li>
</ul>
<p>也就是分别使用<strong>同一网段下的容器名</strong>填写即可。</p>
</li>
</ol>
<p>至此，问题解决</p>
<h3>不同容器通信技巧：</h3>
<h4>情形一：</h4>
<p>两个容器 <strong>都在</strong> 同一个docker网络组中</p>
<p>如果两个容器都在同一个docker网络组中，直接在需要网络通信的地方，使用 <code>&lt;容器名&gt;:&lt;容器端口&gt;</code></p>
<h4>情形二：</h4>
<p>两个容器 <strong>不在</strong> 同一个docker网络组中</p>
<p>那么使用 <code>&lt;容器使用的网络模式的网关&gt;:&lt;宿主机端口(也就是映射端口)&gt;</code> 即可</p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
        <item>
            <title><![CDATA[建立菲律宾台风损害模型]]></title>
            <link>https://iyyh.net/posts/2023/07/philippines-typhoon-damage-model</link>
            <guid isPermaLink="true">https://iyyh.net/posts/2023/07/philippines-typhoon-damage-model</guid>
            <pubDate>Thu, 27 Jul 2023 06:38:51 GMT</pubDate>
            <content:encoded><![CDATA[<h3><strong>客观性</strong></h3>
<p>使用过去 20 年 12 场台风的数据，介绍了菲律宾台风造成的建筑物损坏统计模型的开发过程。</p>
<p>构建损坏模型本质是为了预测全国每个城市受损房屋的比例，使用一组与灾害相关的指标（例如风速）和社会经济指标（例如贫困发生率或墙体建筑质量）作为预测因子。</p>
<p>建立损坏模型：模型用于预测城市中受损房屋的比例。</p>
<h3><strong>数据来源</strong></h3>
<p>损坏模型是根据过去几十年台风造成的建筑物损坏的观测结果建立的（<a href="https://dashboard.510.global/#!/impact_database">510 Global</a>）。该数据集包含 1,638 个观测值，对应菲律宾全国 1,034 个城市以及 12 个台风的影响。它有 34 列，对应于台风过后调查的数据以及每个城市对应的其他现场和社会经济指标。</p>
<ul>
<li><strong>损坏指标</strong>：台风造成的损坏以每个城市部分或完全损坏（分别为 PD[Partly damaged (abs.)] 或 CD[Completely damaged (abs.)]）的房屋数量来衡量。这些指标也以每个城市房屋总数的百分比形式给出（分别为 pPD[Partly damaged (rel.)] 和 pCD[Completely damaged (rel.)]）。其他列对应于根据这两个基本测量计算出的不同指标。</li>
<li><strong>灾害指标</strong>：与台风事件相关的变量。
<ul>
<li>Wind speed -- 风速[公里/小时]</li>
<li>Distance to typhoon -- 到台风的距离[公里]：台风轨迹到城市质心的最短距离。</li>
<li>rainfall -- 降雨量 [毫米]</li>
<li>distance_first_impact -- 距首次影响的距离 [km]：台风登陆点到城市质心的距离。</li>
<li>Experience -- 经历[-]：本次台风之前，该市所属地区平均抵御台风的次数。</li>
</ul>
</li>
<li><strong>场地和暴露指标</strong>：与场地地形特征和市社会经济指标相关的变量。这些仅取决于市政府，而不取决于台风（假设它们在时间上相对恒定）。
<ul>
<li>ruggedness_stdev -- 崎岖度标准[-]：市内地形崎岖度的标准偏差。</li>
<li>Ruggedness -- 崎岖度 [-]：市内平均地形崎岖度。</li>
<li>Elevation -- 海拔 [m]：市内的平均海拔。</li>
<li>Slope -- 坡度[度]：市内的平均地形坡度。</li>
<li>slope_stdev -- 坡度标准[-]：市内地形坡度的标准偏差。</li>
<li>Population -- 人口数量</li>
<li>Population density -- 人口密度[居住区/平方公里]</li>
<li>land_area -- 土地面积</li>
<li>Poverty incidence -- 贫困发生率</li>
<li>% skilled Agriculture/Forestry/Fishermen -- 熟练农业/林业/渔民比例</li>
<li>% strong roof type -- 强屋面类型比例</li>
<li>% strong wall type -- 强墙型比例</li>
</ul>
</li>
</ul>
<h3>数据预览</h3>
<pre><code class="language-python"># 导入原始数据
data = pd.read_csv(r'data/All.csv')
# 查看台风名字及对应数量
data[['disaster_name']].value_counts()
disaster_name
Haima            301
Rammasun         294
Koppu            203
Bopha            175
Haiyan           162
Melor            105
Kalmaegi          92
Nock-Ten          82
Hagupit           81
Sarika            57
Utor              54
Goni              32
dtype: int64
# 输出摘要统计信息
data.describe()
       Completely damaged (abs.)  Partly damaged (abs.)  \
count                1638.000000            1638.000000
mean                  582.935897            1138.982295
std                  1553.413663            2370.653848
min                     1.000000               1.000000
25%                     1.000000              14.000000
50%                    16.000000             179.500000
75%                   269.500000            1411.500000
max                 14132.000000           46553.000000
       Total damaged houses (abs.)  total_damage_houses_0p25weight  \
count                  1638.000000                     1638.000000
mean                   1721.918193                      867.681471
std                    3496.164509                     1952.399073
min                       2.000000                        1.250000
25%                      19.000000                        7.000000
50%                     225.000000                       75.500000
75%                    1962.250000                      694.562500
max                   58823.000000                    23908.250000
       Partly damaged (rel.)  Completely damaged (rel.)  \
count            1638.000000                1638.000000
mean               11.860162                   6.103325
std                17.152123                  14.385213
min                 0.000972                   0.001168
25%                 0.197830                   0.025812
50%                 2.587918                   0.223214
75%                18.698752                   3.026831
max               115.343099                  95.607311
       Total damaged houses (rel.)  total_damage_houses_0p25weight_perc  \
count                  1638.000000                          1638.000000
mean                     17.963487                             9.068365
std                      26.756541                            16.703810
min                       0.002647                             0.001654
25%                       0.277203                             0.105430
50%                       3.259474                             1.104780
75%                      27.268523                             9.262609
max                     129.974141                            98.544514
       ratio_comp_part  Total # of houses   Wind speed  Distance to typhoon  \
count      1638.000000        1638.000000  1638.000000          1638.000000
mean          0.974340       11767.550218    84.682571            74.899818
std           3.676039       15013.119760    35.797212            70.071947
min           0.011246         324.250000    40.000000             0.122506
25%           0.242304        4700.749997    59.999527            24.399295
50%           0.579407        8017.625004    80.000000            50.303957
75%           0.972011       13664.437605   102.693927           104.957121
max          88.201339      194096.500200   298.464302           347.292212
          rainfall  distance_first_impact        Slope    Elevation  \
count  1638.000000            1638.000000  1638.000000  1638.000000
mean    323.920596             197.212283     8.186324   258.570181
std     155.502152             118.607868     5.716850   321.773277
min      45.000000               4.357767     0.456908     2.516287
25%     244.900000             110.800300     3.935659    59.706514
50%     303.507123             175.939736     7.164828   138.017489
75%     376.500000             263.415087    11.331911   305.599518
max    1964.000000            1223.383698    25.229471  1899.717311
       ruggedness_stdev   Ruggedness  slope_stdev  \
count       1638.000000  1638.000000  1638.000000
mean          28.602452    41.832893     6.011024
std           15.179823    28.395457     3.061597
min            1.629265     3.497199     0.286051
25%           18.188352    21.022102     3.935674
50%           29.283881    36.834113     6.375094
75%           39.950044    57.243654     8.481826
max           86.703939   128.965009    13.024484
       Predicted damage class (1-5)     Population    land_area  \
count                           0.0    1638.000000  1638.000000
mean                            NaN   47065.645910   215.933543
std                             NaN   60040.329748   226.523048
min                             NaN    1291.000000     1.856500
25%                             NaN   18807.000000    80.480600
50%                             NaN   32108.000000   146.901100
75%                             NaN   54658.500000   264.230700
max                             NaN  776382.000000  2428.147100
       Population density  Poverty incidence  % strong roof type  \
count         1638.000000        1638.000000         1638.000000
mean           452.178975           0.257932            0.834480
std           1250.825754           0.150841            0.173800
min              4.498900           0.008500            0.236160
25%            115.491400           0.136300            0.740387
50%            229.109300           0.224950            0.915456
75%            434.300650           0.358525            0.963024
max          34384.322200           0.847600            1.000000
       % strong wall type  % skilled Agriculture/Forestry/Fishermen  \
count         1638.000000                               1617.000000   # 该特征数据缺失
mean             0.589403                                  0.107656
std              0.206134                                  0.054270
min              0.053748                                  0.001049
25%              0.430316                                  0.068022
50%              0.590947                                  0.103011
75%              0.776601                                  0.138443
max              0.952283                                  0.340328
        Experience                   Bicol region
count  1637.000000 # 该特征数据丢失  1638.000000
mean      2.100000                     0.117216
std       0.870465                     0.321776
min       1.000000                     0.000000
25%       1.277778                     0.000000
50%       2.034483                     0.000000
75%       2.800000                     0.000000
max       4.280000                     1.000000
</code></pre>
<h3>数据清洗</h3>
<h4>（1）缺失值检验</h4>
<pre><code class="language-python"># 查看多少空值
data.isna().sum()
# 删除缺失值
data.dropna(inplace=True, subset=['% skilled Agriculture/Forestry/Fishermen', 'Experience'])
disaster_type                                  0
disaster_name                                  0
pcode                                          0
Completely damaged (abs.)                      0
Partly damaged (abs.)                          0
Total damaged houses (abs.)                    0
total_damage_houses_0p25weight                 0
Partly damaged (rel.)                          0
Completely damaged (rel.)                      0
Total damaged houses (rel.)                    0
total_damage_houses_0p25weight_perc            0
ratio_comp_part                                0
Total # of houses                              0
Wind speed                                     0
Distance to typhoon                            0
rainfall                                       0
distance_first_impact                          0
Slope                                          0
Elevation                                      0
ruggedness_stdev                               0
Ruggedness                                     0
slope_stdev                                    0
Predicted damage class (1-5)                1638  # 该属性不做处理因为后续不选择该属性作为特征
Population                                     0
land_area                                      0
Population density                             0
Poverty incidence                              0
% strong roof type                             0
% strong wall type                             0
% skilled Agriculture/Forestry/Fishermen      21
Region                                         0
prov                                           0
Experience                                     1
Bicol region                                   0
dtype: int64
</code></pre>
<h4>（2）选择特征</h4>
<p>根据数据探索分析，此处选择有用特征，剔除无用特征。</p>
<pre><code class="language-python"># 特征选择
data = data[['disaster_name', 'Total damaged houses (rel.)', 'Wind speed', 'Distance to typhoon', 'rainfall',
             'distance_first_impact', 'Experience',
             'ruggedness_stdev', 'Ruggedness', 'Elevation', 'Slope', 'slope_stdev', 'Population', 'Population density',
             'land_area', 'Poverty incidence', '% skilled Agriculture/Forestry/Fishermen',
             '% strong roof type', '% strong wall type']]
</code></pre>
<h4>（3）异常值检验</h4>
<p>没检查异常值检验前的数据概况：</p>
<pre><code class="language-python"># 有用特征
features = ['Total damaged houses (rel.)', 'Wind speed', 'Distance to typhoon', 'rainfall',
            'distance_first_impact', 'Experience', 'ruggedness_stdev', 'Ruggedness', 'Elevation',
            'Slope', 'slope_stdev', 'Population', 'Population density', 'land_area', 'Poverty incidence',
            '% skilled Agriculture/Forestry/Fishermen', '% strong roof type', '% strong wall type']
# 直方图
# 显示在同一张画布
def outliers_hist_all(num, df, cols=5, save=False, save_path=None, botton=None, left=None):
    plt.rcParams[&quot;font.sans-serif&quot;] = [&quot;SimHei&quot;]  # 设置字体
    plt.rcParams[&quot;axes.unicode_minus&quot;] = False  # 该语句解决图像中的“-”负号的乱码问题
    fig = plt.figure(figsize=(16, 16))
    fig.text(0.5, 0.04, botton, ha='center', fontsize=28)
    fig.text(0.04, 0.5, left, va='center', rotation='vertical', fontsize=18)
    rows = int(np.ceil(num / cols))
    for i in range(num):
        ax = fig.add_subplot(rows, cols, i + 1)
        ax.hist(df[df.columns[i]], bins=30)
        ax.set_title(df.columns[i])
    if save == True:
        plt.savefig(save_path)
    plt.show()
outliers_hist_all(len(features), data[features], botton='value', left='count')

# 箱线图检验
plt.figure(figsize=(8, 8))
data.boxplot(column=data[features].columns.tolist(), showmeans=True, meanline=True)
plt.xticks(rotation=90)  # 旋转x轴标签，以便更好地显示特征名称
plt.show()
</code></pre>
<p><img src="https://image.iyyh.net/%E5%88%9D%E5%A7%8B%E6%9F%B1%E7%8A%B6%E5%9B%BE.png" alt="初始柱状图"></p>
<p><img src="https://image.iyyh.net/%E5%88%9D%E5%A7%8B%E7%AE%B1%E7%BA%BF%E5%9B%BE.png" alt="初始箱线图"></p>
<p>检查并删除异常值。</p>
<pre><code class="language-python"># 计算每个特征的平均值和标准差
mean = data.iloc[:, 1:].mean()
std = data.iloc[:, 1:].std()
# 定义异常值的阈值（平均值加减3倍标准差）
threshold = 3 * std
# 检查并根据3σ准则删除异常值
data = data[~((data &lt; mean - threshold) | (data &gt; mean + threshold)).any(axis=1)]
</code></pre>
<p>检查异常值并检验后的数据概况：</p>
<p><img src="https://image.iyyh.net/%E5%89%94%E9%99%A4%E5%BC%82%E5%B8%B8%E5%80%BC%E5%90%8E%E6%9F%B1%E7%8A%B6%E5%9B%BE.png" alt="剔除异常值后柱状图"></p>
<p><img src="https://image.iyyh.net/%E5%89%94%E9%99%A4%E5%BC%82%E5%B8%B8%E5%80%BC%E5%90%8E%E7%AE%B1%E7%BA%BF%E5%9B%BE.png" alt="剔除异常值后箱线图"></p>
<p>可以看出，根据三西格玛剔除异常值后直方图的整体分布更加聚集，箱线图中的异常点也减少一定比例。</p>
<p>将目标值缩放到0-1区间中</p>
<pre><code class="language-python"># 将房屋损坏率转换为0-1
data['Total damaged houses (rel.)'] = data['Total damaged houses (rel.)'] / 100
</code></pre>
<h4>（4）相关性检验</h4>
<pre><code class="language-python">data_corr = data[features].corr()  # 相关系数矩阵
fig, ax = plt.subplots(figsize=(12, 12))
sns.heatmap(data_corr, annot=True, ax=ax)
plt.show()
data_corr['Total damaged houses (rel.)'].sort_values()
</code></pre>
<p><img src="https://image.iyyh.net/%E7%83%AD%E5%8A%9B%E5%9B%BE.png" alt="热力图"></p>
<pre><code class="language-plaintext">Distance to typhoon                        -0.435464
% strong wall type                         -0.304187
distance_first_impact                      -0.241009
Experience                                 -0.236378
% strong roof type                         -0.206935
Elevation                                  -0.162279
Population density                         -0.085511
Population                                 -0.065211
Slope                                      -0.057425
Ruggedness                                 -0.052857
land_area                                  -0.023486
slope_stdev                                 0.001225
ruggedness_stdev                            0.001823
% skilled Agriculture/Forestry/Fishermen    0.031725
rainfall                                    0.229307
Poverty incidence                           0.270775
Wind speed                                  0.722516
Total damaged houses (rel.)                 1.000000
Name: Total damaged houses (rel.), dtype: float64
</code></pre>
<h4>（5）多特征关系</h4>
<p><img src="https://image.iyyh.net/20251106144604650.png" alt="myplot"></p>
<p>将筛选出来的特征与预测变量进行展示特征之间关系，可见变量之间存在一定程度上的相关性。</p>
<h3><strong>数据准备</strong></h3>
<h4><strong>变量变换</strong></h4>
<p>使用Box-Cox变换来对潜在的损坏预测变量进行测试，并确定是否需要对变量进行幂律变换，以相对于链接变换的损坏比例标准化变量。</p>
<pre><code class="language-python"># 对预测变量使用逻辑回归转换 expit(x) = 1 / (1 + exp(-x))
link_fn_td = expit(data['Total damaged houses (rel.)'])

# 将每个特征的最大值 转换成离它最近的半整数
def power_est(bC):
    l_est = bC[bC == max(bC)].iloc[0]
    return round(l_est / 0.5) * 0.5

# 选择需要的特征
var_names = data.columns.tolist()
var_names = [var for var in var_names if
             var not in [&quot;disaster_type&quot;, &quot;disaster_name&quot;, &quot;pcode&quot;, &quot;Total damaged houses (rel.)&quot;, &quot;Region&quot;, &quot;prov&quot;]]

# 创建一个全为空的dataframe
power_df = pd.DataFrame(np.nan, index=[0], columns=var_names)

# 使用 Box-Cox 变换来测试每个潜在的损坏预测变量，以确定是否需要对变量进行幂律变换，以相对于链接变换的损坏比例标准化变量。
for i, var_i in enumerate(var_names):
    power_df.iloc[0, i] = power_est(boxcox(link_fn_td - np.min(link_fn_td) * 1.01 + 0.01, data[var_i]))

td_data = data.copy()
   Wind speed  Distance to typhoon  rainfall  distance_first_impact  \
0         0.0                  0.0       0.0                    0.0
   Experience  ruggedness_stdev  Ruggedness  Elevation  Slope  slope_stdev  \
0         0.0               0.0         0.0        0.0    0.0          0.0
   Population  Population density  land_area  Poverty incidence  \
0         0.0                 0.0        0.0               -1.0
   % skilled Agriculture/Forestry/Fishermen  % strong roof type  \
0                                      -1.5                -1.0
   % strong wall type
0                -1.0
</code></pre>
<p>应用获得的变换：</p>
<pre><code class="language-python"># 根据power_df中的值对原始数据进行了不同的转换操作，以使得数据符合特定的分布
for i, var_i in enumerate(var_names):
    if power_df.loc[0, var_i] == 0:
        # 通过对数转换(np.log)
        # 可以将数据转换为更接近正态分布的形式，因为对数转换可以压缩较大的值，拉伸较小的值，使数据更加对称和稳定。
        td_data[var_i] = np.log(td_data[var_i])
    else:
        # 通过幂律变换(td_data[var_i] ** power_df.loc[0, var_i])
        # 可以将数据转换为更接近幂律分布的形式，因为幂律变换可以改变数据的分布形状，使其符合幂律分布的特征。
        td_data[var_i] = td_data[var_i] ** power_df.loc[0, var_i]
</code></pre>
<h4><strong>数据缩放</strong></h4>
<p>将除了目标列的特征列标准化</p>
<pre><code class="language-python"># 标准化
cols_mean_td = td_data[var_names].mean()
cols_sd_td = td_data[var_names].std()
scaled_data_td = (td_data[var_names] - cols_mean_td) / cols_sd_td
td_data[var_names] = scaled_data_td
</code></pre>
<p>数据准备后的数据对其以直方图展示：</p>
<p><img src="https://image.iyyh.net/image-ycet.png" alt="直方图2"></p>
<p>可见，增提分布特征已经越来越明显。因此，可认为所做的数据变换是有效变换。</p>
<h4><strong>探索性数据分析</strong></h4>
<p>探索数据以确定预测变量与建筑物损坏比例之间可能的关系。</p>
<p>房屋受损比例：</p>
<pre><code class="language-python"># 选择有数值的列
numeric_data = td_data.select_dtypes(include='number')

# 数据重塑 将数据从宽格式（wide format）转换为长格式（long format）
melted_data = pd.melt(numeric_data, id_vars=['Total damaged houses (rel.)'],
                      var_name='var', value_name='value')
# 使用seaborn绘制散点图
plt.figure(figsize=(12, 8))
sns.scatterplot(data=melted_data, x='value', y='Total damaged houses (rel.)', hue='var')
plt.title('Scatter plot for each variable')
plt.xlabel('Value')
plt.ylabel('Total damaged houses (rel.)')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left')
plt.show()
features_sc = ['Wind speed', 'Distance to typhoon', 'rainfall',
               'distance_first_impact', 'Experience', 'ruggedness_stdev', 'Ruggedness', 'Elevation',
               'Slope', 'slope_stdev', 'Population', 'Population density', 'land_area', 'Poverty incidence',
               '% skilled Agriculture/Forestry/Fishermen', '% strong roof type', '% strong wall type']
# 散点图
# 创建一个包含所有特征对应的子图标题的列表
titles = [feature for feature in features_sc]
# 计算子图的行数和列数
num_features = len(features_sc)
rows = int(num_features / 4) + 1
cols = min(num_features, 4)
# 创建一个新的图形，并设置图形的大小
fig = plt.figure(figsize=(15, 15))
# 遍历每个特征，创建对应的子图
for i, feature in enumerate(features_sc):
    # 在图形中添加子图，并指定子图的位置
    ax = fig.add_subplot(rows, cols, i + 1)
    # 绘制散点图
    ax.scatter(td_data[feature], expit(td_data['Total damaged houses (rel.)']))
    # 设置子图标题
    ax.set_title(titles[i])
    # 设置x轴和y轴标签
    ax.set_xlabel(feature)
    ax.set_ylabel('Total damaged houses (rel.)')
# 调整子图之间的间距
fig.tight_layout()
# 显示图形
plt.show()
</code></pre>
<p><img src="https://image.iyyh.net/image-drtu.png" alt="scatter"></p>
<p><img src="https://image.iyyh.net/image-ccsm.png" alt="散点图2"></p>
<p>以散点图，可以看出，在一定程度上，经过我们的数据变换使得数据更加集中，这样使得原始数据将会更加有意义。</p>
<p>对于这个变换而言，风速根据其大小可以看到独特的行为。虽然对于较低的风速，可以观察到不少分散且显着的正斜率，但对于较高的风速（例如高于平均水平），这种损害的增量似乎饱和。</p>
<p>其他变量（例如海拔和降雨量）也存在类似的趋势，但由于风速是主要预测变量，因此分析仅限于此。</p>
<h4><strong>数据集</strong></h4>
<p>损坏房屋的比例：</p>
<pre><code class="language-python"># 处理过后的数据集展示
td_data.sample(5)
     disaster_name  Total damaged houses (rel.)  Wind speed  \
279        Hagupit                     0.043671   -1.619854
1610          Utor                     0.166409    0.871446
107          Bopha                     0.027567    0.202984
625         Haiyan                     0.777924    2.111691
1455      Rammasun                     0.117990   -0.640615
      Distance to typhoon  rainfall  distance_first_impact  Experience  \
279              1.369567 -3.911680               0.510022   -1.149703
1610            -0.655048  1.501795              -1.785016    1.055731
107              0.167086  1.160104              -1.089411   -1.545198
625             -2.225993  0.266232               0.776345   -1.092881
1455             0.470196 -0.169615              -0.988571    0.460752
      ruggedness_stdev  Ruggedness  Elevation     Slope  slope_stdev  \
279           0.412075    0.237446  -0.849878  0.107418     0.264466
1610          0.554183    0.460424   0.871855  0.487643     0.587852
107           0.947218    1.091489   1.514961  1.032755     0.884493
625          -0.100165   -0.369386  -0.775195 -0.345895    -0.073127
1455         -0.072546    0.203466  -0.599278  0.213241     0.015068
      Population  Population density  land_area  Poverty incidence  \
279    -2.246590           -0.959423  -0.947639          -0.780200
1610   -0.141595           -0.978254   1.002742          -0.028983
107     1.307730           -0.582448   1.872402          -0.688154
625     0.315079            0.381172  -0.152591          -0.440168
1455   -1.148631            0.322721  -1.425962          -0.815481
      % skilled Agriculture/Forestry/Fishermen  % strong roof type  \
279                                  -0.315185            1.120590
1610                                 -0.290428           -0.550206
107                                  -0.078037            0.167487
625                                  -0.196568           -0.581216
1455                                 -0.317290            2.392163
      % strong wall type
279             1.268849
1610           -0.326936
107             0.723035
625             0.085402
1455            0.139717
</code></pre>
<h4><strong>检查多重共线性</strong></h4>
<p>使用广义线性模型（Generalized Linear Model）来拟合一个多分类的逻辑回归模型，以预测数据集中的'Total damaged houses (rel.)'列的值。</p>
<p>同时检查多重共线性，通过计算方差膨胀因子（VIF）来判断是否存在共线性问题，并在存在共线性问题时（VIF&gt;10 ）进行变量的逐步剔除。</p>
<pre><code class="language-python"># 使用Generalized Linear Model（广义线性模型）来拟合一个多分类的逻辑回归模型，
# 以预测'td_data'中的'Total damaged houses (rel.)'列的值。
td_full = sm.GLM(td_data['Total damaged houses (rel.)'], td_data[var_names], family=Binomial(link=logit())).fit()
td_data.shape
# 检查多重共线性
temp_model = td_full
temp_vif = [variance_inflation_factor(td_data[var_names].values, i) for i in range(len(var_names))]
temp_var = [&quot;dummy&quot;]
temp_data = td_data.copy()

while max(temp_vif) &gt; 10:
    var_remove = temp_data.columns[2:][temp_vif.index(max(temp_vif))]
    temp_var.append(var_remove)
    temp_data = temp_data.drop(columns=[var_remove])
    temp_model = sm.GLM(temp_data['Total damaged houses (rel.)'], temp_data[temp_data.columns[2:]],
                        family=Binomial(link=logit())).fit()
    temp_vif = [variance_inflation_factor(temp_data[temp_data.columns[2:]].values, i) for i in
                range(len(temp_data.columns[2:]))]

temp_vif_with_names = list(zip(temp_data.columns[2:], temp_vif))
pd_temp_vif_with_names = pd.DataFrame(temp_vif_with_names)
pd_temp_vif_with_names.columns = ['Features', 'VIF']
pd_temp_vif_with_names
                                    Features       VIF
0                                 Wind speed  4.024396
1                        Distance to typhoon  3.210826
2                                   rainfall  1.316407
3                      distance_first_impact  1.466195
4                                 Experience  1.509735
5                                  Elevation  3.483213
6                                slope_stdev  3.030725
7                                 Population  1.889770
8                                  land_area  2.336313
9                          Poverty incidence  1.739308
10  % skilled Agriculture/Forestry/Fishermen  1.291850
11                        % strong roof type  1.403770
12                        % strong wall type  1.482686
temp_var
['dummy', 'Population density', 'Slope', 'ruggedness_stdev', 'Ruggedness']
# 更新特征
td_col_to_use = temp_data.columns
td_data = td_data[td_data.columns.intersection(td_col_to_use)]
</code></pre>
<h4>BorutaShap特征选择</h4>
<pre><code class="language-python">X = td_data[['Wind speed', 'Distance to typhoon', 'rainfall', 'distance_first_impact',
             'Experience', 'Elevation', 'slope_stdev', 'Population', 'land_area',
             'Poverty incidence', '% skilled Agriculture/Forestry/Fishermen',
             '% strong roof type', '% strong wall type']]

y = td_data['Total damaged houses (rel.)']
Feature_Selector = BorutaShap(importance_measure='shap', classification=False)
Feature_Selector.fit(X=X, y=y, n_trials=100, random_state=0)
# 采用shap算法，经过100轮计算后得到的各个特征信息如下：
# 9 attributes confirmed important: ['Experience', 'distance_first_impact', 'Wind speed', 'Poverty incidence', 'Elevation', 'Population', '% strong roof type', 'Distance to typhoon', '% strong wall type']
# 3 attributes confirmed unimportant: ['rainfall', 'land_area', 'slope_stdev']
# 1 tentative attributes remains: ['% skilled Agriculture/Forestry/Fishermen']
</code></pre>
<p>数据预处理 最终数据集描述信息：</p>
<pre><code class="language-plaintext">td_data.describe()
       Total damaged houses (rel.)    Wind speed  Distance to typhoon  \
count                  1405.000000  1.405000e+03         1.405000e+03
mean                      0.180416  1.011449e-16        -2.124042e-16
std                       0.258533  1.000000e+00         1.000000e+00
min                       0.000047 -1.619854e+00        -4.906482e+00
25%                       0.003059 -6.406151e-01        -4.960408e-01
50%                       0.034921  5.416582e-02         1.040757e-01
75%                       0.285269  6.854903e-01         7.271722e-01
max                       0.951642  2.143221e+00         1.557193e+00
           rainfall  distance_first_impact    Experience     Elevation  \
count  1.405000e+03           1.405000e+03  1.405000e+03  1.405000e+03
mean   7.333003e-16          -5.714685e-16  8.091590e-17  2.022897e-17
std    1.000000e+00           1.000000e+00  1.000000e+00  1.000000e+00
min   -4.277711e+00          -5.104474e+00 -1.545198e+00 -3.294853e+00
25%   -4.636419e-01          -5.679346e-01 -9.648785e-01 -6.177726e-01
50%    9.712316e-02           1.653390e-01  1.362759e-01  6.635912e-02
75%    6.366046e-01           7.170544e-01  8.923924e-01  7.161769e-01
max    2.501303e+00           1.766611e+00  1.896988e+00  1.972304e+00
        slope_stdev    Population     land_area  Poverty incidence  \
count  1.405000e+03  1.405000e+03  1.405000e+03       1.405000e+03
mean  -8.597314e-17 -5.664113e-16 -1.062021e-16      -4.045795e-17
std    1.000000e+00  1.000000e+00  1.000000e+00       1.000000e+00
min   -3.116919e+00 -4.054597e+00 -3.458290e+00      -1.001795e+00
25%   -1.697487e-01 -6.073934e-01 -6.682982e-01      -6.623434e-01
50%    3.434245e-01  4.849719e-02  2.027343e-03      -2.661507e-01
75%    6.702839e-01  6.905744e-01  6.590482e-01       3.871621e-01
max    1.184968e+00  2.551172e+00  2.195896e+00       9.986928e+00
       % skilled Agriculture/Forestry/Fishermen  % strong roof type  \
count                               1405.000000        1.405000e+03
mean                                   0.000000        3.843505e-16
std                                    1.000000        1.000000e+00
min                                   -0.365098       -7.386823e-01
25%                                   -0.263353       -6.261493e-01
50%                                   -0.187080       -4.621668e-01
75%                                    0.004608        2.504821e-01
max                                   29.045222        5.186857e+00
       % strong wall type
count        1.405000e+03
mean         8.091590e-17
std          1.000000e+00
min         -7.760501e-01
25%         -5.753445e-01
50%         -2.728524e-01
75%          1.895579e-01
max          1.396548e+01
</code></pre>
<p>筛选过特征后的数据直方图：</p>
<p><img src="https://image.iyyh.net/image-lcul.png" alt="直方图"></p>
]]></content:encoded>
            <author>yyhhyyyyyy8@gmail.com (yyhhyyyyyy)</author>
        </item>
    </channel>
</rss>