<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss/feed.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Nanamiの电波发射塔</title><description>人間になりたい!!!!!</description><link>https://blog.nanami.tech</link><language>en</language><item><title>校园网 VLAN 接入 AP 与自动认证</title><link>https://blog.nanami.tech/en/archives/405</link><guid isPermaLink="false">en:405</guid><description>前言
博主的学校宿舍楼在大一的暑假进行了一次翻修, 开学回来后虽然设施是翻新了, 但是居然把墙上的网络面板给弄坏了! 这让博主这种十分依赖有线低延迟和链路聚合的用户十分气愤. 学校的 AP 不仅性能弱, 延迟高. 且每次连接都需要重新在 Captive Protocol 中进行认证, 十分不方便.</description><pubDate>Fri, 09 Oct 2026 07:16:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主的学校宿舍楼在大一的暑假进行了一次翻修, 开学回来后虽然设施是翻新了, 但是居然把墙上的网络面板给弄坏了! 这让博主这种十分依赖有线低延迟和链路聚合的用户十分气愤. 学校的 AP 不仅性能弱, 延迟高. 且每次连接都需要重新在 Captive Protocol 中进行认证, 十分不方便. 一开始得到的回复是十月中旬之前会全部弄好, 但现在已经将近十月中旬了, 也没见有人来施工. 在思考的过程中, 博主将目标转向了每个寝室都会安装的 AP, 思考能不能在这块做些什么. 于是乎就有了今天这篇文章.&lt;/p&gt;
&lt;h2&gt;环境介绍与研究目标&lt;a href=&quot;#环境介绍与研究目标&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;AP 是通过每层楼的 PoE 汇聚交换机接入的, 每个寝室都有. 正常的连接方式是下游 STA 设备通过 WiFi 接入, 然后登录学校的 Captive Protocol 进行认证上网. 博主这里打算将接入 AP 的这条网线接入自己的 OpenWrt 路由器, 实现有线上网.&lt;/p&gt;
&lt;h2&gt;观前须知&lt;a href=&quot;#观前须知&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;注意: 本文为纯整活向文章, 这种上网方式既不合适也不推荐. 不单单是因为麻烦, 还有可能会因为私自修改学校网络设备被校方追责. 看个乐呵就行, 不要照做! 如不听劝, 那后果自负!&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 探明网络架构&lt;a href=&quot;#1-探明网络架构&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;将网线直接接入路由器, 发现 DHCP 能拿到地址
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/405-1.png&quot; alt=&quot;路由器接入 AP 网线后通过 DHCP 获取地址&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;路由器接入 AP 网线后通过 DHCP 获取地址&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;3:&lt;/span&gt;&lt;span&gt; eth1:&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;BROADCAST,MULTICAST,UP,LOWER_U&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mtu&lt;/span&gt;&lt;span&gt; 1492&lt;/span&gt;&lt;span&gt; qdisc&lt;/span&gt;&lt;span&gt; fq_codel&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt; UP&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; qlen&lt;/span&gt;&lt;span&gt; 1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    link/ether&lt;/span&gt;&lt;span&gt; 00:e0:4c:d0:1f:f7&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; ff:ff:ff:ff:ff:ff&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet&lt;/span&gt;&lt;span&gt; 172.17.255.165/18&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; 172.17.255.255&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt; eth1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet6&lt;/span&gt;&lt;span&gt; fe80::2e0:4cff:fed0:1ff7/64&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel_ll&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;正常来说下游 STA 访问外部网站会被直接 302 到门户网站, 这里博主在电脑上尝试后发现并不能. 这里博主使用了一台手机连接学校的 WiFi, 拿到了门户网站的地址, 随后在路由器侧测试 DNS. 发现 DNS 是能通的.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; nslookup&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;.edu.cn&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Server:&lt;/span&gt;&lt;span&gt;         127.0.0.1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address:&lt;/span&gt;&lt;span&gt;        127.0.0.1:53&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Non-authoritative&lt;/span&gt;&lt;span&gt; answer:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Name:&lt;/span&gt;&lt;span&gt;   *&lt;/span&gt;&lt;span&gt;.edu.cn&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address:&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Non-authoritative&lt;/span&gt;&lt;span&gt; answer:&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;尝试直接 ping 门户网站服务器, 发现无法通信&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; (211.*.*.*): 56 data bytes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 100%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. 分析路由策略&lt;a href=&quot;#2-分析路由策略&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;观察后发现, 路由器侧拿到的 DHCP 地址为 &lt;code&gt;172.0.0.0/8&lt;/code&gt; 段, 但是 STA 侧如果连接 WiFi, 拿到的地址就是 &lt;code&gt;10.0.0.0/8&lt;/code&gt; 段, 这与路由器拿到的地址不一致. STA 使用这个地址段的 IP 可以直接访问到门户网站, 而路由器却不行. 因此可以推测: &lt;strong&gt;下游设备到门户服务器中的路由有防火墙, 且可能仅对 &lt;code&gt;10.0.0.0/8&lt;/code&gt; 地址段开放.&lt;/strong&gt;
既然 STA 连接 WiFi 能拿到 &lt;code&gt;10.0.0.0/8&lt;/code&gt; 的地址, 那么路由器肯定也是能通过某些方法拿到这段地址的. 这里最有可能的方式便是 &lt;code&gt;VLAN&lt;/code&gt;.
使用 Wireshark 对路由器进行抓包, 发现三条 VLAN. 分析后发现其对应的网段如下&lt;/p&gt;





















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;VLAN ID&lt;/th&gt;&lt;th&gt;Network&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;602&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.130.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;604&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.140.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;606&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.150.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;使用 STA 连接 AP 发射的三条 WLAN, 发现网段与 ISP 的对应关系如下&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;VLAN ID&lt;/th&gt;&lt;th&gt;Network&lt;/th&gt;&lt;th&gt;ISP&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;602&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.130.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;td&gt;CTNET&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;604&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.140.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;td&gt;CMCC&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;606&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.150.0.0/16&lt;/code&gt;&lt;/td&gt;&lt;td&gt;CUNIQ&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;知道了这些信息, 我们就可以着手开始在路由器侧进行配置了.&lt;/p&gt;
&lt;h3&gt;3. 接口配置&lt;a href=&quot;#3-接口配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;打开 LuCi WebUI, 转到 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Interfaces&lt;/code&gt; -&amp;gt; &lt;code&gt;Devices&lt;/code&gt;, 点击 &lt;code&gt;Add device configuration...&lt;/code&gt; 添加接口配置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Device type&lt;/code&gt; 选择 &lt;code&gt;VLAN (802.1q)&lt;/code&gt;, 填入对应 VLAN ID 和接口名称.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 这里有多少个用户就需要创建多少个 VLAN 端口, 否则因为接口参数不变, 不管创建多少个 DHCP 拿到的永远都是同一个地址.
&lt;strong&gt;如果需要在一个接口上创建多个 VlanIf, 则需要将第 &amp;gt;=2 个 VlanIf 接口的 MAC 地址做更改. 值与接口本身不同即可.&lt;/strong&gt;
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/405-2.png&quot; alt=&quot;创建 VLAN 802.1q 设备并填写 VLAN ID&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;创建 VLAN 802.1q 设备并填写 VLAN ID&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;接口全部创建完成后单击保存并应用.
&lt;figure&gt;&lt;img src=&quot;/images/405-3.png&quot; alt=&quot;全部配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;全部配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;转到 &lt;code&gt;Interfaces&lt;/code&gt; 选项卡, 点击 &lt;code&gt;Add new interface...&lt;/code&gt; 添加新接口&lt;/li&gt;
&lt;li&gt;协议选择 &lt;code&gt;DHCP Client&lt;/code&gt;, 名称按需填写, 接口则选择刚刚创建的 VlanIf 接口&lt;/li&gt;
&lt;li&gt;转到 &lt;code&gt;Advanced Settings&lt;/code&gt;, &lt;strong&gt;将 &lt;code&gt;Use default gateway&lt;/code&gt; 取消勾选&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意: 这一步非常重要, 如果不取消勾选, 系统将会在路由表内自动创建一条到达该接口网关的默认路由. 这个操作会影响当前路由器的正常上网!&lt;/strong&gt;
出于隐私考虑, 也推荐将 &lt;code&gt;General Settings&lt;/code&gt; 中的 &lt;code&gt;Hostname to send when requesting DHCP&lt;/code&gt; 选项改为 &lt;code&gt;Do not send a hostname&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;全部创建完成后, 单击保存并应用. 如果全部可以正常获取地址, 则该部分配置完成.
&lt;figure&gt;&lt;img src=&quot;/images/405-4.png&quot; alt=&quot;创建 DHCP Client 接口并取消默认网关&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;创建 DHCP Client 接口并取消默认网关&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 在某些 aarch64 机型上, SoC 可能会限制&lt;strong&gt;同一个 VID 只能创建一个 VlanIf 设备.&lt;/strong&gt; 如果您使用 VlanIf 创建 DHCP Client 时, 出现报错 &lt;code&gt;DEVICE_CLAIM_FAILED&lt;/code&gt;, 则可能是这个原因. 这种情况下最合适的做法是: &lt;strong&gt;基于该接口创建一个 VlanIf 接口, 然后多用户使用 Mac VLAN 接入.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4. 尝试登录网络&lt;a href=&quot;#4-尝试登录网络&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;在之前的分析中, 我们获得了 Captive Protocol 认证门户的 IP 地址, 所以我们这里随便找一个 MAC VlanIf 接口作为出口, 写一条到认证门户的路由即可测试.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ip&lt;/span&gt;&lt;span&gt; r&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;/32&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.150.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; lan1.cuniq-&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;路由写进去后使用下游设备登录门户网站
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/405-5.png&quot; alt=&quot;校园网 Captive Portal 登录页面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;校园网 Captive Portal 登录页面&lt;/figcaption&gt;&lt;/figure&gt;
发现成功登录. 输入正确的校园网账号密码后可以正常登录.
&lt;figure&gt;&lt;img src=&quot;/images/405-6.png&quot; alt=&quot;校园网认证成功页面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;校园网认证成功页面&lt;/figcaption&gt;&lt;/figure&gt;
至此, Captive Protocol 门户的验证也完成了.&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;5. 持久化&lt;a href=&quot;#5-持久化&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;注销刚刚登录的校园网账号, 打开 BurpSuit 进行抓包. 分析后发现登录过程如下:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;获取客户端 IP — 从门户页面的 CONFIG 嵌入信息中提取 ip 字&lt;/li&gt;
&lt;li&gt;获取 &lt;code&gt;Challenge Token&lt;/code&gt; — GET &lt;code&gt;/cgi-bin/get_challenge?username=&amp;lt;账号@域名&amp;gt;&amp;amp;ip=&amp;lt;IP&amp;gt;&amp;amp;callback=cb&lt;/code&gt;, 返回 64 字节 hex token (有效期 60 秒)&lt;/li&gt;
&lt;li&gt;HMAC-MD5 — hmd5 = HMAC-MD5 (key=密码, msg=token), 逆向自 all.min.js 中 md5 v2.10.0 库的 &lt;code&gt;A(n,t,r)&lt;/code&gt; 函数, 双参数时实际调用的是 HMAC&lt;/li&gt;
&lt;li&gt;用户信息加密 — 将 &lt;code&gt;&lt;/code&gt; 的 JSON 用 &lt;code&gt;XXTEA (delta=0x9E3779B9)&lt;/code&gt; 以 token 为密钥加密, 再用自定义 Base64 字母表 &lt;code&gt;LVoJPiCN2R8G90yg+hmFHuacZ1OWMnrsSTXkYpUq/3dlbfKwv6xztjI7DeBE45QA&lt;/code&gt; 编码, 前缀 &lt;code&gt;{SRBX1}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;校验和 + 登录 — chksum = &lt;code&gt;SHA1(token+username + token+hmd5 + token+acid + token+ip + token+n + token+type + token+info)&lt;/code&gt;, 然后 GET &lt;code&gt;/cgi-bin/srun_portal&lt;/code&gt; 发起 JSONP 登录&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;根据逆向结果, 我们可以写一份登录脚本&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;USERNAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PASSWORD&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;DOMAIN&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;INTERFACE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;GATEWAY&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;CPURL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Set IP route to captive protocol server&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ip&lt;/span&gt;&lt;span&gt; route&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; $GATEWAY &lt;/span&gt;&lt;span&gt;dev&lt;/span&gt;&lt;span&gt; $INTERFACE&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;Route added, sleep 5s...&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sleep&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;set&lt;/span&gt;&lt;span&gt; -euo&lt;/span&gt;&lt;span&gt; pipefail&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Get AC_ID from captive protocol url&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AUTH_HOST&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span&gt; &apos;%s\n&apos; &quot;&lt;/span&gt;&lt;span&gt;$CPURL&lt;/span&gt;&lt;span&gt;&quot; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; sed&lt;/span&gt;&lt;span&gt; -nE &apos;s#^https?://([^/]+)/.*#\1#p&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ACID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;printf&lt;/span&gt;&lt;span&gt; &apos;%s\n&apos; &quot;&lt;/span&gt;&lt;span&gt;$CPURL&lt;/span&gt;&lt;span&gt;&quot; &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; sed&lt;/span&gt;&lt;span&gt; -nE &apos;s/.*ac_id=([0-9]+).*/\1/p&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt; -z&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$ACID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; ACID&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;1&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;=== Srun Portal Login ===&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;Captive Protocol Server: &lt;/span&gt;&lt;span&gt;$AUTH_HOST&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;ac_id:      &lt;/span&gt;&lt;span&gt;$ACID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;Username:     &lt;/span&gt;&lt;span&gt;${USERNAME}${DOMAIN}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;python3&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$AUTH_HOST&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$ACID&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$USERNAME&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$PASSWORD&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$DOMAIN&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; &apos;PYTHON_SCRIPT&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import sys, json, hmac, hashlib, base64, re, urllib.request, urllib.parse, time&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auth_host, ac_id, username_raw, password, domain = sys.argv[1:6]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;username = username_raw + domain&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;base_url = f&quot;http://{auth_host}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- HTTP GET with retry ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def http_get(url, timeout=15, retries=5):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    last_err = None&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for attempt in range(1, retries + 1):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        try:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            req = urllib.request.Request(url, headers={&apos;User-Agent&apos;: &apos;Mozilla/5.0&apos;})&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            with urllib.request.urlopen(req, timeout=timeout) as resp:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                return resp.read().decode(&apos;utf-8&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        except Exception as e:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            last_err = e&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            wait = attempt * 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print(f&quot;  [retry {attempt}/{retries}] {e} — waiting {wait}s...&quot;, file=sys.stderr)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            time.sleep(wait)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    raise last_err&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def parse_jsonp(body):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    m = re.search(r&apos;\((\{.*\})\)&apos;, body, re.S)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return json.loads(m.group(1)) if m else json.loads(body)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- XXTEA Enc ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def xxtea_encrypt(text, key):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if text == &apos;&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return &apos;&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    def str_to_ints(s, append_len):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        c = len(s)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v = []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for i in range(0, c, 4):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            n = (ord(s[i]) if i &amp;lt; c else 0)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            n |= (ord(s[i+1]) if i+1 &amp;lt; c else 0) &amp;lt;&amp;lt; 8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            n |= (ord(s[i+2]) if i+2 &amp;lt; c else 0) &amp;lt;&amp;lt; 16&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            n |= (ord(s[i+3]) if i+3 &amp;lt; c else 0) &amp;lt;&amp;lt; 24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v.append(n &amp;amp; 0xFFFFFFFF)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if append_len:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v.append(c)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return v&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    def ints_to_str(v):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        chars = []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for val in v:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            chars.append(chr(val &amp;amp; 0xff))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            chars.append(chr((val &amp;gt;&amp;gt; 8) &amp;amp; 0xff))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            chars.append(chr((val &amp;gt;&amp;gt; 16) &amp;amp; 0xff))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            chars.append(chr((val &amp;gt;&amp;gt; 24) &amp;amp; 0xff))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return &apos;&apos;.join(chars)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v = str_to_ints(text, True)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    k = str_to_ints(key, False)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if len(k) &amp;lt; 4:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        k.extend([0] * (4 - len(k)))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    n = len(v) - 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    z, y = v[n], v[0]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    DELTA = 0x9E3779B9&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    M = 0xFFFFFFFF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    q = 6 + 52 // (n + 1)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    d = 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    while q &amp;gt; 0:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        d = (d + DELTA) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        e = (d &amp;gt;&amp;gt; 2) &amp;amp; 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        for p in range(n):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            y = v[p + 1]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            m = ((z &amp;gt;&amp;gt; 5) ^ (y &amp;lt;&amp;lt; 2)) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            m = (m + (((y &amp;gt;&amp;gt; 3) ^ ((z &amp;lt;&amp;lt; 4) &amp;amp; M)) ^ (d ^ y))) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            m = (m + (k[(p &amp;amp; 3) ^ e] ^ z)) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            z = v[p] = (v[p] + m) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        p = n&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        y = v[0]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        m = ((z &amp;gt;&amp;gt; 5) ^ (y &amp;lt;&amp;lt; 2)) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        m = (m + (((y &amp;gt;&amp;gt; 3) ^ ((z &amp;lt;&amp;lt; 4) &amp;amp; M)) ^ (d ^ y))) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        m = (m + (k[(p &amp;amp; 3) ^ e] ^ z)) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        z = v[n] = (v[n] + m) &amp;amp; M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        q -= 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return ints_to_str(v)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Custom Base64 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;CUSTOM = &apos;LVoJPiCN2R8G90yg+hmFHuacZ1OWMnrsSTXkYpUq/3dlbfKwv6xztjI7DeBE45QA&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;STD    = &apos;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def custom_b64(data_bytes):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    std_b64 = base64.b64encode(data_bytes).decode(&apos;ascii&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return std_b64.translate(str.maketrans(STD, CUSTOM))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 0: Get Client IP ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;try:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    page = http_get(f&quot;{base_url}/srun_portal_pc?ac_id={ac_id}&amp;amp;theme=pro&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    m = re.search(r&apos;ip\s*:\s*&quot;([^&quot;]+)&quot;&apos;, page)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    client_ip = m.group(1) if m else &apos;&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;except Exception as e:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;[!] Failed to get client IP: {e}&quot;, file=sys.stderr)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys.exit(1)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if not client_ip:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(&quot;[!] Could not parse client IP from portal page&quot;, file=sys.stderr)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys.exit(1)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;print(f&quot;Client IP: {client_ip}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 1: Get Challenge Token ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cb = f&quot;srun{int(time.time()*1000)}&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;params = urllib.parse.urlencode({&apos;username&apos;: username, &apos;ip&apos;: client_ip, &apos;callback&apos;: cb})&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;resp = parse_jsonp(http_get(f&quot;{base_url}/cgi-bin/get_challenge?{params}&quot;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if resp.get(&apos;error&apos;) != &apos;ok&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;[!] Failed to get challenge token: {resp}&quot;, file=sys.stderr)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys.exit(1)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;token = resp[&apos;challenge&apos;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;print(f&quot;Token:       {token[:16]}...&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 2: HMAC-MD5(key=password, msg=token) ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;hmd5 = hmac.new(password.encode(&apos;utf-8&apos;), token.encode(&apos;utf-8&apos;), hashlib.md5).hexdigest()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 3: Encrypted user info (XXTEA + Custom Base64) ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;info_json = json.dumps({&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;username&apos;: username,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;password&apos;: password,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;ip&apos;: client_ip,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;acid&apos;: ac_id,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;enc_ver&apos;: &apos;srun_bx1&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}, separators=(&apos;,&apos;, &apos;:&apos;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;encrypted = xxtea_encrypt(info_json, token).encode(&apos;latin-1&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;info = &apos;{SRBX1}&apos; + custom_b64(encrypted)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 4: Calculate chksum = SHA1(token + ...) ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;n_val, type_val = 200, 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chk = (token + username + token + hmd5 + token + ac_id +&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       token + client_ip + token + str(n_val) +&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       token + str(type_val) + token + info)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chksum = hashlib.sha1(chk.encode(&apos;utf-8&apos;)).hexdigest()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- Step 5: Post Login Request ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;login_params = urllib.parse.urlencode({&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;action&apos;: &apos;login&apos;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;username&apos;: username,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;password&apos;: &apos;{MD5}&apos; + hmd5,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;os&apos;: &apos;Linux&apos;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;name&apos;: &apos;Linux&apos;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;double_stack&apos;: &apos;0&apos;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;chksum&apos;: chksum,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;info&apos;: info,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;ac_id&apos;: ac_id,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;ip&apos;: client_ip,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;n&apos;: str(n_val),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;type&apos;: str(type_val),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;callback&apos;: cb&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;})&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;result = parse_jsonp(http_get(f&quot;{base_url}/cgi-bin/srun_portal?{login_params}&quot;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;err = result.get(&apos;error&apos;, &apos;&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;suc = result.get(&apos;suc_msg&apos;, &apos;&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if err == &apos;ok&apos; and suc == &apos;login_ok&apos;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;\n[OK] Login successfully!&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;  User: {result.get(&apos;username&apos;, username)}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;  IP:   {result.get(&apos;client_ip&apos;, client_ip)}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    msg = result.get(&apos;ploy_msg&apos;, &apos;&apos;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if msg:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print(f&quot;  Message: {msg}&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;elif err == &apos;ok&apos; and &apos;already_online&apos; in suc:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;\n[OK] This IP is already online&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;elif &apos;already_online&apos; in err:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;\n[OK] This IP is already online&quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;else:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print(f&quot;\n[FAIL] Failed to login: {result.get(&apos;error_msg&apos;, err)}&quot;, file=sys.stderr)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys.exit(1)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PYTHON_SCRIPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Remove IP route&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ip&lt;/span&gt;&lt;span&gt; route&lt;/span&gt;&lt;span&gt; del&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; $GATEWAY &lt;/span&gt;&lt;span&gt;dev&lt;/span&gt;&lt;span&gt; $INTERFACE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;填写好参数后执行脚本&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Route&lt;/span&gt;&lt;span&gt; added,&lt;/span&gt;&lt;span&gt; sleep&lt;/span&gt;&lt;span&gt; 5s...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; Srun&lt;/span&gt;&lt;span&gt; Portal&lt;/span&gt;&lt;span&gt; Login&lt;/span&gt;&lt;span&gt; ===&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Captive&lt;/span&gt;&lt;span&gt; Protocol&lt;/span&gt;&lt;span&gt; Server:&lt;/span&gt;&lt;span&gt; 211.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ac_id:&lt;/span&gt;&lt;span&gt;      2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Username:&lt;/span&gt;&lt;span&gt;     ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Client&lt;/span&gt;&lt;span&gt; IP:&lt;/span&gt;&lt;span&gt; 10.150.196.77&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Token:&lt;/span&gt;&lt;span&gt;       ***&lt;/span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;OK&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Login successfully&lt;/span&gt;&lt;span&gt;!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  User:&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  IP:&lt;/span&gt;&lt;span&gt;   10.150.196.77&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Message:&lt;/span&gt;&lt;span&gt; E0000:&lt;/span&gt;&lt;span&gt; Login&lt;/span&gt;&lt;span&gt; is&lt;/span&gt;&lt;span&gt; successful.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 已经登录成功了.
接下来只需要写一份 init.d 脚本, 让 initd 在每次启动时执行一遍脚本登录就可以了. 这份脚本可以复制多份, 以对应不同的用户登录.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你的学校用的也是 SRun (深渊) 软件, 或许这份脚本也可以帮到你.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;创建 initd 脚本&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/init.d/srun_login&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; +x&lt;/span&gt;&lt;span&gt; /etc/init.d/srun_login&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;将以下内容填入脚本&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/bin/sh /etc/rc.common&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;USE_PROCD&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;START&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;95&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;STOP&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;15&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;start_service&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_open_instance&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_set_param&lt;/span&gt;&lt;span&gt; command&lt;/span&gt;&lt;span&gt; /root/srun_login/srun_login.sh&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_set_param&lt;/span&gt;&lt;span&gt; respawn&lt;/span&gt;&lt;span&gt; ${respawn_threshold&lt;/span&gt;&lt;span&gt;:-&lt;/span&gt;&lt;span&gt;3600} ${respawn_timeout&lt;/span&gt;&lt;span&gt;:-&lt;/span&gt;&lt;span&gt;5} ${respawn_retry&lt;/span&gt;&lt;span&gt;:-&lt;/span&gt;&lt;span&gt;5}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_set_param&lt;/span&gt;&lt;span&gt; stdout&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_set_param&lt;/span&gt;&lt;span&gt; stderr&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    procd_close_instance&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;stop_service&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;启用开机启动并启动脚本&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/etc/init.d/srun_login&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/etc/init.d/srun_login&lt;/span&gt;&lt;span&gt; start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;6. 链路聚合&lt;a href=&quot;#6-链路聚合&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;博主之前已经写过一篇利用 &lt;code&gt;mwan3&lt;/code&gt; 做链路聚合的文章. 具体可以查看 &lt;a href=&quot;https://blog.nanami.tech/archives/52/&quot;&gt;这里&lt;/a&gt;. 本篇文章就不再赘述.&lt;/p&gt;
&lt;p&gt;至此, 所有配置均已完成.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;a href=&quot;#总结&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业人士, 如有错误或疏漏请指出. 感谢阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/98/&quot;&gt;单网口校园网多线路载波聚合&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/331/&quot;&gt;OSPFv3 + WireGuard 借用 IPv6 出口&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/344/&quot;&gt;FakeMesh + 802.11kvr 全屋 WiFi 漫游&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category></item><item><title>盛科 CTC7132 逆向: 解锁 SFP+ 2.5G</title><link>https://blog.nanami.tech/en/archives/387</link><guid isPermaLink="false">en:387</guid><description>前言
博主前段时间购入了一台基于 Centec CTC7132 平台的企业级交换机. 其拥有 48 个 2.5Gbe 电口, 4 个 SFP+ 光口和两个 40G QSFP 光口. 同时, 博主也购入了两条 2.5Gbe 的 SFP GPON 猫棒.</description><pubDate>Wed, 07 Oct 2026 13:51:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主前段时间购入了一台基于 Centec CTC7132 平台的企业级交换机. 其拥有 48 个 2.5Gbe 电口, 4 个 SFP+ 光口和两个 40G QSFP 光口. 同时, 博主也购入了两条 2.5Gbe 的 SFP GPON 猫棒. 使用这类猫棒的一个硬性要求就是&lt;strong&gt;端口速率强制锁死在 2.5Gbe / 1Gbe, 否则无法使用.&lt;/strong&gt; 当博主在其 WebUI 上尝试更改速率时, 出现了要求我使用 &lt;code&gt;group-speed&lt;/code&gt; 命令更改的报错. 但使用 CLI 发现 &lt;code&gt;group-speed&lt;/code&gt; 并没有可以将接口调制成 2.5Gbe 的命令, 遂深入研究.&lt;/p&gt;
&lt;h2&gt;CTC7132 平台&lt;a href=&quot;#ctc7132-平台&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;CTC7132（TsingMa）芯片是盛科面向云时代，边缘计算技术演进需求推出的第六代核心交换芯片。芯片集成 ARM 双核 A53 处理器，支持 QSGMII 和 USXGMII 等端口形态，提供从 100M 到 100G 的全速率端口能力。
芯片创新集成 X-Engine™，包含了 OAM/BFD Engine，Telemetry Engine，Security Engine 和 Wireless Engine 等。提供线速的增强特性能力和更高的集成度，更好服务于边缘的多业务接入场景，满足网络未知，业务需求不断融合的网络发展趋势。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OAM/BFD Engine 提供高精度，多条目的 OAM 和 BFD 会话，并集成了 RFC2544 和 TWAMP 能力，提供 IP RAN 的接入解决方案。&lt;/li&gt;
&lt;li&gt;Telemetry Engine 提供的 NetFlow 功能，基于会话提供业务统计，丢包统计，提供最小和最大的时延抖动分析，为业务和流量优化提供数据支撑。&lt;/li&gt;
&lt;li&gt;Wireless Engine 提供线速的 CAPWAP 加解封装以及分片重组能力，支撑 1G/2.5G/5G 多速率融合，有效支撑有线无线的融合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;作为盛科第六代芯片，CTC7132 继承了丰富的特性，包括 L2、L3、MPLS、VXLAN、MPLS SR 和 OAM/APS 等特性，亮点特性包括可视化特性、可编程特性、安全和流量控制特性、高精度时钟特性。
CTC7132 提供 100M/1G/2.5G/5G/10G/25G/40G/50G/100G 的端口速率。其 SerDes 设计满足多个端口协议：SGMII/QSGMII/USXGMII/XFI/SFI/XAUI/CAUI4/10G-KR/40G-KR4/100G-KR4/25G-KR/50G-KR2。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;引用自 &lt;a href=&quot;https://www.centec.com/silicon/Ethernet-Switch-Silicon/CTC7132&quot;&gt;https://www.centec.com/silicon/Ethernet-Switch-Silicon/CTC7132&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;综上所述, 芯片侧是支持 2.5Gbe 速率的配置的.&lt;/p&gt;
&lt;h2&gt;研究目标&lt;a href=&quot;#研究目标&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;既然判断大概率不是 CPU 侧的限制, 那么研究方向主要集中在软件, 例如底层 SDK, 上层 CLI. 除此之外, 我们还需要探究为什么厂商要强制将四个 SFP+ 端口绑定在一个组内统一调整速率, 以及为什么不能调整 2.5Gbe 速率.&lt;/p&gt;
&lt;h2&gt;观前提示&lt;a href=&quot;#观前提示&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;阅读本文需要您具备一定的 Linux 基础知识, Linux 编程基础, 逆向基础, 计算机网络知识基础等. 如果您没有这些知识, 可能会阅读困难. 可以尝试借助 AI 来辅助理解.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 固件分析&lt;a href=&quot;#1-固件分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;使用 &lt;code&gt;binwalk&lt;/code&gt; 解包固件, 获取完整的 rootfs. 经过分析后可以得到以下信息&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;项&lt;/th&gt;&lt;th&gt;值&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;内核版本&lt;/td&gt;&lt;td&gt;&lt;code&gt;4.9.62-tsingma&lt;/code&gt; (厂商自定义 &lt;code&gt;LOCALVERSION&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;架构&lt;/td&gt;&lt;td&gt;AArch64 (ARM64), SMP&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;编译工具&lt;/td&gt;&lt;td&gt;Linaro GCC 6.3.1 (2017.02)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;构建时间&lt;/td&gt;&lt;td&gt;2024-11-18 CST&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;平台&lt;/td&gt;&lt;td&gt;Centec (盛科), &lt;code&gt;CLDK v20.01&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;我们的核心目的是将端口速率更改至 2.5Gbe, 所以我们需要使得 &lt;code&gt;group-speed&lt;/code&gt; 命令支持 2.5Gbe 速率的下发. 因此首要入手点是 &lt;code&gt;group-speed&lt;/code&gt; 命令. 全盘搜索该字符串, 查找哪些二进制里包含这个字符串.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;nanami114@NanamiWork-PC:~/firmware/moondon_webImage_v3.0.17.20250718/_uImage_v3.0.15.7.bin.extracted/_53E8E4.extracted/cpio-root$&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; -rl&lt;/span&gt;&lt;span&gt; --binary-files=text&lt;/span&gt;&lt;span&gt; &quot;group-speed&quot;&lt;/span&gt;&lt;span&gt; usr/&lt;/span&gt;&lt;span&gt; lib/&lt;/span&gt;&lt;span&gt; sbin/&lt;/span&gt;&lt;span&gt; bin/&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;usr/sbin/imi&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;usr/sbin/nsm&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;usr/bin/imish&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;lib/libimish.so&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在博主之前的分析中已经得出 &lt;code&gt;imish&lt;/code&gt; 和 &lt;code&gt;imi&lt;/code&gt; 均为用户态 OEM Shell, 只具备下发命令参数的功能, 不具备底层 SDK 实现. 因此, 这里我们需要检查的就是 &lt;code&gt;usr/sbin/nsm&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;2. 分析 &lt;code&gt;nsm&lt;/code&gt;&lt;a href=&quot;#2-分析-nsm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;2.1 &lt;code&gt;group-speed&lt;/code&gt; 分析&lt;a href=&quot;#21-group-speed-分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;在 IDA Pro 中对其进行静态逆向. 查找所有包含 &lt;code&gt;group-speed&lt;/code&gt; 的函数
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/387-1.png&quot; alt=&quot;IDA Pro 中搜索 group-speed 字符串的交叉引用&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;IDA Pro 中搜索 group-speed 字符串的交叉引用&lt;/figcaption&gt;&lt;/figure&gt;
经过分析和查找, 发现在 &lt;code&gt;00b9a090&lt;/code&gt; 处的 &lt;code&gt;group-speed&lt;/code&gt; 指向了一个 &lt;code&gt;sub_536744&lt;/code&gt; 函数, 对其进行分析.
&lt;figure&gt;&lt;img src=&quot;/images/387-2.png&quot; alt=&quot;sub_536744 函数中 group-speed 的调用关系&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;sub_536744 函数中 group-speed 的调用关系&lt;/figcaption&gt;&lt;/figure&gt;
完整的 &lt;code&gt;sub_536744&lt;/code&gt; 伪代码如下&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_536744&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;__int64 &lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; __int64 &lt;/span&gt;&lt;span&gt;a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; **&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  unsigned&lt;/span&gt;&lt;span&gt; __int8 v6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+33h] [xbp+33h] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v7&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+34h] [xbp+34h] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+38h] [xbp+38h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; v9&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+3Fh] [xbp+3Fh]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+40h] [xbp+40h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  unsigned&lt;/span&gt;&lt;span&gt; __int8 v11&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+4Fh] [xbp+4Fh]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v10 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 64&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v9 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v11 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;%% Can only set speed on physical interface&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_50EB5C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v7&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v8 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; &quot;%% Get port group id fail &lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;%% Unsupported CLI in present interface. Please refer to CLI &lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;speed %s&lt;/span&gt;&lt;span&gt;\&quot;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (((&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;byte_B9B4E8 &lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F1B0&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      byte_B9B4E8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F184&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      byte_B9B4E8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      byte_B9B4E8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  sub_49ABCC&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  sub_49AC88&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  sub_49ACFC&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v9 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; byte_CAB190&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;1000&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; sub_52C79C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4294967051&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F1B0&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v9 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;speed has already been 1G, no need to config &lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v11 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;10G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; sub_52C79C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4294967051&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F184&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v9 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;speed has already been 10G, no need to config &lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v11 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;25G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v7 &lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;80&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; sub_52C79C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4294967051&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v9 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;speed has already been 25G, no need to config &lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v11 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;default&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; ((&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F1B0&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; byte_B9B4E8 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       ||&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F184&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; byte_B9B4E8 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       ||&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v10 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; byte_B9B4E8 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v9 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;speed has already been default value, no need to config &lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v11 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; byte_B9B4E8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_510E9C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; v11&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; v6&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v8 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; &quot;%% Set speed failed!&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;default&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; v11 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int8&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;byte_B9B4E8 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      byte_CAB191 &lt;/span&gt;&lt;span&gt;&amp;amp;=&lt;/span&gt;&lt;span&gt; ~&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int8&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      byte_CAB191 &lt;/span&gt;&lt;span&gt;|=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      dword_CAB194 &lt;/span&gt;&lt;span&gt;&amp;amp;=&lt;/span&gt;&lt;span&gt; ~&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;15&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;)));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      dword_CAB194 &lt;/span&gt;&lt;span&gt;|=&lt;/span&gt;&lt;span&gt; v11 &lt;/span&gt;&lt;span&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    byte_CAB190 &lt;/span&gt;&lt;span&gt;|=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;v6 &lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以明显看出, 这个函数就是 &lt;code&gt;group-speed&lt;/code&gt; 的处理函数. 因此我们标记其为 &lt;code&gt;0x536744&lt;/code&gt;.
在该函数中, 有几处明显和速率有关的 &lt;code&gt;strncmp&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;1000&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;10G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;25G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;default&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;其中 1000, 10G, 25G, default 恰好对应了 &lt;code&gt;group-speed&lt;/code&gt; 的四种速率状态&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Switch(config-if&lt;/span&gt;&lt;span&gt;)# group-speed &lt;/span&gt;&lt;span&gt;?&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  1000&lt;/span&gt;&lt;span&gt;     Switch&lt;/span&gt;&lt;span&gt; speed&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; 1G&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  10G&lt;/span&gt;&lt;span&gt;      Switch&lt;/span&gt;&lt;span&gt; speed&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; 10G&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  25G&lt;/span&gt;&lt;span&gt;      Switch&lt;/span&gt;&lt;span&gt; speed&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; 25G&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  default&lt;/span&gt;&lt;span&gt;  Switch&lt;/span&gt;&lt;span&gt; speed&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; value&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;同时我们还可以看出, 所有用户输入处理完成后, 被统一交付给了一个 &lt;code&gt;sub_510E9C&lt;/code&gt; 函数进行处理, 然后将返回值交给 &lt;code&gt;v8&lt;/code&gt; 参数, 作为命令执行的结果. 因此我们这里定位到 &lt;code&gt;sub_510E9C&lt;/code&gt; 进行研究&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_510E9C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;__int64 &lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; unsigned&lt;/span&gt;&lt;span&gt; __int8 &lt;/span&gt;&lt;span&gt;a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; unsigned&lt;/span&gt;&lt;span&gt; __int8 &lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 4294967287&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 4294967284&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_4FC03C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该函数指向了 &lt;code&gt;sub_4FC03C&lt;/code&gt;, 继续分析&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_4FC03C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;__int64 &lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; unsigned&lt;/span&gt;&lt;span&gt; __int8 &lt;/span&gt;&lt;span&gt;a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; unsigned&lt;/span&gt;&lt;span&gt; __int8 &lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_9C0DC4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 128&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该函数指向了 &lt;code&gt;sub_9C0DC4&lt;/code&gt;, 继续分析&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_9C0DC4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v4&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+28h] [xbp+28h] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; v5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+2Ch] [xbp+2Ch]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; v6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+2Dh] [xbp+2Dh]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v4 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v5 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v6 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; sub_9B4D70&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;929&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;该函数指向了 &lt;code&gt;sub_9B4D70&lt;/code&gt;, 继续分析&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_9B4D70&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        const&lt;/span&gt;&lt;span&gt; void&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        size_t&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        __int64 &lt;/span&gt;&lt;span&gt;a4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        __int64 &lt;/span&gt;&lt;span&gt;a5&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        __int64 &lt;/span&gt;&lt;span&gt;a6&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        __int64 &lt;/span&gt;&lt;span&gt;a7&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // w0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  _DWORD s&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;span&gt; // [xsp+58h] [xbp+58h] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v14&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+6Ch] [xbp+6Ch]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v15&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+70h] [xbp+70h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  void&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+78h] [xbp+78h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v15 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v14 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  memset&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;10&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; dword_E51FE0 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; a1 &lt;/span&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;479&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;a3 &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; a2 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; sock_shal &lt;/span&gt;&lt;span&gt;&amp;gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; qword_E4FF98 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;hal socket not connect, send msg(%d) fail&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; a3 &lt;/span&gt;&lt;span&gt;&amp;lt;=&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FF4&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; qword_E51FF0 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int16 &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;qword_E51FF0 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; a3 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              sub_9B4B60&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; dword_E4FF84&lt;/span&gt;&lt;span&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            s&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; v8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            s&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; a3 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            s&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v15 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_9B3F1C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;sock_shal&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a3 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v15 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v15 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 18&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int16 &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v15 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              memcpy&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;C&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v15 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +=&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;dest &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              memcpy&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v15 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +=&lt;/span&gt;&lt;span&gt; a3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;dword_E51FA4 &lt;/span&gt;&lt;span&gt;||&lt;/span&gt;&lt;span&gt; a7 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                while&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; qword_E51FE8 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                  v14 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_9B4B60&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v14 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                    pal_delay&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;hal talk: no memory&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;hal talk: req_len is too longer&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;req == NULL, but req_len != 0&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;Msg type error, 0x%x&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    log_sys&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;158&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;hal socket not init&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;FFFFFFFF&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;不难看出, 函数 &lt;code&gt;sub_9B4D70&lt;/code&gt; 就是用户 CLI 与板层 HAL 通讯的函数.
纵观整个 &lt;code&gt;group-speed&lt;/code&gt; 实现, 我们不难发现, &lt;strong&gt;该命令根本没有 2.5Gbe 速率的分支, 从底层也根本没实现 2.5Gbe 速率的下发.&lt;/strong&gt; 因此 &lt;code&gt;group-speed&lt;/code&gt; 对于我们的目的而言已经没有研究的价值了. 现在的方向应该是&lt;strong&gt;检查在什么情况下 &lt;code&gt;speed&lt;/code&gt; 命令才会拒绝下发命令, 转而要求使用 &lt;code&gt;group-speed&lt;/code&gt;.&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;2.2 &lt;code&gt;speed&lt;/code&gt; 分析&lt;a href=&quot;#22-speed-分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;查找所有包含 &lt;code&gt;speed&lt;/code&gt; 的函数
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/387-3.png&quot; alt=&quot;IDA Pro 中搜索 speed 相关函数的交叉引用&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;IDA Pro 中搜索 speed 相关函数的交叉引用&lt;/figcaption&gt;&lt;/figure&gt;
在 &lt;code&gt;sub_534568&lt;/code&gt; 函数中发现了关于配置速率报错的字符串输出, 我们这里重点分析该函数&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;__int64 __fastcall &lt;/span&gt;&lt;span&gt;sub_534568&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;__int64 &lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; __int64 &lt;/span&gt;&lt;span&gt;a2&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; **&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;v4&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;__int64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt; // x19&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // x20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;v6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // x0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;v7&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;__int64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt; // x19&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // x20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;v9&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // x21&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;v10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // x0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; dest&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;span&gt; // [xsp+50h] [xbp+50h] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v14&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+52h] [xbp+52h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; v15&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+5Bh] [xbp+5Bh] BYREF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; v16&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+5Ch] [xbp+5Ch]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v17&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+60h] [xbp+60h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v18&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+68h] [xbp+68h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  int&lt;/span&gt;&lt;span&gt; v19&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+74h] [xbp+74h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  __int64 v20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+78h] [xbp+78h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; v21&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+84h] [xbp+84h]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  char&lt;/span&gt;&lt;span&gt; v22&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+8Bh] [xbp+8Bh]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; v23&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; // [xsp+8Ch] [xbp+8Ch]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v20 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 64&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v22 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v15 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_50EB5C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v15&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;v19 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v15 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v14 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        strcpy&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;%% Unsupported CLI in present interface. Please refer to CLI &lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;group-speed %s&lt;/span&gt;&lt;span&gt;\&quot;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 76&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_DWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 84&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;%% Can not set speed with interface media type auto select&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v18 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 448&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v18 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v18 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 125&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v18 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 96&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;%% Cannot configure aggregator member&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  v17 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 448&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v17 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v17 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 125&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v17 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 96&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; &quot;%% Cannot configure aggregator&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 9&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v4 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;__int64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v5 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v6 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_49EB94&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int16 &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v5&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;%% Can&apos;t set speed on %s interface&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; v6&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;400G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;200G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;100G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;40G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;50G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;25G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 9&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;10G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;5G&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;2G5&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;1000&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;100&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;span&gt; if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;10&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; strncmp&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;auto&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; &quot;%% Invalid speed : %s&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v23 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_DWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 268&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_DWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 820&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;%% Please disable eee function first&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; !=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ||&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F024&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F050&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0A8&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F184&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      v22 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v22 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;80&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 9&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;3F&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;3F&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;3F&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;3F&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 8&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 9&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F050&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0A8&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F050&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;3F&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 11&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 12&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F07C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F0D4&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_50F100&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v21 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 20&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v23 &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 8&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 249&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 248&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;__fastcall &lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;%% Please disable flowcontrol send and receive function first&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      v16 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_510A48&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 136&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;LL&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; v20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; v23&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;v16 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_BYTE &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 401&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; |=&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;u&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_52C79C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; v16&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v7 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;__int64&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v8 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v9 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_49FF90&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; __int16 &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 836&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v10 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;sub_49ED5C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;unsigned&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 68&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v7&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v8&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;%% Warning: FEC %s can be configured but not in effect on %s port&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;%% Please use show interface cmd to confirm FEC status details&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v9&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          v10&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; v21&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看出, 该函数中包含了 &lt;code&gt;speed&lt;/code&gt; 命令的多个速率模式 &lt;code&gt;(auto, 10, 100, 1000, 10G, 40G, 100G)&lt;/code&gt;, 以及关键用户侧报错 &lt;code&gt;%% Unsupported CLI in present interface. Please refer to CLI \&quot;group-speed %s\&quot;\n&lt;/code&gt;. 定位到报错位置具体分析代码.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v15 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_50EB5C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v15&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;v19 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v15 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v14 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        strcpy&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;%% Unsupported CLI in present interface. Please refer to CLI &lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;group-speed %s&lt;/span&gt;&lt;span&gt;\&quot;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从代码中我们可以看出, 只有当 &lt;code&gt;sub_50EB5C&lt;/code&gt; 返回非零值时, 才会触发相应检测. 这里我们查看其汇编继续分析&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:00000000005367AC&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367AC loc_5367AC                              ; CODE XREF: sub_536744+38↑j&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367AC                 ADD             X1, X29, #0x50+var_1C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367B0                 ADD             X0, X29, #0x50+var_1D&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367B4                 MOV             X2, X1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367B8                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367BC                 LDR             X0, [X29,#0x50+var_10]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367C0                 BL              sub_50EB5C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367C4                 STR             W0, [X29,#0x50+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367C8                 LDR             W0, [X29,#0x50+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367CC                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367D0                 B.EQ            loc_536800&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367D4                 LDR             X0, [X29,#0x50+var_28]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367D8                 LDR             X2, [X0,#0x10]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367DC                 LDR             X0, [X29,#0x50+var_28]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367E0                 LDR             X3, [X0,#0x18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367E4                 ADRL            X0, aGetPortGroupId ; &quot;%% Get port group id fail \n&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367EC                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367F0                 MOV             X0, X3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367F4                 BLR             X2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367F8                 MOV             W0, #1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005367FC                 B               loc_536DCC&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里我们可以看到, 该函数执行后调用了 &lt;code&gt;sub_50EB5C&lt;/code&gt;, 然后读取其返回值, 当其返回值为 0 时, 继续执行 &lt;code&gt;loc_536800&lt;/code&gt; 处代码, 当其返回值非 0 时, 输出 &lt;code&gt;%% Get port group id fail \n&lt;/code&gt;. 因此这里我们可以判断, &lt;code&gt;sub_50EB5C&lt;/code&gt; 的语义正为用户态的 &lt;code&gt;get port group id&lt;/code&gt;.
所以这里得出的结论是: &lt;strong&gt;当 &lt;code&gt;speed&lt;/code&gt; 检测到 &lt;code&gt;group-id&lt;/code&gt; 非 0 时触发告警, 并让用户使用 &lt;code&gt;group-speed&lt;/code&gt; 指定速率.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;3. 研究判断逻辑&lt;a href=&quot;#3-研究判断逻辑&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;既然我们现在已经知道 &lt;code&gt;speed&lt;/code&gt; 命令检测的是 &lt;code&gt;group-id&lt;/code&gt;, 那么我们就从这里下手. 现在我们就来研究怎么样让 &lt;code&gt;speed&lt;/code&gt; 命令绕过 &lt;code&gt;group-id&lt;/code&gt; 的检测, 直接向板卡下发命令.
在上面的分析中我们可以得知, &lt;code&gt;sub_536744&lt;/code&gt; 函数是 &lt;code&gt;group-speed&lt;/code&gt; 命令的处理函数. 我们现在要找的是 &lt;code&gt;speed&lt;/code&gt;, 所以肯定还有别的函数是包含 &lt;code&gt;Unsupported CLI in present interface&lt;/code&gt; 报错的. 经过全局搜索后, 发现除了 &lt;code&gt;sub_536744&lt;/code&gt; 以外, 只有 &lt;code&gt;sub_534568&lt;/code&gt; 是包含这个报错的.
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/387-4.png&quot; alt=&quot;speed 命令对 group-id 的检测逻辑&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;speed 命令对 group-id 的检测逻辑&lt;/figcaption&gt;&lt;/figure&gt;
因此我们这里分析该函数.&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;v20 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 302&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; )&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v15 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    v19 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sub_50EB5C&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;v20&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;v15&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;v19 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt; v15 &lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_WORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;dest &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        v14 &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        strcpy&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;dest&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;void&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;**&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;_QWORD&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; char&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;))(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;_QWORD &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;)(&lt;/span&gt;&lt;span&gt;a1 &lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt; 24&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;%% Unsupported CLI in present interface. Please refer to CLI &lt;/span&gt;&lt;span&gt;\&quot;&lt;/span&gt;&lt;span&gt;group-speed %s&lt;/span&gt;&lt;span&gt;\&quot;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          *&lt;/span&gt;&lt;span&gt;a3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从该函数中得知, 当 &lt;code&gt;v15&lt;/code&gt; 非 0 时, 会触发报错. 而修改 &lt;code&gt;v15&lt;/code&gt; 的函数为 &lt;code&gt;sub_50EB5C&lt;/code&gt;, 也就是上面所说的 &lt;code&gt;get port group id&lt;/code&gt;. 所以我们这里直接查看汇编, 看看哪个地址调用了该函数.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:00000000005345AC                 B.NE            loc_534644&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345B0                 STRB            WZR, [X29,#0x90+var_35]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345B4                 STR             WZR, [X29,#0x90+var_1C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345B8                 ADD             X0, X29, #0x90+var_35&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345BC                 MOV             X2, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345C0                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345C4                 LDR             X0, [X29,#0x90+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345C8                 BL              sub_50EB5C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345CC                 STR             W0, [X29,#0x90+var_1C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345D0                 LDR             W0, [X29,#0x90+var_1C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345D4                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345D8                 B.NE            loc_534644&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345DC                 LDRB            W0, [X29,#0x90+var_35]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345E0                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345E4                 B.EQ            loc_534644&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345E8                 ADRL            X0, word_AAD088&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345F0                 LDRH            W0, [X0]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345F4                 STRH            W0, [X29,#0x90+dest]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345F8                 STUR            XZR, [X29,#0x90+var_3E]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:00000000005345FC                 LDR             X0, [X29,#0x90+var_58]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534600                 LDR             X1, [X0] ; src&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534604                 ADD             X0, X29, #0x90+dest ; dest&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534608                 BL              .strcpy&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053460C                 LDR             X0, [X29,#0x90+var_48]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534610                 LDR             X3, [X0,#0x10]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534614                 LDR             X0, [X29,#0x90+var_48]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534618                 LDR             X4, [X0,#0x18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053461C                 LDR             X0, [X29,#0x90+var_58]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534620                 LDR             X1, [X0]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534624                 ADRL            X0, aUnsupportedCli ; &quot;%% Unsupported CLI in present interface&quot;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053462C                 MOV             X2, X1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534630                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534634                 MOV             X0, X4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534638                 BLR             X3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053463C                 MOV             W0, #1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534640                 B               loc_53504C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从汇编码中可以看到, 在 &lt;code&gt;0x5345C8&lt;/code&gt; 位置调用了该函数. 查看上下文, 可以发现:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.text:00000000005345C4                 LDR             X0, [X29,#0x90+var_18]&lt;/code&gt; 为 ifentry&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sub_50EB5C&lt;/code&gt; 获取 &lt;code&gt;group-id&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:00000000005345CC                 STR             W0, [X29,#0x90+var_1C]&lt;/code&gt; 保存返回值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:00000000005345D8                 B.NE            loc_534644&lt;/code&gt; 取失败, 当作无组接口继续&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:00000000005345DC                 LDRB            W0, [X29,#0x90+var_35]&lt;/code&gt; 取上文获取的返回值&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:00000000005345E4                 B.EQ            loc_534644&lt;/code&gt; &lt;code&gt;group==0&lt;/code&gt;, 跳至正常 speed 设置速率.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在已经分析的很明确了: &lt;code&gt;0x5345E4&lt;/code&gt; 就是&lt;strong&gt;判断 &lt;code&gt;group-id&lt;/code&gt; 为 0 则正常下发速率的命令.&lt;/strong&gt; 到了这一步我们就可以做一个尝试: &lt;strong&gt;将这一块的 &lt;code&gt;B.EQ&lt;/code&gt; 改为 &lt;code&gt;B&lt;/code&gt;, 即无论如何都走正常速率下发流程.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;4. 第一次 Patch&lt;a href=&quot;#4-第一次-patch&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;知道了手段, 那么我们就尝试写一份内存 Patch 脚本, 然后在设备上运行.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 该设备的 Linux Root Shell 已被博主破解, 目前已和厂商反馈并申请相关 CVE-ID. 在厂商明确修复完成并下放补丁前不做技术细节公开.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;已知设备上有 Python 2.7 环境, 所以我们这里用 Python 写内存补丁.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;GPATCH &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;5345e4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ABIL&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;pack&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&amp;lt;I&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;20&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;      # 给能力位图补 0x20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;GPATCH&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unhexlify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;18000014&apos;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;   # b.eq -&amp;gt; b&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;应用内存补丁后, 尝试使用 &lt;code&gt;speed&lt;/code&gt; 命令进行修改. 虽然没有报错使用 &lt;code&gt;group-speed&lt;/code&gt;, 但是出现了新的报错: &lt;code&gt;% Can not set speed with interface media type auto select&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;5. 定位首次 Patch 报错点&lt;a href=&quot;#5-定位首次-patch-报错点&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;在 &lt;code&gt;0x534674&lt;/code&gt; 处发现该报错的字符串&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:0000000000534674                 ADRL            X0, aCanNotSetSpeed ; &quot;%% Can not set speed with interface med&quot;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;查看具体汇编码&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:0000000000534644 loc_534644                              ; CODE XREF: sub_534568+44↑j&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534644                                         ; sub_534568+70↑j ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534644                 LDR             X0, [X29,#0x90+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534648                 LDR             W0, [X0,#0x4C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053464C                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534650                 B.GE            loc_534690&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534654                 LDR             X0, [X29,#0x90+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534658                 LDR             W0, [X0,#0x54]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053465C                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534660                 B.NE            loc_534690&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534664                 LDR             X0, [X29,#0x90+var_48]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534668                 LDR             X2, [X0,#0x10]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053466C                 LDR             X0, [X29,#0x90+var_48]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534670                 LDR             X3, [X0,#0x18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534674                 ADRL            X0, aCanNotSetSpeed ; &quot;%% Can not set speed with interface med&quot;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053467C                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534680                 MOV             X0, X3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534684                 BLR             X2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:0000000000534688                 MOV             W0, #1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000053468C                 B               loc_53504C&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里可以看到, 该报错的执行条件是 &lt;code&gt;[ifentry+0x4c] &amp;lt; 0 &amp;amp;&amp;amp; [ifentry+0x54] == 0&lt;/code&gt;. 读取各口字段发现厂商做了如下处理&lt;/p&gt;























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;端口&lt;/th&gt;&lt;th&gt;&lt;code&gt;[+0x4c]&lt;/code&gt;&lt;/th&gt;&lt;th&gt;&lt;code&gt;[+0x54]&lt;/code&gt;&lt;/th&gt;&lt;th&gt;结果&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;电口 / QSFP&lt;/td&gt;&lt;td&gt;正数&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;通过&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SFP+ 51~54&lt;/td&gt;&lt;td&gt;负数&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;报错&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;也就是说当 &lt;code&gt;media-type&lt;/code&gt; 为 电口 / QSFP 时, 可以通过检查. 厂商 CLI 中有直接修改 &lt;code&gt;media-type&lt;/code&gt; 的相关命令, 所以这里尝试直接在 CLI 中修改. 修改完成后再次使用 speed 命令下发指令, 随即被设备接受.&lt;/p&gt;
&lt;h3&gt;6. 第一次踩坑&lt;a href=&quot;#6-第一次踩坑&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;应用速率后, 接入设备查看连接. 发现等了好一会并没有成功协商 2.5Gbe 速率. 再次下发指令发现出现新的报错: &lt;code&gt;% Unsupport port speed ability&lt;/code&gt;. 查看设备日志发现, &lt;strong&gt;手动更改的 &lt;code&gt;media-type&lt;/code&gt; 被守卫进程 &lt;code&gt;hsrvd&lt;/code&gt; 从 HAL 层重新拉回了 &lt;code&gt;0x04&lt;/code&gt;.&lt;/strong&gt; 因此这里得出了一个结论:
&lt;strong&gt;数据补丁不可靠, 必须直接改代码.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;7. 尝试更改代码&lt;a href=&quot;#7-尝试更改代码&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;经过上面的步骤, 博主发现: 能力限制的真正源头在 HAL 层, nsm 只是通讯中间件.
经过一番查找, 发现类型门校验在 &lt;code&gt;0x50f920&lt;/code&gt; 处. 查看附近汇编码&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:000000000050F750                 ADD             X0, X29, #0x30+var_10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F754                 MOV             X1, X0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F758                 LDR             X0, [X29,#0x30+var_18]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F75C                 BL              sub_50EAAC&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F760                 LDR             W0, [X29,#0x30+var_10]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F764                 AND             W0, W0, #0x1FFF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F768                 STR             W0, [X29,#0x30+var_4]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F76C                 LDR             W0, [X29,#0x30+var_8]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F770                 AND             W0, W0, #0xFFFFFF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F774                 STR             W0, [X29,#0x30+var_C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F910 loc_50F910                              ; CODE XREF: sub_50F728+1D4↑j&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F910                 LDR             W0, [X29,#0x30+var_1C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F914                 CMP             W0, #7&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F918                 B.NE            loc_50F92C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F91C                 LDR             W0, [X29,#0x30+var_C]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F920                 AND             W0, W0, #0x20 ; &apos; &apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F924                 CMP             W0, #0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050F928                 B.NE            loc_50F970&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;逐一解读逻辑:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.text:000000000050F758                 LDR             X0, [X29,#0x30+var_18]&lt;/code&gt; - ifentry&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:000000000050F75C                 BL              sub_50EAAC&lt;/code&gt; - 计算端口类型&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:000000000050F768                 STR             W0, [X29,#0x30+var_4]&lt;/code&gt; - &lt;code&gt;*type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:000000000050F76C                 LDR             W0, [X29,#0x30+var_8]&lt;/code&gt; - ifentry + 0x50&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.text:000000000050F774                 STR             W0, [X29,#0x30+var_C]&lt;/code&gt; - ability = 能力位图&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;接着查找能力位图&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;.text:000000000050E3BC                 AND             W0, W0, #0x1FFF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3C0                 CMP             W0, #0x63 ; switch 100 cases&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3C4                 B.HI            def_50E3DC ; jumptable 000000000050E3DC default case, case 54&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3C8                 ADRL            X1, jpt_50E3DC&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3D0                 LDR             W0, [X1,W0,UXTW#2]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3D4                 ADR             X1, loc_50E3E0 ; jumptable 000000000050E3DC case 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3D8                 ADD             X0, X1, W0,SXTW#2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;.text:000000000050E3DC                 BR              X0      ; switch jump&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;50e3fc: ... 50e404: bl strncmp        ; 与 0xaa3d48 = &apos;agg&apos;   (len 3) → 返回 20&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;50e430: ... bl strncmp                ; 与 0xaa3d50 = &apos;vlan&apos;  (len 4) → 返回 21&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;50e45c: ... bl strncmp                ; 与 0xaa3d58 = &apos;tunnel&apos;(len 6) → 返回 22&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;50e488: ... bl strncmp                ; 与 0xaa3d60 = &apos;loopback&apos;(len 8) → 返回 23&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;50e4b4: ... bl strncmp                ; 与 0xaa3d70 = &apos;seth&apos;  → 返回 ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;即 type 是&lt;strong&gt;按接口名(agg/vlan/tunnel*/loopback*/seth*/eth*……)分出来的类别码&lt;/strong&gt;.
最终解出来的能力位图如下&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;分支&lt;/th&gt;&lt;th&gt;允许的速率码&lt;/th&gt;&lt;th&gt;说明&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;type==1&lt;/td&gt;&lt;td&gt;{0,1,2,3}&lt;/td&gt;&lt;td&gt;&lt;code&gt;[if+0x10c]!=0&lt;/code&gt; 时禁 3(1G),返回 -246&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;type==3&lt;/td&gt;&lt;td&gt;{0,1,2}&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;type==45&lt;/td&gt;&lt;td&gt;{0,2,3,7,8}&lt;/td&gt;&lt;td&gt;&lt;code&gt;[if+0x10c]!=0&lt;/code&gt; 时禁 3/7/8;再查能力位&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;type==43 (0x2b)&lt;/td&gt;&lt;td&gt;{0,2,3,4,7,8}&lt;/td&gt;&lt;td&gt;&lt;code&gt;[if+0x10c]!=0&lt;/code&gt; 时禁 3/7/8/4;再查能力位&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;其余&lt;/td&gt;&lt;td&gt;5/6/4/3/2/10/9/7/11/12 ……&lt;/td&gt;&lt;td&gt;按大速率集查能力位&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;因此速率码对照表即为: 0=auto 1=10M 2=100M 3=1G 4=10G 5=40G 6=100G 7=2.5G 8=5G 9=25G 10=50G 11=200G 12=400G
所以这里我们需要给校验码打补丁:&lt;/p&gt;















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;地址&lt;/th&gt;&lt;th&gt;原值&lt;/th&gt;&lt;th&gt;新值&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;nsm VA &lt;code&gt;0x50f728&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;fd 7b bd a9&lt;/code&gt; (&lt;code&gt;stp x29,x30,[sp,#-48]!&lt;/code&gt;)&lt;/td&gt;&lt;td&gt;&lt;code&gt;00 00 80 52 c0 03 5f d6&lt;/code&gt; (&lt;code&gt;mov w0,#0; ret&lt;/code&gt;)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h3&gt;8. 第二次 Patch&lt;a href=&quot;#8-第二次-patch&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;使用 Python 编写补丁&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;pid &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;span&gt;; act &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BK &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;/tmp/mpatch_bk.txt&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# (label, nsm VA, original bytes hex, new bytes hex)  -- lengths may be 4 or 8 bytes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;EDITS &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    # 0x50f728 = port-speed ability validator: &quot;stp x29,x30,[sp,#-48]!&quot; -&amp;gt; &quot;mov w0,#0; ret&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;&apos;valid_entry&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;50f728&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;fd7bbda9&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;00008052c0035fd6&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    f &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/proc/&lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;/mem&apos;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;rb&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;seek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;off&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;; &lt;/span&gt;&lt;span&gt;return&lt;/span&gt;&lt;span&gt; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    f &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/proc/&lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;/mem&apos;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;r+b&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;seek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;off&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;data&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;; f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;flush&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;hexlify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; act &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;read&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%-14s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%x&lt;/span&gt;&lt;span&gt;  now=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; act &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;patch&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    lines &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        cur &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        lines&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; %x&lt;/span&gt;&lt;span&gt; %s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unhexlify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;WARN &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; current=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; expected=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BK&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;w&apos;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;lines&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%-14s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%x&lt;/span&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; act &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;restore&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; line &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BK&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unhexlify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;WARN &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; current=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; expected=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BK&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;w&apos;&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;lines&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; +&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; o&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%-14s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%x&lt;/span&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;o&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; act &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;restore&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; line &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BK&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; line&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;split&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; binascii&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;unhexlify&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cur&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;restored &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;a&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;cur&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在设备上应用补丁. 然后再次 speed 下发速率.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Switch(config-if&lt;/span&gt;&lt;span&gt;)# speed 2G5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Switch#&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; running-config&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; eth-0-51&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;interface&lt;/span&gt;&lt;span&gt; eth-0-51&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; speed&lt;/span&gt;&lt;span&gt; 2G5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Switch#&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; eth-0-51&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Interface&lt;/span&gt;&lt;span&gt; current&lt;/span&gt;&lt;span&gt; state:&lt;/span&gt;&lt;span&gt; UP&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Bandwidth&lt;/span&gt;&lt;span&gt; 2500000&lt;/span&gt;&lt;span&gt; kbits&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Speed&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; 2.5Gb/s&lt;/span&gt;&lt;span&gt; ,&lt;/span&gt;&lt;span&gt; Duplex&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; Full&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 此时端口速率已经成功的应用为 2.5Gbe. 且测试后接入设备也没有重置速率. 至此, Patch 完成.
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/387-5.png&quot; alt=&quot;端口速率成功设置为 2.5Gbe&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;端口速率成功设置为 2.5Gbe&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;9. 持久化&lt;a href=&quot;#9-持久化&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;该交换机的 rootfs 文件系统为 ramfs, 所以没法做持久化. 但是 flash 挂载为 ext4. 因此我们可以写个 patch 脚本在设备上, 如果设备重启就手动应用一遍脚本. 交换机这种设备只要不是设备断电, 几乎不会重启. 所以这种方法暂且也是可行的. 之后或许会研究真正持久化的做法. 这里把完整补丁内容贴出来&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;#!/usr/bin/python2.7&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# -*- coding: utf-8 -*-&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; glob&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;TARGET &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;/usr/sbin/nsm&apos;&lt;/span&gt;&lt;span&gt;                     # 目标进程&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;WAIT_SECS &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 30&lt;/span&gt;&lt;span&gt;                               # 等待 nsm 上线的秒数&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# (标签, 运行时地址 == 文件内 VA（nsm 为非 PIE）, 原始字节, 补丁字节)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 注意：字节串均为小端（ARM64 指令在内存中的实际字节序）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;EDITS &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;&apos;group_check      &apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;5345e4&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;00030054&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt;         &apos;18000014&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    (&lt;/span&gt;&lt;span&gt;&apos;ability_validator&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 0x&lt;/span&gt;&lt;span&gt;50f728&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;fd7bbda9fd030091&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;00008052c0035fd6&apos;&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PATCHDIR &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;dirname&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;abspath&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;__file__&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BACKUP &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;PATCHDIR&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;patch-sfp+.bak&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; find_pid&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;&quot;&quot;按 /proc/&amp;lt;pid&amp;gt;/exe 指向找到 nsm 的 pid（不依赖 pidof 是否可用）。&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; p &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; glob&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;glob&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/proc/[0-9]*/exe&apos;&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        try&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            if&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;readlink&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; TARGET&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                return&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;p&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;split&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/&apos;&lt;/span&gt;&lt;span&gt;)[&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;])&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        except&lt;/span&gt;&lt;span&gt; OSError&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            pass&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; None&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; wait_pid&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; _ &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; range&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;WAIT_SECS&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        pid &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; find_pid&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; pid &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; not&lt;/span&gt;&lt;span&gt; None&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            return&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        time&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;sleep&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; None&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; &apos;&apos;&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt;%02x&lt;/span&gt;&lt;span&gt;&apos;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; ord&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;c&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; c &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; b&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; mem_rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lseek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SEEK_SET&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;read&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; mem_wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;lseek&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SEEK_SET&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;write&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; data&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; do_status&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; patched&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        n &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orig&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        cur &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mem_rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; patched&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            state &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;PATCHED&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        elif&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            state &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;original&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            state &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;UNKNOWN&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%06x&lt;/span&gt;&lt;span&gt; = &lt;/span&gt;&lt;span&gt;%-20s&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;]&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; rc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; do_restore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; not&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exists&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BACKUP&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ERROR: 找不到备份 &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;，无法还原&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; BACKUP&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; line &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BACKUP&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; orig &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; line&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;split&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mem_wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;decode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;hex&apos;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  restored &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mem_rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orig&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; do_patch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;):&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bk &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; patched&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; EDITS&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        n &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; len&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;orig&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; //&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        cur &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mem_rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        bk&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;append&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; %x&lt;/span&gt;&lt;span&gt; %s\n&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;strip&lt;/span&gt;&lt;span&gt;(),&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;span&gt;   # 备份一律记原始字节&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; patched&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  SKIP  &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%06x&lt;/span&gt;&lt;span&gt; 已经打过补丁&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        elif&lt;/span&gt;&lt;span&gt; cur &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            mem_wr&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; patched&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;decode&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;hex&apos;&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  PATCH &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%06x&lt;/span&gt;&lt;span&gt;  %s&lt;/span&gt;&lt;span&gt; -&amp;gt; &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; hx&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;mem_rd&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; n&lt;/span&gt;&lt;span&gt;))))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  WARN  &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; @0x&lt;/span&gt;&lt;span&gt;%06x&lt;/span&gt;&lt;span&gt; 未知内容 &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;（期望 &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;），已跳过&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;lab&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; addr&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; cur&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; orig&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    try&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        f &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BACKUP&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &apos;w&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;writelines&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;bk&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        f&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  备份已写入 &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; BACKUP&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    except&lt;/span&gt;&lt;span&gt; IOError&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  WARN 备份写入失败: &lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; e&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; rc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;def&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;span&gt;():&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    mode &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;patch&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; &apos;--restore&apos;&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mode &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;restore&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    elif&lt;/span&gt;&lt;span&gt; &apos;--status&apos;&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;argv&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        mode &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; &apos;status&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;=== patch-sfp+.py  mode=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt; ===&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; mode&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    pid &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; wait_pid&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; pid &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; None&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;ERROR: 等待 &lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;s 仍未找到 nsm 进程 (&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;span&gt;)&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;WAIT_SECS&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; TARGET&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        return&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;  nsm pid = &lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    fd &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;open&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;/proc/&lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;/mem&apos;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; pid&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;O_RDWR&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    try&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        if&lt;/span&gt;&lt;span&gt; mode &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;status&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; do_status&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        elif&lt;/span&gt;&lt;span&gt; mode &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;restore&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; do_restore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            rc &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; do_patch&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    finally&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;close&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fd&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if&lt;/span&gt;&lt;span&gt; rc &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;=== DONE ===&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        print&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;=== DONE (rc=&lt;/span&gt;&lt;span&gt;%d&lt;/span&gt;&lt;span&gt;，请检查上面的 WARN) ===&quot;&lt;/span&gt;&lt;span&gt; %&lt;/span&gt;&lt;span&gt; rc&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; rc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; __name__ &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &apos;__main__&apos;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;exit&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;main&lt;/span&gt;&lt;span&gt;())&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;10. 关于开头的问题&lt;a href=&quot;#10-关于开头的问题&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;10.1 为什么厂商要将这四个端口绑定到一个组内?&lt;a href=&quot;#101-为什么厂商要将这四个端口绑定到一个组内&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;芯片侧存在 &lt;strong&gt;PLL 域 (CMU)&lt;/strong&gt; 的概念 (&lt;code&gt;sys_tsingma_datapath_12g_is_pll_equal&lt;/code&gt;、&lt;code&gt;sys_tsingma_datapath_28g_is_pll_equal&lt;/code&gt;、&lt;code&gt;_sys_tsingma_datapath_12g_load_cmu_val&lt;/code&gt;), 按速率分 &lt;strong&gt;12G 域 (≤12.5G，容纳 1G/2.5G/10G)&lt;/strong&gt; 与 &lt;strong&gt;28G 域 (25G/50G)&lt;/strong&gt;.
但是博主手上的这台设备端口规格为 SFP+, 并非 SFP28. 因此也就不支持 25G/50G 速率, 也就不会出现 28G 时钟速率的情况. 厂家将其绑定为一个组归根结底还是避免速率调整导致的设备故障, 这种做法也可以理解. 但由于固件过于公版, 并没有针对每个设备做十分细致的调整, 也就导致了这台设备非必要的功能缺失.&lt;/p&gt;
&lt;h4&gt;10.2 为什么 &lt;code&gt;group-speed&lt;/code&gt; 没有设计 2.5Gbe 速率的下发实现?&lt;a href=&quot;#102-为什么-group-speed-没有设计-25gbe-速率的下发实现&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;关于这个疑问, 其实分析完之后也没法做出一个很准确的回答. 但分析过程中也确实从侧面获取到了一些厂家可能的意图.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;产品定位: SFP+ 是上联口, 而 2.5G 是接入侧的定位
整机是 48×2.5G 电口 + 4×10G + 2×40G:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;2.5Gbe 是接入侧的能力, 由 48 个电口的 PHY 提供;&lt;/li&gt;
&lt;li&gt;SFP+ 是上联 / 级联用途, 目标速率是 1G/10G.
在这种分工下, 让上联口跑 2.5Gbe 不是产品设计里的应用场景, 厂商自然不会把它做进上联专用的 group-speed.&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;2.5Gbe 在 SFP+ 上不是标准速率
SFP+ MSA 定义的是 1G / 10G. 2.5G 跑 SFP+ 属于非标准用法, 能用它的模块很少.
厂商为上联口提供非标准速率意味着: 额外的模块兼容性验证、DDM/CDR 行为的未知风险、以及售后支持成本.&lt;/li&gt;
&lt;li&gt;代码结构原因&lt;div&gt;&lt;/div&gt; vs 特化逻辑
这是最直接的工程解释:&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;每端口 speed 是全产品线共用的代码路径, 它的 token 表要覆盖所有 SKU 的所有口类型 (10M……400G), 所以 2G5 天然在里面;&lt;/li&gt;
&lt;li&gt;group-speed 是针对 &lt;em&gt;上联端口组&lt;/em&gt; 特化的逻辑, 厂家只枚举了该场景真正要用的速率 (default|1000|10G|25G).&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;厂家其实是有意关掉, 不是漏做
这是最有力的一条: &lt;code&gt;speed-mode (1-10G | 2G5-10G | 1-25G | 10-25G)&lt;/code&gt; 这个命令已经把 2G5-10G 写好了, 包括写 &lt;code&gt;EEPROM&lt;/code&gt;/&lt;code&gt;sysenv&lt;/code&gt;, 重启生效, &lt;code&gt;show speed-mode&lt;/code&gt; 全套. 但本板没有任何端口带上启用所需的标志, 导致该命令直接回 Do not support speed mode config!
也就是说: 能力是现成的, 开关是故意焊死的. 这不太像是忘了做, 而是更像&lt;strong&gt;做了但按板型分产品&lt;/strong&gt;或是&lt;strong&gt;客户配置关闭&lt;/strong&gt;.很可能是按订单 / SKU 分级的产品策略 &lt;em&gt;(要 2.5G 就得买对应型号)&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;总结&lt;a href=&quot;#总结&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本分并非专业人士, 如有错误或疏漏请指出! 感谢您的阅读.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/373/&quot;&gt;盛科 CTC 交换机逆向: 固件到 Root Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/127/&quot;&gt;H3C 交换机 Console 密码清除&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/363/&quot;&gt;OrangePi 3B 编译 UEFI 固件&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:逆向</category></item><item><title>自建 Debian 13 镜像源: ftpsync + Nginx</title><link>https://blog.nanami.tech/en/archives/382</link><guid isPermaLink="false">en:382</guid><description>前言
在某些企业中, 由于私有服务器有不联公网的要求, 但同时也需要更新相关软件包, 这时就需要自建软件镜像源. 而在某些 HomeLab 玩家中, 为了追求极致的速度和极低的延迟, 也会选择自建相关镜像源. 这篇文章将会记录博主自建 Debian 镜像源的全过程, 为有需要的人提供一些帮助.</description><pubDate>Sun, 20 Sep 2026 04:45:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在某些企业中, 由于私有服务器有不联公网的要求, 但同时也需要更新相关软件包, 这时就需要自建软件镜像源. 而在某些 HomeLab 玩家中, 为了追求极致的速度和极低的延迟, 也会选择自建相关镜像源. 这篇文章将会记录博主自建 Debian 镜像源的全过程, 为有需要的人提供一些帮助.&lt;/p&gt;
&lt;h2&gt;示例环境&lt;a href=&quot;#示例环境&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Mirror:~#&lt;/span&gt;&lt;span&gt; neowofetch&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       _,met$$$$$gg.&lt;/span&gt;&lt;span&gt;             root@Mirror&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,g$$$$$$$$$$$$$$$P.&lt;/span&gt;&lt;span&gt;          -----------&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ,g$$P&lt;/span&gt;&lt;span&gt;&quot;        &quot;&quot;&quot;&lt;/span&gt;&lt;span&gt;Y$$.&lt;/span&gt;&lt;span&gt;&quot;.        OS: Debian GNU/Linux 13.6 (trixie) x86_64 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; ,$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&apos;              &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$.        Host: KVM/QEMU (&lt;/span&gt;&lt;span&gt;Standard&lt;/span&gt;&lt;span&gt; PC (i440FX + PIIX, &lt;/span&gt;&lt;span&gt;1996&lt;/span&gt;&lt;span&gt;) pc-i440fx-11.0) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&apos;,$$P       ,ggs.     `$$b:      Kernel: 6.12.74+deb13+1-amd64 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;`d$$&apos;&lt;/span&gt;&lt;span&gt;     ,&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;&apos;   .    &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$       Uptime: 6 mins &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;      d$&apos;     ,    $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;       Packages: 450 (dpkg) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;:      &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.   -    ,d&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;&apos;       Shell: bash 5.2.37 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;;      Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;._   _,d&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&apos;         Terminal: /dev/pts/0 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.    &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;&apos;            CPU: Intel Xeon E5-2696 v4 (8) @ 2.1GHz &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; `&lt;/span&gt;&lt;span&gt;$$b&lt;/span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;-.__                 Memory: 0.32 GiB / 1.92 GiB (16%) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  `&lt;/span&gt;&lt;span&gt;Y$$&lt;/span&gt;&lt;span&gt;                           Network: Unknown &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   `&lt;/span&gt;&lt;span&gt;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.                         BIOS: SeaBIOS 0.0 (04/01/2014) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     `&lt;/span&gt;&lt;span&gt;$$b.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       `&lt;/span&gt;&lt;span&gt;Y$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.                                            &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          `&lt;/span&gt;&lt;span&gt;&quot;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;._                                        &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              `&lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;注意&lt;a href=&quot;#注意&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;搭建软件镜像源需要非常多的磁盘存储, 在操作之前请确认你有足够多的空间去存放软件源. Debian 相关软件源大小可以从 &lt;a href=&quot;https://www.debian.org/mirror/size&quot;&gt;这里&lt;/a&gt; 获取&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 前置工作&lt;a href=&quot;#1-前置工作&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;用于进行软件源同步的工具有非常多, 具体功能与特色可以参考下表&lt;/p&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;工具&lt;/th&gt;&lt;th&gt;核心特点&lt;/th&gt;&lt;th&gt;适用场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;apt-mirror&lt;/code&gt;&lt;/td&gt;&lt;td&gt;简单易用, 配置直观, 适合快速搭建完整镜像.&lt;/td&gt;&lt;td&gt;希望快速上手, 对功能要求不复杂的个人或小型内网环境.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;apt-mirror2&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;apt-mirror&lt;/code&gt; 的现代重写版, 使用 &lt;code&gt;Python&lt;/code&gt;/&lt;code&gt;asyncio&lt;/code&gt;, 性能功耗, 支持数据完整性检查和 GPG 签名校验, 能保证镜像完整不损坏.&lt;/td&gt;&lt;td&gt;追求更好性能和可靠性, 希望避免同步过程中产生损坏镜像的用户.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;debmirror&lt;/code&gt;&lt;/td&gt;&lt;td&gt;功能强大且灵活, 支持按架构, 发行版, 组件进行精细化同步. 支持 HTTP/HTTPS/FTP/rsync 多种传输方式.&lt;/td&gt;&lt;td&gt;需要精细控制同步内容, 或者网络环境需要特定协议的场景.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;aptly&lt;/code&gt;&lt;/td&gt;&lt;td&gt;企业级仓库管理工具. 除了镜像, 还支持快照, 合并, 发布等高级功能, 适合需要版本控制和 CI/CD 集成的环境.&lt;/td&gt;&lt;td&gt;企业级应用, 需要对仓库进行复杂管理和版本控制的场景.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;reprepro&lt;/code&gt;&lt;/td&gt;&lt;td&gt;轻量级的仓库构建和管理工具, 可以从本地 &lt;code&gt;.deb&lt;/code&gt; 文件池构建仓库, 也支持镜像功能, 配置灵活.&lt;/td&gt;&lt;td&gt;希望从本地软件包构建仓库, 或者需要进行更细粒度镜像配置的场景.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;rsync&lt;/code&gt;&lt;/td&gt;&lt;td&gt;最基础的同步工具, 直接镜像整个目录, 增量同步效率高.&lt;/td&gt;&lt;td&gt;对同步要求内容不高, 仅需简单, 完整地复制整个仓库目录的场景.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这里我们使用 &lt;code&gt;ftpsync&lt;/code&gt; 作为同步工具.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;首先我们需要安装 &lt;code&gt;ftpsync&lt;/code&gt; 同步镜像源, Web 服务器 &lt;code&gt;(nginx / apache)&lt;/code&gt; 确保能够被 HTTP 访问&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; ftpsync&lt;/span&gt;&lt;span&gt; nginx&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;创建一个专门用于同步镜像的用户, 这是官方推荐的安全做法&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;adduser&lt;/span&gt;&lt;span&gt; mirror&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;创建存储目录并配置权限, 用于存放所有镜像文件&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; path/to/mirrir&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chown&lt;/span&gt;&lt;span&gt; mirror:mirror&lt;/span&gt;&lt;span&gt; path/to/mirror&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. 配置同步&lt;a href=&quot;#2-配置同步&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建配置文件&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /etc/ftpsync&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/ftpsync/ftpsync.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;填入以下参数&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;########################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ftpsync.conf - Debian 13 (trixie) amd64 + arm64 镜像配置&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;########################################################################&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 基础信息 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 镜像主机名，用于生成 trace 文件&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MIRRORNAME&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(hostname -f)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 镜像存放的目标目录（必须为空或仅含 pool 数据）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;TO&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;/srv/mirrors/debian&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 日志与邮件（日志目录需提前创建）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;LOGDIR&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;/home/mirror/log&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MAILTO&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;&quot;&lt;/span&gt;&lt;span&gt;          # 留空则不发送邮件，改为查看日志&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 是否为叶子节点（不向下游推送）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;HUB&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;false&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 上游连接 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 选择一个支持 rsync 的上游镜像&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 国内推荐使用阿里云/腾讯云镜像，但需确认其提供 rsync 服务&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 这里以官方 ftp.debian.org 为例，实际请替换为你的上游&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RSYNC_HOST&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;ftp.debian.org&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RSYNC_PATH&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;debian&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 架构过滤 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 只同步 amd64 和 arm64，source 包含在内以便后续需要&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ARCH_INCLUDE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;amd64 arm64 source&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 发行版过滤 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 只同步 trixie（Debian 13）及其相关组件&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# DIST_INCLUDE 是 ftpsync 支持的过滤选项&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;DIST_INCLUDE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;trixie trixie-updates trixie-backports&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 日志详细程度 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 开启 FULLLOGS 才能看到 rsync 的详细传输进度&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;FULLLOGS&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- 安全删除限制 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 防止误删，设置最大删除数量&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MAX_DELETE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# ---- rsync 额外选项 ----&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# --info=progress2 用于显示整体进度（配合 FULLLOGS 使用）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RSYNC_EXTRA&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;--info=progress2&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果想设置同步多个镜像, 则需要在相同目录下按照 &lt;code&gt;ftpsync-&amp;lt;mirrorName&amp;gt;.conf&lt;/code&gt; 创建配置文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;执行同步命令测试配置&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ftpsync&lt;/span&gt;&lt;span&gt; sync:all&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果执行后没有立即报错, 正常开始同步, 则证明配置文件无误. 此时可以 ^C 然后继续进行后续配置&lt;/p&gt;
&lt;h3&gt;3. 配置 Web 服务器&lt;a href=&quot;#3-配置-web-服务器&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;创建 Nginx 配置文件&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/nginx/site-avaliable/mirrors&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;填入以下内容&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;server &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    listen 80;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    listen [&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;:]:&lt;/span&gt;&lt;span&gt;80&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    server_name &amp;lt;your_domain&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    root path/to/mirror;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    autoindex on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    autoindex_exact_size on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    autoindex_localtime on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    sendfile on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    tcp_nopush on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    tcp_nodelay on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    charset utf&lt;/span&gt;&lt;span&gt;-8&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    keepalive_timeout &lt;/span&gt;&lt;span&gt;65&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    access_log /var/log/nginx/mirrors.access.log;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    error_log /var/log/nginx/mirrors.error.log;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    location ~* /(dists|pool)/.*(InRelease|Release|Release.gpg|Packages|Sources)(\.gz|\.xz|\.bz&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;)?$ &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        expires 1h;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        add_header Cache-Control &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;public&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    location ~ /\. &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        deny all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        access_log off;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        log_not_found off;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;server_name&lt;/code&gt; 服务器名称. 填入您的域名即可
&lt;code&gt;root&lt;/code&gt; 网站根目录. 填写镜像同步目录即可
如果你的 URL 中包含 &lt;code&gt;debian&lt;/code&gt;, 则需要添加以下内容&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;  location /debian/ &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      alias path/to/mirror;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      autoindex on;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;将配置文件链接到 &lt;code&gt;sites-enabled&lt;/code&gt; 目录以启用&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ln&lt;/span&gt;&lt;span&gt; -s&lt;/span&gt;&lt;span&gt; /etc/nginx/sites-available/mirror-debian&lt;/span&gt;&lt;span&gt; /etc/nginx/sites-enabled/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;测试配置&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;nginx&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果输出没有报错, 则正常.
4. 重新加载 Nginx, 使其生效&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; reload&lt;/span&gt;&lt;span&gt; nginx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;配置相关权限, 使得 &lt;code&gt;www-data&lt;/code&gt; 也对镜像目录有可读可执行权限&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; -R&lt;/span&gt;&lt;span&gt; a+rX&lt;/span&gt;&lt;span&gt; /mnt/Mirror/mirrors/debian&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;4. 创建定时任务&lt;a href=&quot;#4-创建定时任务&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;安装 &lt;code&gt;crontab&lt;/code&gt;, &lt;code&gt;flock&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; cron&lt;/span&gt;&lt;span&gt; flock&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;添加互斥锁目录, 编辑权限和配置文件&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /var/run/ftpsync&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chown&lt;/span&gt;&lt;span&gt; mirror:mirror&lt;/span&gt;&lt;span&gt; /var/run/ftpsync&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;crontab&lt;/span&gt;&lt;span&gt; -u&lt;/span&gt;&lt;span&gt; mirror&lt;/span&gt;&lt;span&gt; -e&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;添加行 &lt;code&gt;0 3 * * * flock -xn /var/run/ftpsync/ftpsync-debian.lock ftpsync sync:all&lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;含义为每天凌晨三点自动运行同步
如果想设置为每隔 n 小时同步一次, 则可以添加 &lt;code&gt;0 */n * * * flock -xn /var/run/ftpsync/ftpsync-debian.lock ftpsync sync:all&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;保存并退出&lt;/p&gt;
&lt;h3&gt;5. 进行首次同步&lt;a href=&quot;#5-进行首次同步&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;运行 &lt;code&gt;ftpsync sync:all&lt;/code&gt; 进行首次同步&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 单次全量同步时间较长, 建议使用 &lt;code&gt;screen&lt;/code&gt; 等类似工具创建虚拟显示器&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;等待同步完成后, 即可在客户机替换软件源&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;6. 测试&lt;a href=&quot;#6-测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;替换客户机软件源, 使用 &lt;code&gt;apt update &amp;amp;&amp;amp; apt upgrade&lt;/code&gt; 进行测试.&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@test:~#&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; upgrade&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Get:1&lt;/span&gt;&lt;span&gt; http://mirrors.vm.homelab/debian-security&lt;/span&gt;&lt;span&gt; trixie-security&lt;/span&gt;&lt;span&gt; InRelease&lt;/span&gt;&lt;span&gt; [43.4 &lt;/span&gt;&lt;span&gt;kB]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Hit:2&lt;/span&gt;&lt;span&gt; http://mirrors.vm.homelab/debian&lt;/span&gt;&lt;span&gt; trixie&lt;/span&gt;&lt;span&gt; InRelease&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Hit:3&lt;/span&gt;&lt;span&gt; http://mirrors.vm.homelab/debian&lt;/span&gt;&lt;span&gt; trixie-updates&lt;/span&gt;&lt;span&gt; InRelease&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Fetched&lt;/span&gt;&lt;span&gt; 43.4&lt;/span&gt;&lt;span&gt; kB&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; 0s&lt;/span&gt;&lt;span&gt; (134 &lt;/span&gt;&lt;span&gt;kB/s&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;All&lt;/span&gt;&lt;span&gt; packages&lt;/span&gt;&lt;span&gt; are&lt;/span&gt;&lt;span&gt; up&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; date.&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Summary:&lt;/span&gt;&lt;span&gt;                        &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Upgrading:&lt;/span&gt;&lt;span&gt; 0,&lt;/span&gt;&lt;span&gt; Installing:&lt;/span&gt;&lt;span&gt; 0,&lt;/span&gt;&lt;span&gt; Removing:&lt;/span&gt;&lt;span&gt; 0,&lt;/span&gt;&lt;span&gt; Not&lt;/span&gt;&lt;span&gt; Upgrading:&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果没有报错且速度很快, 那就表明没有问题. 如果有条件的话, 还可以在内网 DNS Server 做单独配置, 给予一个内网可用的专有域名. 至此, 镜像源的搭建就结束了.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业人士, 如有错误请指出! 感谢您的阅读.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/297/&quot;&gt;iVentoy 部署 PXE 网络启动服务器&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/369/&quot;&gt;自建私有 VoIP: FreePBX 电话系统&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/134/&quot;&gt;Docker 下 umami prisma migrate 报错修复&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:Linux 运维</category></item><item><title>自建私有 VoIP: FreePBX 电话系统</title><link>https://blog.nanami.tech/en/archives/369</link><guid isPermaLink="false">en:369</guid><description>前言
在这个技术日益高速发展的时代, 科技单位对我们的监控也变得越来越变本加厉. 信息安全成为了所有人都应该注重的因素. 电话是我们所有人日常生活中都需要使用的功能. 众所周知, 普通电话是可以很轻易地被运营商监听监控的, 所以在谈论一些要事时, 不适宜用普通电话进行交谈.</description><pubDate>Thu, 13 Aug 2026 10:39:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在这个技术日益高速发展的时代, 科技单位对我们的监控也变得越来越变本加厉. 信息安全成为了所有人都应该注重的因素. 电话是我们所有人日常生活中都需要使用的功能. 众所周知, 普通电话是可以很轻易地被运营商监听监控的, 所以在谈论一些要事时, 不适宜用普通电话进行交谈. 为了使自己的电话隐私得到更严密的保护, 本篇文章将会记录博主搭建私有 VoIP 电话系统的全过程, 供有需要的读者进行参考.&lt;/p&gt;
&lt;h2&gt;什么是 VoIP?&lt;a href=&quot;#什么是-voip&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;VoIP (Voice over IP)&lt;/code&gt;, 是一种语音通话协议. 它将实时音频流封装到 IP 协议中, 通过互联网基础设施进行传输. 我们可以对其数据包进行一定程度的加密, 从而达到保护隐私的目的.&lt;/p&gt;
&lt;h2&gt;搭建规划&lt;a href=&quot;#搭建规划&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主建立了一张可以在家中, 学校中和一些朋友的网络中互相通信的 VPN 网络. 这套 VoIP 系统需要承载 VPN 内电话流量, 但同时不可以被外网访问. 因此防火墙需要指定在 VPN 内网网段和刚才提到的这些网络的内网网段.&lt;/p&gt;
&lt;h2&gt;配置需求&lt;a href=&quot;#配置需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可以安装 Debian 12 的服务器 / KVM &lt;em&gt;(客户机至少需要 2G RAM, 20G 硬盘)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;VPN 网络 &lt;em&gt;(可选)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;免责声明&lt;a href=&quot;#免责声明&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;本篇文章仅作技术交流, 请勿使用相关技术进行违规违法行为. 博主已尽到相关警告义务, 所有由读者造成的相关后果与本文, 博主, 本站均无关!&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 安装 &lt;code&gt;FreePBX&lt;/code&gt;&lt;a href=&quot;#1-安装-freepbx&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Q. 什么是 FreePBX?
A. FreePBX 是一套开源免费的, 基于 &lt;code&gt;Asterisk&lt;/code&gt; 平台的 IP 电话系统管理工具. 具有用户友好的 WebUI 页面. 同时是全球部署最广泛的开源商业通信系统之一, 拥有数百万活跃安装量. 其拥有庞大的开发者群体和社区, 提供丰富的文档支持. 同时功能可根据需求进行模块化定制和扩展, 十分方便.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;1.1 使用 ISO 映像安装&lt;a href=&quot;#11-使用-iso-映像安装&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://www.freepbx.org/downloads/&quot;&gt;FreePBX 下载页&lt;/a&gt; 下载最新版的 FreePBX 安装映像&lt;/li&gt;
&lt;li&gt;启动映像, 选择第一项直接安装. 选择后会让你花 30s 的时间阅读一份帮助文档, 随后就可以进入安装页面. 整个安装过程是全自动的, 并不需要手动操作什么, 等待安装完成即可.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1.2 手动安装&lt;a href=&quot;#12-手动安装&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;使用这种方法需要你当前的操作系统为 &lt;code&gt;Debian 12 (bookworm)&lt;/code&gt;. 如果你和我一样使用 Proxmox VE 作为宿主系统, 那么我这里推荐使用 &lt;a href=&quot;https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2&quot;&gt;Debian 12 Cloud Init&lt;/a&gt; 映像作为安装映像&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用该指令执行安装脚本&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;wget&lt;/span&gt;&lt;span&gt; https://github.com/FreePBX/sng_freepbx_debian_install/raw/master/sng_freepbx_debian_install.sh&lt;/span&gt;&lt;span&gt; -O&lt;/span&gt;&lt;span&gt; /tmp/sng_freepbx_debian_install.sh&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; bash&lt;/span&gt;&lt;span&gt; /tmp/sng_freepbx_debian_install.sh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;执行后, 该脚本会自动安装所有所需要的软件包, &lt;strong&gt;整个过程大约需要半小时&lt;/strong&gt;, 耐心等待即可.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可能需要科学上网&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 配置 FreePBX&lt;a href=&quot;#2-配置-freepbx&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;2.1 初始化&lt;a href=&quot;#21-初始化&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后, 直接访问服务器 IP 地址, 端口为默认 80 端口, 打开 WebUI.&lt;/li&gt;
&lt;li&gt;按照要求填写管理员用户名, 密码, 邮箱地址等, 然后完成设置.&lt;/li&gt;
&lt;li&gt;进入 WebUI 后登录, 会自动跳转到服务器初始化设置页面. 单击 &lt;code&gt;Active&lt;/code&gt; 激活服务器.&lt;/li&gt;
&lt;li&gt;这里会让你创建 Portal Account &lt;em&gt;(门户账户)&lt;/em&gt;, 输入邮箱后服务器会自动检查可用性.&lt;/li&gt;
&lt;li&gt;在这之后按照 WebUI 指示完成全部配置即可.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2.2 基础配置&lt;a href=&quot;#22-基础配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;h5&gt;2.2.1 防火墙&lt;a href=&quot;#221-防火墙&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;进入 &lt;code&gt;Connectivity&lt;/code&gt; -&amp;gt; &lt;code&gt;Firewall&lt;/code&gt; 页面, 设置防火墙&lt;/li&gt;
&lt;li&gt;选择 &lt;code&gt;Interfaces&lt;/code&gt; 选项卡, 进入接口设置.
这里会列举出你的服务器上当前可用的所有网络接口. 然后在 &lt;code&gt;Default Zone&lt;/code&gt; 中配置默认区域.&lt;/li&gt;
&lt;/ul&gt;









































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Default Zone&lt;/th&gt;&lt;th&gt;名称&lt;/th&gt;&lt;th&gt;简介&lt;/th&gt;&lt;th&gt;安全性&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Internet&lt;/code&gt;&lt;/td&gt;&lt;td&gt;互联网&lt;/td&gt;&lt;td&gt;允许网络上的所有 SIP 客户端接入, 黑名单除外&lt;/td&gt;&lt;td&gt;&lt;strong&gt;最低&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Local&lt;/code&gt;&lt;/td&gt;&lt;td&gt;本地&lt;/td&gt;&lt;td&gt;仅允许本地受信任的通讯接入&lt;/td&gt;&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Other&lt;/code&gt;&lt;/td&gt;&lt;td&gt;其他&lt;/td&gt;&lt;td&gt;仅允许其他类型通讯接入&lt;/td&gt;&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Reject&lt;/code&gt;&lt;/td&gt;&lt;td&gt;拒绝&lt;/td&gt;&lt;td&gt;拒绝所有通讯接入&lt;/td&gt;&lt;td&gt;&lt;strong&gt;最高&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Trusted&lt;/code&gt;&lt;/td&gt;&lt;td&gt;受信任&lt;/td&gt;&lt;td&gt;仅允许受信任的通讯接入&lt;/td&gt;&lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;这里按需选择接口防火墙配置. 在本文的场景中, 选择 &lt;code&gt;Local&lt;/code&gt; 即可.
配置完成后, 单击右下角 &lt;code&gt;Update Interfaces&lt;/code&gt; 即可更新防火墙配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;来到 &lt;code&gt;Networks&lt;/code&gt; 选项卡, 配置受信任的网段.
服务器会自动将本地网段和你用于访问 WebUI 的设备地址加入受信任域, 这里我们可以手动添加. &lt;strong&gt;输入的 IP 地址段须符合 &lt;code&gt;CIDR&lt;/code&gt; 规则 &lt;em&gt;(例如 &lt;code&gt;192.168.1.0/24&lt;/code&gt;, &lt;code&gt;10.0.0.0/8&lt;/code&gt; 等)&lt;/em&gt;&lt;/strong&gt;
输入完成后单击右下角的 &lt;code&gt;Save&lt;/code&gt; 即可&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;2.2.2 SIP 中继&lt;a href=&quot;#222-sip-中继&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;如果你需要将你的系统接入外部 SIP 系统, 来访问其他全球 VoIP 服务器, 则需要配置中继. 在本文的需求中是不需要的. 但这里为了使得教程更加通用, 还是介绍一下如何配置.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首先向一个 SIP 服务提供商 (如 &lt;code&gt;VoIP.ms&lt;/code&gt;, &lt;code&gt;Twilio&lt;/code&gt; 等) 购买服务&lt;/li&gt;
&lt;li&gt;进入 &lt;code&gt;Connectivity&lt;/code&gt; -&amp;gt; &lt;code&gt;Trunks&lt;/code&gt; 点击 &lt;code&gt;Add Trunk&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;根据 SIP 提供商给出的相关信息, 选择相应的类型, 填入数据后保存即可&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;2.2.3 创建分机 (添加用户)&lt;a href=&quot;#223-创建分机-添加用户&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;进入 &lt;code&gt;Connectivity&lt;/code&gt; -&amp;gt; &lt;code&gt;Extensions&lt;/code&gt; 点击 &lt;code&gt;Quick Create Extension&lt;/code&gt; 快速添加分机, 按照指示填写参数&lt;/li&gt;
&lt;/ul&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;参数名称&lt;/th&gt;&lt;th&gt;含义&lt;/th&gt;&lt;th&gt;详解&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Type&lt;/code&gt;&lt;/td&gt;&lt;td&gt;分机类型&lt;/td&gt;&lt;td&gt;这里直接选择 &lt;code&gt;chan_pjsip&lt;/code&gt; 即可. 这是 FreePBX 目前推荐且默认的现代 SIP 协议栈, 兼容性更好且支持 IPv6 和更强的加密&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Extension Number&lt;/code&gt;&lt;/td&gt;&lt;td&gt;分机号码&lt;/td&gt;&lt;td&gt;系统内外呼时的号码&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Display Name&lt;/code&gt;&lt;/td&gt;&lt;td&gt;显示名称&lt;/td&gt;&lt;td&gt;该分机来电时显示的名称&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Outbound Caller ID&lt;/code&gt;&lt;/td&gt;&lt;td&gt;外呼主叫号码&lt;/td&gt;&lt;td&gt;拨打外线电话 (其他 SIP 中继号码) 时, 对方看到的来电号码&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Email Address&lt;/code&gt;&lt;/td&gt;&lt;td&gt;电子邮件&lt;/td&gt;&lt;td&gt;该分机关联的邮箱&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;参考配置
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/369-1.png&quot; alt=&quot;FreePBX 分机配置参考&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;FreePBX 分机配置参考&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;填写完单击下一步, 然后继续按照要求填写&lt;/li&gt;
&lt;/ul&gt;








































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;参数名称&lt;/th&gt;&lt;th&gt;含义&lt;/th&gt;&lt;th&gt;详解&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Enable Find Me/Follow Me&lt;/code&gt;&lt;/td&gt;&lt;td&gt;启用 “查找我”/“跟踪我”&lt;/td&gt;&lt;td&gt;多终端联动功能. 当有人拨打你的号码时, 系统可以同时或依次呼叫你的其他分机&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;ParkingLot&lt;/code&gt;&lt;/td&gt;&lt;td&gt;驻留区域&lt;/td&gt;&lt;td&gt;通话驻留是指可以将你正在进行的通话暂存到系统的某个编号, 然后去另一部分机上取回继续通话&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Create User Manager User&lt;/code&gt;&lt;/td&gt;&lt;td&gt;创建用户管理用户&lt;/td&gt;&lt;td&gt;是否在 FreePBX 的用户控制面板中创建一个 Web 登录账号&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;User Manager Groups&lt;/code&gt;&lt;/td&gt;&lt;td&gt;用户管理分组&lt;/td&gt;&lt;td&gt;给这个用户分配的权限组&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Enable Voicemail&lt;/code&gt;&lt;/td&gt;&lt;td&gt;启用语音信箱&lt;/td&gt;&lt;td&gt;当无人接听或忙线时, 可以给你留言&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Voicemail PIN&lt;/code&gt;&lt;/td&gt;&lt;td&gt;语音信箱密码&lt;/td&gt;&lt;td&gt;用电话拨号盘接听语音留言时, 需要输入 PIN 码&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;参考配置
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/369-2.png&quot; alt=&quot;FreePBX 语音信箱参考配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;FreePBX 语音信箱参考配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后单击 &lt;code&gt;Finish&lt;/code&gt;. 然后单击用户右侧的编辑按钮, 进入编辑页面&lt;/li&gt;
&lt;li&gt;找到用户密码, 将鼠标指针移至编辑框内就会显示密码, 复制并记录. 如需修改也可以现在修改.&lt;/li&gt;
&lt;li&gt;全部配置完成后, 返回用户列表页面, 单击右上方红色 &lt;code&gt;Apply Config&lt;/code&gt; 按钮提交配置.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 配置客户端&lt;a href=&quot;#3-配置客户端&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;SIP 分机拨号客户端有很多种, 这里我们使用 ZoiPer 作为演示. 安卓端可以直接在 Play 商店中下载, 桌面端请移步官网.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开软件, 在 &lt;code&gt;Username @ PBX/VoIP provider&lt;/code&gt; 一栏中, 按照 &lt;strong&gt;分机号 @ IP 地址&lt;/strong&gt; 的格式填写&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;例如 &lt;code&gt;10001@192.168.1.24&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;密码填写刚才记录的用户密码, 然后点击 &lt;code&gt;Login&lt;/code&gt; 登录.&lt;/li&gt;
&lt;li&gt;接下来两个页面都直接下一步即可, 随后会进入一个测试连接可用性的页面. 博主的环境中测试 &lt;code&gt;SIP UDP&lt;/code&gt; 是可用的.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意: 如果你正在使用 HTTP Proxy 或透明代理, 可能会无法使用! 请暂时关闭您的代理&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;进入主页面后, 就可以直接尝试拨打电话了.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至此, 服务端和客户端的基础配置就完成了. FreePBX 的功能十分强大, 十分推荐自行去挖掘一下其他有用的功能. 本文只做基础配置讲解, 暂且不提其他配置. 如果后面有机会, 还会再出一篇进阶配置的文章.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人并非专业人员, 如有错误会疏漏请直接指出, 感谢您的阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/382/&quot;&gt;自建 Debian 13 镜像源: ftpsync + Nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/80/&quot;&gt;家庭数据中心设备与业务介绍&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:Linux 运维</category></item><item><title>OrangePi 3B 编译 UEFI 固件</title><link>https://blog.nanami.tech/en/archives/363</link><guid isPermaLink="false">en:363</guid><description>前言
就在前几天 (2026-08-05), Proxmox VE 官方宣布了对 Arm64 平台的支持. 这使得我想起了实验室学长们送我的那块 OrangePi 3B 开发板, 索性尝试使用这块开发板来启动 Proxmox VE 原生的 iso 映像文件. 由于 Proxmox VE</description><pubDate>Sun, 09 Aug 2026 14:15:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;就在前几天 (2026-08-05), &lt;a href=&quot;https://www.proxmox.com/en/about/company-details/press-releases/proxmox-virtual-environment-launches-official-arm64-support&quot;&gt;Proxmox VE 官方宣布了对 Arm64 平台的支持&lt;/a&gt;. 这使得我想起了实验室学长们送我的那块 OrangePi 3B 开发板, 索性尝试使用这块开发板来启动 Proxmox VE 原生的 iso 映像文件. 由于 Proxmox VE 官方提供的映像文件是需要使用 efi 启动的, 查了一圈发现没有专门给 OrangePi 3B 编译的 UEFI 固件, 索性自己尝试编译&lt;/p&gt;
&lt;h2&gt;本文操作环境&lt;a href=&quot;#本文操作环境&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;       _,met$$$$$gg.&lt;/span&gt;&lt;span&gt;             nanami114@VM-Main&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,g$$$$$$$$$$$$$$$P.&lt;/span&gt;&lt;span&gt;          -----------------&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ,g$$P&lt;/span&gt;&lt;span&gt;&quot;        &quot;&quot;&quot;&lt;/span&gt;&lt;span&gt;Y$$.&lt;/span&gt;&lt;span&gt;&quot;.        OS: Debian GNU/Linux 13.4 (trixie) x86_64 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; ,$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&apos;              &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$.        Host: KVM/QEMU (&lt;/span&gt;&lt;span&gt;Standard&lt;/span&gt;&lt;span&gt; PC (i440FX + PIIX, &lt;/span&gt;&lt;span&gt;1996&lt;/span&gt;&lt;span&gt;) pc-i440fx-11.0) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&apos;,$$P       ,ggs.     `$$b:      Kernel: 6.12.74+deb13+1-amd64 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;`d$$&apos;&lt;/span&gt;&lt;span&gt;     ,&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;&apos;   .    &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$       Uptime: 29 days, 3 hours, 15 mins &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;      d$&apos;     ,    $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;       Packages: 3 (npm), 1526 (dpkg) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;:      &lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.   -    ,d&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;&apos;       Shell: bash 5.2.37 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; $&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;;      Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;._   _,d&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&apos;         Resolution: 1280x800 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.    &lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;&apos;            Terminal: /dev/pts/1 &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; `&lt;/span&gt;&lt;span&gt;$$b&lt;/span&gt;&lt;span&gt;      &quot;&lt;/span&gt;&lt;span&gt;-.__                 CPU: Intel Xeon E5-2696 v4 (44) @ 2.1GHz &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  `&lt;/span&gt;&lt;span&gt;Y$$&lt;/span&gt;&lt;span&gt;                           GPU: Vendor &lt;/span&gt;&lt;span&gt;1234&lt;/span&gt;&lt;span&gt; Device &lt;/span&gt;&lt;span&gt;1111&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   `&lt;/span&gt;&lt;span&gt;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;.                         Memory: 20.74 GiB / 31.33 GiB (66%) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;     `&lt;/span&gt;&lt;span&gt;$$b.&lt;/span&gt;&lt;span&gt;                       Network: Unknown &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       `&lt;/span&gt;&lt;span&gt;Y$&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;.                    BIOS: SeaBIOS 0.0 (04/01/2014) &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          `&lt;/span&gt;&lt;span&gt;&quot;Y&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;b&lt;/span&gt;&lt;span&gt;._&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              `&lt;/span&gt;&lt;span&gt;&quot;&quot;&quot;                                       &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                                                         &lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 编译 UEFI&lt;a href=&quot;#1-编译-uefi&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;1.1 准备材料&lt;a href=&quot;#11-准备材料&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在 GitHub 中有一个叫做 &lt;a href=&quot;https://github.com/jaredmcneill/quartz64_uefi&quot;&gt;quartz64_uefi&lt;/a&gt; 的项目专门给 &lt;code&gt;RK356X&lt;/code&gt; 的平台适配了 UEFI, 所以我们可以从这里入手. 首先 clone 该仓库&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; clone&lt;/span&gt;&lt;span&gt; https://github.com/jaredmcneill/quartz64_uefi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;查看项目结构, 发现项目中已经包含了专门为 Orange Pi 3B 的 platform, device tree, drivers 等, 并且 &lt;code&gt;build.sh&lt;/code&gt; 中也有适用于 OrangePi 3B 的构建流程. 所以这里可以尝试直接构建
&lt;figure&gt;&lt;img src=&quot;/images/363-1.png&quot; alt=&quot;quartz64_uefi 项目中的 OrangePi 3B 平台目录结构&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;quartz64_uefi 项目中的 OrangePi 3B 平台目录结构&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; board &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; ${RKUEFIBOARDS}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        case&lt;/span&gt;&lt;span&gt; ${board} &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        QUARTZ64&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Pine64&lt;/span&gt;&lt;span&gt; Quartz64&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; Quartz64&lt;/span&gt;&lt;span&gt; rk3566-quartz64-a&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        SOQUARTZ&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Pine64&lt;/span&gt;&lt;span&gt; SOQuartz&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; SOQuartz&lt;/span&gt;&lt;span&gt; rk3566-soquartz-cm4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ROC-RK3566-PC&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Firefly&lt;/span&gt;&lt;span&gt; ROC-RK3566-PC&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; ROC-RK3566-PC&lt;/span&gt;&lt;span&gt; rk3566-roc-pc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ROC-RK3568-PC&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Firefly&lt;/span&gt;&lt;span&gt; ROC-RK3568-PC&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; ROC-RK3568-PC&lt;/span&gt;&lt;span&gt; rk3568-firefly-roc-pc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# OrangePi 3B Here...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ORANGEPI3B&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; OrangePi&lt;/span&gt;&lt;span&gt; OrangePi3B&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; OrangePi3B&lt;/span&gt;&lt;span&gt; rk3566-orangepi-3b&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        PINETAB2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Pine64&lt;/span&gt;&lt;span&gt; PineTab2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; PineTab2&lt;/span&gt;&lt;span&gt; rk3566-pinetab2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ZERO-3W&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; Radxa&lt;/span&gt;&lt;span&gt; Zero-3W&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; Zero-3W&lt;/span&gt;&lt;span&gt; rk3566-radxa-zero-3w&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ODROID-M1S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_uefi&lt;/span&gt;&lt;span&gt; HardKernel&lt;/span&gt;&lt;span&gt; Odroid-M1S&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                build_fit&lt;/span&gt;&lt;span&gt; Odroid-M1S&lt;/span&gt;&lt;span&gt; rk3566-hardkernel-odroid-m1s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        *)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                echo&lt;/span&gt;&lt;span&gt; &quot;Unknown board &lt;/span&gt;&lt;span&gt;${board}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                exit&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                ;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        esac&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;1.2 检查环境&lt;a href=&quot;#12-检查环境&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;检查 Git 子模块状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; submodule&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果你当前所处的目录属主与当前执行的用户不一致, 则 Git 会报错 &lt;code&gt;dubious ownership&lt;/code&gt;, 此时执行这条指令添加信任&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; config&lt;/span&gt;&lt;span&gt; --global&lt;/span&gt;&lt;span&gt; --add&lt;/span&gt;&lt;span&gt; safe.directory&lt;/span&gt;&lt;span&gt; path/to/quartz64_uefi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;检查编译工具链
由于博主这里是在 &lt;code&gt;amd64&lt;/code&gt; 架构的设备上去编译 &lt;code&gt;arm64&lt;/code&gt; 的固件, 故这里需要配置交叉编译工具链.
我们从官方 CI 配置文件中提取依赖清单并安装&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; .github/workflows/build.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从这份配置文件中我们可以得到官方构建所需要的所有依赖, 分别为 &lt;code&gt;gcc-aarch64-linux-gnu&lt;/code&gt; &lt;code&gt;iasl&lt;/code&gt; &lt;code&gt;device-tree-compiler&lt;/code&gt; &lt;code&gt;python3-pyelftools&lt;/code&gt; &lt;code&gt;uuid-dev&lt;/code&gt;. 这里我们直接安装&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; --no-install-recommends&lt;/span&gt;&lt;span&gt; gcc-aarch64-linux-gnu&lt;/span&gt;&lt;span&gt; iasl&lt;/span&gt;&lt;span&gt; device-tree-compiler&lt;/span&gt;&lt;span&gt; python3-pyelftools&lt;/span&gt;&lt;span&gt; uuid-dev&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;检查 &lt;code&gt;edk2-rockchip&lt;/code&gt; 目录性质&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; -C&lt;/span&gt;&lt;span&gt; ed2k-rockchip&lt;/span&gt;&lt;span&gt; rev-parse&lt;/span&gt;&lt;span&gt; HEAD&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ls&lt;/span&gt;&lt;span&gt; edk2-rockchip/.git&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; ls-files&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; edk2-rockchip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;执行完后我们可以发现, 项目里 &lt;code&gt;edk2-rockchip/&lt;/code&gt; 和 &lt;code&gt;edk2-rockchip-non-osi/rkbin/&lt;/code&gt; 是 platform 代码和 Rockchip 官方 vendor 组件 (DDR 初始化固件, &lt;code&gt;BL31&lt;/code&gt;, &lt;code&gt;OP-TEE&lt;/code&gt;, &lt;code&gt;boot_merger/ddrbin_tool&lt;/code&gt; 工具). 我们需要确认它们是 submodule 还是直接打进 git 的:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.git 文件不存在, 同时 &lt;code&gt;git ls-files&lt;/code&gt; 显示 &lt;code&gt;234&lt;/code&gt; 个文件被直接跟踪. 因此得出它们是 vendored 进主仓库的, 我们只需要克隆主仓库就齐了.&lt;/li&gt;
&lt;li&gt;只有 &lt;code&gt;edk2&lt;/code&gt; 是真正的 submodule, 因此只有 &lt;code&gt;edk2&lt;/code&gt; 需要单独初始化.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1.3 初始化编译环境&lt;a href=&quot;#13-初始化编译环境&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;这里我们更新并初始化所有 submodule&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;git&lt;/span&gt;&lt;span&gt; submodule&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;span&gt; --init&lt;/span&gt;&lt;span&gt; --recursive&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--rescursive&lt;/code&gt; 的作用是连带嵌套 submodule 一起克隆 edk2 自己还有 &lt;code&gt;cmocka&lt;/code&gt;/&lt;code&gt;googletest&lt;/code&gt;/&lt;code&gt;subhook&lt;/code&gt; 等测试框架子模块&lt;/li&gt;
&lt;li&gt;edk2 是一个 200MB+ 的大仓库, 这里更新需要拥有一个稳定的网络环境.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4&gt;1.4 尝试编译&lt;a href=&quot;#14-尝试编译&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;使用 make 工具启动构建&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;make&lt;/span&gt;&lt;span&gt; BOARDS=ORANGEPI3B&lt;/span&gt;&lt;span&gt; uefi&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;这里通常只需要等待几分钟, 如果编译时间过长请检查之前的动作有没有问题&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;编译完成后, 使用 make 编译一个可烧录进 SD 卡的映像文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;make&lt;/span&gt;&lt;span&gt; BOARDS=ORANGEPI3B&lt;/span&gt;&lt;span&gt; sdcard&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;这里需要提前安装 &lt;code&gt;parted&lt;/code&gt;, 否则会报错&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;编译完成后我们会得到一份 &lt;code&gt;ORANGEPI3B_EFI.img&lt;/code&gt; 文件, 这份文件可以直接烧录进 SD 卡尝试启动.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 启动 UEFI&lt;a href=&quot;#2-启动-uefi&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;2.1 烧录&lt;a href=&quot;#21-烧录&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;使用 &lt;a href=&quot;https://sourceforge.net/projects/win32diskimager/&quot;&gt;Win32DiskImager&lt;/a&gt; 将 &lt;code&gt;ORANGEPI3B_EFI.img&lt;/code&gt; 烧录至 SD 卡即可.&lt;/p&gt;
&lt;h4&gt;2.2 启动&lt;a href=&quot;#22-启动&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;重启之后会看到 Orange Pi 的 Logo, 还有 tianocore 项目的文字. 如果没有插入任何启动设备, 则会自动进入 BIOS.
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/363-2.png&quot; alt=&quot;OrangePi 3B 启动后进入 UEFI 设置界面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;OrangePi 3B 启动后进入 UEFI 设置界面&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;据了解, 在以前的版本中, 只有 USB3.0 处于可用状态. 但这里博主编译的版本, 四个 USB-A 接口都处于可用状态.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;2.3 烧录系统&lt;a href=&quot;#23-烧录系统&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;这里可以使用 UltraISO 之类的软件, 将可启动映像烧录至 U 盘等存储介质中, 然后直接上电启动, UEFI 会自动引导到您的安装介质.
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/363-3.png&quot; alt=&quot;使用镜像工具将 UEFI 固件烧录到 SD 卡&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;使用镜像工具将 UEFI 固件烧录到 SD 卡&lt;/figcaption&gt;&lt;/figure&gt;
至此, 整个 UEFI 编译及烧录过程就结束了.&lt;p&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人并非专业人士, 如有错误或疏漏请指出, 谢谢!&lt;/p&gt;
&lt;h2&gt;附件&lt;a href=&quot;#附件&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.nanami.tech/usr/uploads/2026/08/2932782880.zip&quot;&gt;ORANGEPI3B_EFI.zip&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/373/&quot;&gt;盛科 CTC 交换机逆向: 固件到 Root Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/387/&quot;&gt;盛科 CTC7132 逆向: 解锁 SFP+ 2.5G&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:编程开发</category></item><item><title>FakeMesh + 802.11kvr 全屋 WiFi 漫游</title><link>https://blog.nanami.tech/en/archives/344</link><guid isPermaLink="false">en:344</guid><description>前言
博主最近在思考如何优化自己的家庭网络环境时, 突然想到对家里的 WiFi 进行一个优化. 由于博主自己是一个人使用一台 AP 的, 所以对 WiFi 信号一直都觉得挺好的. 但是最近家里人和博主反映说家里的 WiFi 信号不是很好, 且走到某个房间里时就基本没信号了.</description><pubDate>Mon, 27 Jul 2026 14:06:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主最近在思考如何优化自己的家庭网络环境时, 突然想到对家里的 WiFi 进行一个优化. 由于博主自己是一个人使用一台 AP 的, 所以对 WiFi 信号一直都觉得挺好的. 但是最近家里人和博主反映说家里的 WiFi 信号不是很好, 且走到某个房间里时就基本没信号了. 博主自己使用的是一台小米 AX3600, 但是家里其他人使用的却是一台很普通的 WiFi5 路由器. 所以博主打算给全屋 WiFi 进行一个更新.&lt;/p&gt;
&lt;h2&gt;现状&lt;a href=&quot;#现状&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;目前的 WiFi 环境是这样的: 博主自己使用 AX3600 拥有一个单独的 SSID, 发射功率和穿墙性能都还可以. 家里人使用的一台 ASUS WiFi5 路由器的功率和穿墙性能都不太行. 对于博主当前家里的这个户型来说很不友好.&lt;/p&gt;
&lt;h2&gt;优化思路&lt;a href=&quot;#优化思路&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;目前打算购置两台能刷 OpenWrt 软路由系统的硬路由, 然后配置 &lt;code&gt;FakeMesh&lt;/code&gt;, 统一由主路由管理 SSID 和密码之类的配置. 然后两台路由器运行 &lt;code&gt;802.11kvr&lt;/code&gt; &lt;em&gt;(WiFi 漫游)&lt;/em&gt;, 以此来实现自动分配信号更好的 AP. 在网上看了一圈, 发现小米 AX1800 刚好能满足这个需求, 且价格很便宜 (目前二手平台 40 左右就能买到), 所以买了两台 AX3600, 刷了 X-WRT, 准备来做这么一个配置. 当然博主自己使用的 AX3600 因为有特殊需求, 所以不参与这个网络的构建.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 本文的方案适用于纯 OpenWrt 系列操作系统环境. 如果你想将你的 OpenWrt 路由器和其他硬路由 / AP 等设备进行 WiFi 漫游, 则可以参考 &lt;a href=&quot;https://blog.iyoroy.cn/archives/305/&quot;&gt;家庭网络更新 - 猫棒 + 802.11k/v/r 漫游 - Kagura iYoRoy&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 统一内网网段&lt;a href=&quot;#1-统一内网网段&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;博主的规划是整个内网使用同一个网段, 因此所有路由器必须处于 AP 模式, 不再承担 DHCP Server 和 NAT 工作, 由主路由负责, 而不是 AP.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;启动 AP, 接入内网, 打开 WebUI.&lt;/li&gt;
&lt;li&gt;进入 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Interface&lt;/code&gt; 页面, 找到并编辑 &lt;code&gt;lan&lt;/code&gt; 接口. 将其 IPv4 地址设置为处于主网段但不与其他设备冲突的地址, 这里博主设置为 &lt;code&gt;192.168.1.253&lt;/code&gt;. 然后将网关设置为主路由.
&lt;figure&gt;&lt;img src=&quot;/images/344-1.png&quot; alt=&quot;设置 AP 的 lan 接口 IPv4 地址与网关&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;设置 AP 的 lan 接口 IPv4 地址与网关&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;切换到 &lt;code&gt;DHCP Server&lt;/code&gt; 选项卡, 勾选 &lt;code&gt;Ignore Interface&lt;/code&gt; 选项以完全禁用其 DHCP Server, 然后点击 &lt;code&gt;Save&lt;/code&gt; 保存
&lt;figure&gt;&lt;img src=&quot;/images/344-2.png&quot; alt=&quot;在 AP 上忽略 DHCP Server&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;在 AP 上忽略 DHCP Server&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;删除 &lt;code&gt;wan&lt;/code&gt; 和 &lt;code&gt;wan6&lt;/code&gt; 接口&lt;/li&gt;
&lt;li&gt;切换到 &lt;code&gt;Devices&lt;/code&gt; 选项卡, 找到 &lt;code&gt;br-lan&lt;/code&gt; 接口的 Configure 按钮并点击进行配置&lt;/li&gt;
&lt;li&gt;勾选所有物理接口和 AP 并单击保存
&lt;figure&gt;&lt;img src=&quot;/images/344-3.png&quot; alt=&quot;将物理接口与 AP 绑定到 br-lan&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;将物理接口与 AP 绑定到 br-lan&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你的情况和我一样, 这里列出的接口是 &lt;code&gt;Switch VLAN&lt;/code&gt; 类型而不是 &lt;code&gt;Ethernet Adapter&lt;/code&gt;, 可以通过这个方式来查找接口.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;切换到 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Switch&lt;/code&gt; 页面
&lt;figure&gt;&lt;img src=&quot;/images/344-4.png&quot; alt=&quot;OpenWrt Switch 页面中的 VLAN 划分&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;OpenWrt Switch 页面中的 VLAN 划分&lt;/figcaption&gt;&lt;/figure&gt;
从这里我们可以看出, &lt;code&gt;LAN1&lt;/code&gt;, &lt;code&gt;LAN2&lt;/code&gt;, &lt;code&gt;LAN3&lt;/code&gt; 处于 &lt;code&gt;VLAN 1&lt;/code&gt; 中, 模式为 &lt;code&gt;Access&lt;/code&gt;, 由 &lt;code&gt;CPU (eth0)&lt;/code&gt; 负责流量转发, &lt;code&gt;WAN&lt;/code&gt; 处于 &lt;code&gt;VLAN 2&lt;/code&gt; 中, 由 &lt;code&gt;CPU (eth1)&lt;/code&gt; 负责流量转发. 所以上图中的 &lt;code&gt;Switch VLAN: &quot;eth0.1&quot;&lt;/code&gt; 就是所有 LAN 口, &lt;code&gt;Switch VLAN: &quot;eth1.2&quot;&lt;/code&gt; 就是 WAN 口.
同时这种情况还可能导致下游设备没法拿到 IPv6 地址. 这里我们检查 &lt;code&gt;eth0.1&lt;/code&gt;, &lt;code&gt;eth1.2&lt;/code&gt; 的配置页面, 将 &lt;code&gt;IPv6 Enabled&lt;/code&gt; 选项手动改为 &lt;code&gt;enabled&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;做好所有配置后, 单击 &lt;code&gt;Save&amp;amp;Apply&lt;/code&gt; 保存并应用.&lt;/li&gt;
&lt;li&gt;等待一段时间后, 尝试连接 WiFi, 查看 WiFi 属性
&lt;figure&gt;&lt;img src=&quot;/images/344-5.png&quot; alt=&quot;连接 WiFi 后获取到公网 IPv6 与内网 IPv4&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;连接 WiFi 后获取到公网 IPv6 与内网 IPv4&lt;/figcaption&gt;&lt;/figure&gt;
可以看到这里已经成功拿到公网 IPv6 地址和 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 网段的 IPv4 地址.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这样的配置在两台路由器上都需要进行&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 启用 FakeMesh&lt;a href=&quot;#2-启用-fakemesh&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;FakeMesh 是 OpenWrt 提供的一个轻量级, 软件模拟的 Mesh 组网功能. 它能够做到在多台 AP 设备中进行统一的配置管理, 实现无缝漫游, 并且简化多路由网络管理.&lt;/p&gt;
&lt;h4&gt;2.1 主路由配置&lt;a href=&quot;#21-主路由配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入 &lt;code&gt;Mesh&lt;/code&gt; -&amp;gt; &lt;code&gt;FakeMesh&lt;/code&gt; 页面, 勾选 &lt;code&gt;Enable&lt;/code&gt; 启用功能&lt;/li&gt;
&lt;li&gt;在 Mesh ID 处创建当前 Mesh 会话的标识符. 这里建议不要填写英文字母, 下划线, 数字以外的特殊字符, 以免出现编码错误.&lt;/li&gt;
&lt;li&gt;在 Key 中创建当前 Mesh 会话的加密密钥&lt;/li&gt;
&lt;li&gt;在 Band 中选择 &lt;code&gt;5G&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 Role 处切换至 &lt;code&gt;Controller (AC)&lt;/code&gt; 模式&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;模式解释&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Wired AP&lt;/code&gt; 表示该设备为被控制有线 AP&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Agent&lt;/code&gt; 表示该设备用于无线 Mesh 组网&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;勾选 &lt;code&gt;Sync Configuration&lt;/code&gt; 同步配置&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Band Steering Helper&lt;/code&gt; 中选择 &lt;code&gt;usteer&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;usteer:&lt;/code&gt; OpenWrt 官方的轻量级漫游辅助工具, 简单稳定&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DAWN:&lt;/code&gt; 一个功能更强大的第三方漫游辅助工具, 算法更复杂. 这里考虑到路由器的性能, 不做选择.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;None:&lt;/code&gt; 关闭漫游辅助功能&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;关于 &lt;code&gt;Controller Access IP&lt;/code&gt;: 这个地址是 FakeMesh 控制器设置的一个固定 IP, 方便你在局域网内访问它的 WebUI. 通常情况下不需要修改, 保持默认值 &lt;code&gt;10.10.10.1&lt;/code&gt; 即可. 这个 IP 是 FakeMesh 在内部网络中用于服务发现的, 不会和你的主路由 LAN 口 IP 产生冲突. 平时管理主路由还是使用 LAN 口的 IP 去管理. &lt;strong&gt;当然, 如果你的网络环境中 &lt;code&gt;10.10.10.1&lt;/code&gt; 这个地址存在冲突, 那你当然可以换掉它. 但请记住在 AP 中配置时也要填写相应的 IP.&lt;/strong&gt;
关于 &lt;code&gt;Disable Fronthaul&lt;/code&gt;: 该功能用于开关当前节点的 SSID 广播功能. 如果你不希望当前节点发射 SSID 信号, 则可以勾选它. 在博主的配置场景中, 主路由不具备 WiFi 信号发射功能, 所以这里可以勾选&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;img src=&quot;/images/344-6.png&quot; alt=&quot;主路由 FakeMesh 控制器配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;主路由 FakeMesh 控制器配置&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后点击 &lt;code&gt;Save&amp;amp;Apply&lt;/code&gt;. 应用成功后, 下方的 Wireless Management 板块会出现一个 WiFi SSID. 这里我们点击编辑&lt;/li&gt;
&lt;li&gt;在弹出的对话框中配置你想要的 SSID, 加密方式, 频段和密码. 填写完成后再次点击保存并应用.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;到这里为止, 主路由 FakeMesh 的配置就结束了&lt;/p&gt;
&lt;h4&gt;2.2 AP 配置&lt;a href=&quot;#22-ap-配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入 &lt;code&gt;Mesh&lt;/code&gt; -&amp;gt; &lt;code&gt;FakeMesh&lt;/code&gt; 页面, 勾选 &lt;code&gt;Enable&lt;/code&gt; 启用功能&lt;/li&gt;
&lt;li&gt;在下面的信息中填入你刚才在主路由中配置的信息, &lt;strong&gt;并将 Role 切换为 &lt;code&gt;Wired AP (Ethernet backhaul)&lt;/code&gt; 模式&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;信息填写完成后单击保存并应用.
届时, AP 设备原有的 IP 地址将会失效, 此时需要进入主路由的 &lt;code&gt;Mesh&lt;/code&gt; -&amp;gt; &lt;code&gt;Usteer&lt;/code&gt; 页面查看
&lt;figure&gt;&lt;img src=&quot;/images/344-7.png&quot; alt=&quot;Usteer 页面显示已上线的 AP&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Usteer 页面显示已上线的 AP&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以看到这里有一台 AP 已经上线. 我们使用页面中所给的 &lt;code&gt;192.168.1.182&lt;/code&gt; 访问 AP 的后台&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录后台, 切换到 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Interface&lt;/code&gt; 页面&lt;/li&gt;
&lt;li&gt;点击 &lt;code&gt;meshx0&lt;/code&gt; 接口的编辑按钮, 将其从 &lt;code&gt;DHCP Client&lt;/code&gt; 切换到 &lt;code&gt;Static Address&lt;/code&gt; 协议&lt;/li&gt;
&lt;li&gt;输入你之前设定的 IP 地址信息, 然后点击保存并提交. 之后使用你设置的新 IP 访问 AP 后台.&lt;/li&gt;
&lt;li&gt;切换到 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Wireless&lt;/code&gt; 查看 WiFi 发射信息. 如果看到刚才在主路由上配置的 SSID 有正确发送, 则证明配置成功.
&lt;figure&gt;&lt;img src=&quot;/images/344-8.png&quot; alt=&quot;AP 侧 Wireless 页面确认 SSID 已下发&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;AP 侧 Wireless 页面确认 SSID 已下发&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你配置完成后, AP 侧已经同步了相关配置信息, 但是就是没有发送 WiFi 信号. 别急, 这不是你的问题.
经过分析, 这是由于&lt;strong&gt;主路由 FakeMesh 控制器的 &lt;code&gt;wifim&lt;/code&gt; 配置中缺少 &lt;code&gt;band&lt;/code&gt; 选项.&lt;/strong&gt; 在 AP 侧, 生成 WiFi 信号的主要逻辑在 &lt;code&gt;agent_sync_config&lt;/code&gt; 函数中:&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;  while&lt;/span&gt;&lt;span&gt; uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/dev/null&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          ssid&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;].ssid&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          encryption&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;].encryption&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          key&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;].key&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          bands&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;].band&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;    # ← 关键！&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          enabled&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; fakemeshac.@wifim[&lt;/span&gt;&lt;span&gt;$J&lt;/span&gt;&lt;span&gt;].enabled&lt;/span&gt;&lt;span&gt; ||&lt;/span&gt;&lt;span&gt; echo&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          [&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$bands&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &quot;2g5g&quot;&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; bands&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;2g 5g&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          [&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;$enabled&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &quot;1&quot;&lt;/span&gt;&lt;span&gt; ]&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              for&lt;/span&gt;&lt;span&gt; band &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; $bands&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;span&gt;                      # ← band 为空则循环不执行！&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                  for&lt;/span&gt;&lt;span&gt; wbandstr &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; $(&lt;/span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; wireless&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; .band=&lt;/span&gt;&lt;span&gt;\&apos;&lt;/span&gt;&lt;span&gt;${band}&lt;/span&gt;&lt;span&gt;\&apos;&lt;/span&gt;&lt;span&gt;$&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      radio&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; $wbandstr &lt;/span&gt;&lt;span&gt;|&lt;/span&gt;&lt;span&gt; cut&lt;/span&gt;&lt;span&gt; -d&lt;/span&gt;&lt;span&gt;\.&lt;/span&gt;&lt;span&gt; -f2&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      uci&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; wireless.wifinet&lt;/span&gt;&lt;span&gt;$K&lt;/span&gt;&lt;span&gt;=wifi-iface&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      uci&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; wireless.wifinet&lt;/span&gt;&lt;span&gt;$K&lt;/span&gt;&lt;span&gt;.device=&quot;&lt;/span&gt;&lt;span&gt;${radio}&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      # ... 设置 SSID、加密、802.11r/k/v 等&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                      K&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$((&lt;/span&gt;&lt;span&gt;K+1&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                  done&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;              done&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          J&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$((&lt;/span&gt;&lt;span&gt;J+1&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;控制器的 &lt;code&gt;wifim&lt;/code&gt; 配置没有 &lt;code&gt;band&lt;/code&gt; 选项, 导致 AP 同步配置后无法匹配任何 radio, 客户端 WiFi 接口从未被创建. 初步判断这可能是 OpenWrt 系统的 Bug. 现在来进行修复&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;登录主路由 SSH, 执行以下指令&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; fakemesh.@wifim[0].band=&quot;2g5g&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; fakemesh&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;登录 AP SSH, 执行以下指令&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; delete&lt;/span&gt;&lt;span&gt; fakemesh.default.wifim_md5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;uci&lt;/span&gt;&lt;span&gt; commit&lt;/span&gt;&lt;span&gt; fakemesh&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;/etc/init.d/fakemesh&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;等待 20s 左右, 让 FakeMesh 完成同步. 届时你就应该能看到 WiFi 信号正确创建.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此, AP 侧配置完成.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;相应的配置在两台 AP 上都需要执行.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;3. 测试&lt;a href=&quot;#3-测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在两台 AP 上都配置完成后, 再次打开主路由的 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Usteer&lt;/code&gt; 页面. 应当能看到两台 AP 接入
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/344-9.png&quot; alt=&quot;Usteer 页面显示两台 AP 接入&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Usteer 页面显示两台 AP 接入&lt;/figcaption&gt;&lt;/figure&gt;
此时打开手机的 WiFi 页面检查, 理应能看到 4 个 AP 接入点. (双 2.5G, 双 5G)
&lt;figure&gt;&lt;img src=&quot;/images/344-10.png&quot; alt=&quot;手机 WiFi 列表显示 4 个 AP 接入点&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;手机 WiFi 列表显示 4 个 AP 接入点&lt;/figcaption&gt;&lt;/figure&gt;
连接上网络后, 四处走动观察首选 AP 连接状况变化&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AP 1
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/344-11.png&quot; alt=&quot;漫游测试中 AP1 的连接记录&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;漫游测试中 AP1 的连接记录&lt;/figcaption&gt;&lt;/figure&gt;
AP 2
&lt;figure&gt;&lt;img src=&quot;/images/344-12.png&quot; alt=&quot;漫游测试中 AP2 的连接记录&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;漫游测试中 AP2 的连接记录&lt;/figcaption&gt;&lt;/figure&gt;
可以看到, AP 确实有在按照信号强度切换.&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最后使用 Speedtest 对网络速率进行测试
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/344-13.png&quot; alt=&quot;Speedtest 测速结果约 700Mbps&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Speedtest 测速结果约 700Mbps&lt;/figcaption&gt;&lt;/figure&gt;
博主家里是 2000Mbps 宽带, 路由器的接口速率为 1Gbps, 这里局限于路由器性能, 跑到 700Mbps 属正常水平, 故测试正常!&lt;p&gt;&lt;/p&gt;
&lt;p&gt;至此, 配置全部结束&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业人士, 如有错误或疏漏请直接指出! 感谢您的阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/326/&quot;&gt;LACP 聚合双千兆网口实现 2Gbps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/405/&quot;&gt;校园网 VLAN 接入 AP 与自动认证&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/80/&quot;&gt;家庭数据中心设备与业务介绍&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category></item><item><title>OSPFv3 + WireGuard 借用 IPv6 出口</title><link>https://blog.nanami.tech/en/archives/331</link><guid isPermaLink="false">en:331</guid><description>前言
博主大学的校园网环境中没有公网 IPv6 出口. 对于博主这种玩网络的人来说十分的不便. 但是博主在学校和在家的主路由都是 OpenWrt, 且之间有一条 VPN 骨干网可以互相通信. 于是乎博主想到了一个方法: 使用类似 Overlay Network 的方式, 通过 OSPFv3</description><pubDate>Wed, 22 Jul 2026 15:35:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主大学的校园网环境中没有公网 IPv6 出口. 对于博主这种玩网络的人来说十分的不便. 但是博主在学校和在家的主路由都是 OpenWrt, 且之间有一条 VPN 骨干网可以互相通信. 于是乎博主想到了一个方法: 使用类似 Overlay Network 的方式, 通过 OSPFv3 将学校主路由的 IPv6 默认路由下一跳改为家里的主路由, 将家里的 IPv6 网络给校园网用.&lt;/p&gt;
&lt;h2&gt;配置需求&lt;a href=&quot;#配置需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对端网关可以互相通信 (可通过 &lt;code&gt;EasyTier&lt;/code&gt;, &lt;code&gt;ZeroTier&lt;/code&gt;, &lt;code&gt;TailScale&lt;/code&gt; 等 VPN)&lt;/li&gt;
&lt;li&gt;双方网关为软路由系统或可玩性较高的硬路由&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;基础配置思路&lt;a href=&quot;#基础配置思路&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;由于没有 IPv6 环境, 但是 OSPFv3 又需要使用 IPv6 来进行通信, 所以这里我们借助 &lt;code&gt;WireGuard&lt;/code&gt; 来建立一条 6in4 通道. 然后使用 &lt;code&gt;BIRD v2&lt;/code&gt; 来运行 OSPFv3, 将家庭宽带的 &lt;code&gt;::/0&lt;/code&gt; 路由引入该 OSPF 会话, 从而达到校园网网关使用这条线路进行 IPv6 上网的目的.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由于该文章编写于暑期阶段, 因此这里将使用 Debian 13 虚拟机作为&lt;em&gt;校园网网关&lt;/em&gt;. 该虚拟机已经在内网接口关闭了 IPv6 功能, 因此无法直接通过内网连接公网 IPv6 业务.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 安装并配置 BIRD v2&lt;a href=&quot;#1-安装并配置-bird-v2&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;由于新版 OpenWrt 系统内置 WireGuard, 因此我们这里只需要另外安装 BIRD 即可.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入 WebUI, 打开 &lt;code&gt;System&lt;/code&gt; -&amp;gt; &lt;code&gt;Software&lt;/code&gt; 页面, 搜索 BIRD 并安装 &lt;code&gt;bird2&lt;/code&gt;, &lt;code&gt;bird2c&lt;/code&gt;
&lt;figure&gt;&lt;img src=&quot;/images/331-1.png&quot; alt=&quot;OpenWrt 软件包页面安装 BIRD&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;OpenWrt 软件包页面安装 BIRD&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;安装完成后打开 SSH, 查询 BIRD 安装状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-Home:~#&lt;/span&gt;&lt;span&gt; bird&lt;/span&gt;&lt;span&gt; --version&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;移动配置文件位置并更改配置文件存储位置
随着配置愈发复杂, 单个配置文件是无法满足我们的配置要求的. 所以这里我们使用 &lt;code&gt;/etc/bird&lt;/code&gt; 来作为配置文件的存储文件夹.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;实际上, 除了 OpenWrt, 常规 Linux 安装 BIRD 时都是采用 &lt;code&gt;/etc/bird&lt;/code&gt; 作为配置文件目录&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /etc/bird&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; /etc/bird.conf&lt;/span&gt;&lt;span&gt; /etc/bird/bird.conf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/init.d/bird&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;将其中的 &lt;code&gt;BIRD_CONF&lt;/code&gt; 赋值为 &lt;code&gt;/etc/bird/bird.conf&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;更改完后保存并重启 BIRD 进程&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/etc/init.d/bird&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;2. 配置 WireGuard 接口&lt;a href=&quot;#2-配置-wireguard-接口&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;OpenWrt 默认安装 WireGuard, 但没有默认的私钥和公钥, 所以这里我们自己生成&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;进入 SSH, 生成公钥和私钥&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wg&lt;/span&gt;&lt;span&gt; genkey&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; tee&lt;/span&gt;&lt;span&gt; privatekey&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; wg&lt;/span&gt;&lt;span&gt; pubkey&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; publickey&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;OpenWrt 原生支持在 WebUI 中配置和管理 WireGuard 接口, 所以我们这里直接在 WebUI 上进行配置.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开 WebUI, 切换至 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Interfaces&lt;/code&gt;, 单击 &lt;code&gt;Add new interface...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 Name 中输入该 WireGuard 接口的名称, 注意不要太长. 然后将 Protocol 切换至 &lt;code&gt;WireGuard VPN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Private Key&lt;/code&gt; 和 &lt;code&gt;Public Key&lt;/code&gt; 中填入我们刚刚生成的密钥&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Listen Port&lt;/code&gt; 中填入可供 WireGuard 监听的空闲端口&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;IP Addresses&lt;/code&gt; 中填入一个&lt;strong&gt;CIDR 格式的链路本地 IPv6 地址和一个符合 ULA 规范的 IPv6 地址&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;我们这里因为接入的设备不多, 所以即使在考虑冗余的情况下, 给一个 &lt;code&gt;/112&lt;/code&gt; 的网段也是绰绰有余了.
示例配置
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/331-2.png&quot; alt=&quot;WireGuard 接口示例配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;WireGuard 接口示例配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;切换至 &lt;code&gt;Peers&lt;/code&gt; 页面, 点击 &lt;code&gt;Add peer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Description&lt;/code&gt; 中填入对端设备名称&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Public Key&lt;/code&gt; 中填入对端设备公钥&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Allowed IPs&lt;/code&gt; 中填入对端 WireGuard 内网 IPv6 地址和 &lt;code&gt;::/0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Endpoint Host&lt;/code&gt; 中填入校园网网关的 VPN 内网地址&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Endpoint Port&lt;/code&gt; 中填入校园网网关的 WireGuard 监听地址&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;因为我们还未配置校园网网关接口, 所以这里直接随便写一个端口即可.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;Persistent Keep Alive&lt;/code&gt; 中填入 &lt;code&gt;25&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;示例配置
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/331-3.png&quot; alt=&quot;WireGuard Peer 示例配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;WireGuard Peer 示例配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后保存提交&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;相同的配置需要在校园网网关上也配置一遍&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;双方都配置好后, 检查接口状态. 如果接口的 &lt;code&gt;TX&lt;/code&gt; 和 &lt;code&gt;RX&lt;/code&gt; 都有流量, 那就证明配置成功了. 此时可以进行测试.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Debian:/etc/wireguard#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; fe80::1%tunnel_ipip6&lt;/span&gt;&lt;span&gt; (fe80:1::1%tunnel_ipip6) 56 data bytes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;0.812&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;0.614&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;0.750&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;1.25&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; fe80:1::1%tunnel_ipip6&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 3052ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0.614/0.857/1.254/0.239&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到连接是没有问题的, 至此 WireGuard 侧配置完成.&lt;/p&gt;
&lt;h3&gt;3. 配置 OSPF&lt;a href=&quot;#3-配置-ospf&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在这两台设备上创建 &lt;code&gt;bird.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/bird/bird.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;按照该模板填写&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;log syslog all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define ROUTER_ID                = &amp;lt;ROUTER_ID&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol device &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    scan time 10;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol direct &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;kernel.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;ospf.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ROUTER_ID&lt;/code&gt; 当前路由器的 Router ID. 需要双方不同且唯一. 值形式与 IPv4 类似, 均为 &lt;code&gt;xxx.xxx.xxx.xxx&lt;/code&gt;. 这里可以直接填写本机的内网 IPv4 地址.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;分别创建 &lt;code&gt;kernel.conf&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;protocol kernel kernel_v&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import none;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export filter {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            if source = RTS_STATIC then reject;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            accept;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol kernel kernel_v&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import none;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export filter {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            if source = RTS_STATIC then reject;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            accept;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;该配置文件旨在让 BIRD 将动态路由协议 (如 &lt;code&gt;BGP&lt;/code&gt;, &lt;code&gt;OSPF&lt;/code&gt;) 学习到的路由写入系统内核, 但拒绝将自己配置文件中写死的静态路由写入内核.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;分别创建 &lt;code&gt;ospf.conf&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;校园网网关&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;protocol ospf v&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ospf_&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    router id ROUTER_ID;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export none;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    include &lt;/span&gt;&lt;span&gt;&quot;/etc/bird/ospf/0.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;该配置文件旨在让 BIRD 从该 OSPF 会话中引入所有学习到的路由, 但不导出任何路由到该 OSPF 会话中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;家庭网关&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;filter export_default &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if net ~ [ &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;:/&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; ] then &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        accept;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt; else &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        reject;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol ospf v&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ospf_&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;to&lt;/span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;_test &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    router id ROUTER_ID;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import none;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export filter export_default;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    include &lt;/span&gt;&lt;span&gt;&quot;/etc/bird/ospf/0.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;该配置文件旨在让 BIRD 将 &lt;code&gt;::/0&lt;/code&gt; 的默认路由导入 OSPF 中, 但不导出任何学习到的路由到系统内核中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;分别创建 OSPF 会话配置文件&lt;/li&gt;
&lt;li&gt;校园网网关&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; ospf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; ospf/0.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;plain - 配置文件
&lt;code&gt;bash     area 0.0.0.0 {         interface &quot;tunnel_ipip6&quot; {             type ptmp;             ttl security tx only;             neighbors {                 fd00:1::1;             };         };     };     &lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;家庭网关&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; ospf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; ospf/0.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;plain - 配置文件
&lt;code&gt;bash     area 0.0.0.0 {         interface &quot;tunnel_ipip6&quot; {             type ptmp;             ttl security tx only;             neighbors {                 fd00:1::2;             };         };     };     &lt;/code&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Q. 为什么使用 ULA 地址建立连接却还需要 Link-Local 地址?
A. 因为 OSPFv3 邻居发现依赖链路本地地址 (Link-Local）, 协议报文以 Link-Local 为源/目的进行邻接建立; 全局或 ULA 地址可以用于配置, 管理或路由条目. 但不能替代接口上的 Link-Local 地址参与邻接建立, 但是公网会话却需要使用符合 ULA 规范的地址. 因此虽然 OSPF 配置文件中使用 ULA 地址, 但实际连接时 BIRD 会检查该接口是否拥有 Link-Local 地址. 如果没有, OSPF 连接则会失败.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;分别应用配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;检查会话状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt; p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果 OSPF 已经处于 &lt;code&gt;Running&lt;/code&gt; 状态, 则配置完成&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Debian:/etc/bird#&lt;/span&gt;&lt;span&gt; birdc&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt; p&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;span&gt;       Proto&lt;/span&gt;&lt;span&gt;      Table&lt;/span&gt;&lt;span&gt;      State&lt;/span&gt;&lt;span&gt;  Since&lt;/span&gt;&lt;span&gt;         Info&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;device1&lt;/span&gt;&lt;span&gt;    Device&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     14:40:45.408&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;direct1&lt;/span&gt;&lt;span&gt;    Direct&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     14:40:45.408&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v4&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     14:40:45.408&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v6&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     14:40:45.408&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ospf_4to6&lt;/span&gt;&lt;span&gt;  OSPF&lt;/span&gt;&lt;span&gt;       master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     14:46:00.698&lt;/span&gt;&lt;span&gt;  Running&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;3. 配置防火墙&lt;a href=&quot;#3-配置防火墙&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;到达这一步, 我们已经拥有了 IPv6 默认路由, ULA 地址, Link-Local 地址. 但我们仍然无法上网. 为什么呢? 这是因为在家庭网关侧我们需要启用 &lt;code&gt;nat6&lt;/code&gt; 才可以让本地数据包正确的发往公网, 同时公网返回的数据包也可以正确的到达本地设备. 因为 OpenWrt 可以使用 WebUI 配置, 所以这里我们全程使用 WebUI.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开 &lt;code&gt;Network&lt;/code&gt; -&amp;gt; &lt;code&gt;Firewall&lt;/code&gt; 页面, 在下方的 &lt;code&gt;Zones&lt;/code&gt; 区域点击 &lt;code&gt;wan&lt;/code&gt; 区域的编辑按钮&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Advanced Setting&lt;/code&gt; 中勾选 &lt;code&gt;IPv6 Masquerading&lt;/code&gt;, 然后保存提交
&lt;figure&gt;&lt;img src=&quot;/images/331-4.png&quot; alt=&quot;在 wan 区域启用 IPv6 Masquerading&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;在 wan 区域启用 IPv6 Masquerading&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;点击左下角 &lt;code&gt;Add&lt;/code&gt; 按钮, 命名为 &lt;code&gt;WireGuard&lt;/code&gt;, 将所有规则都选择 &lt;code&gt;accept&lt;/code&gt;, Covered networks 选择之前创建的 WireGuard 接口, Allowed forwared to &lt;em&gt;destination&lt;/em&gt; zones 和 Allowed forwared to &lt;em&gt;source&lt;/em&gt; zones 全部勾选. 之后同样切换到 &lt;code&gt;Advanced Settings&lt;/code&gt; 中打开 &lt;code&gt;IPv6 Masquerading&lt;/code&gt;, 保存提交
&lt;figure&gt;&lt;img src=&quot;/images/331-5.png&quot; alt=&quot;新建 WireGuard 防火墙区域&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;新建 WireGuard 防火墙区域&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;切换到 &lt;code&gt;NAT Rules&lt;/code&gt; 选项卡, 点击 &lt;code&gt;Add&lt;/code&gt; 按钮新建规则&lt;/li&gt;
&lt;li&gt;规则名称命名为 &lt;code&gt;nat6_ipip6Tunnel&lt;/code&gt;, Restrict to address family 选择 &lt;code&gt;IPv6 Only&lt;/code&gt;. Outbound Zone 选择 &lt;code&gt;WireGuard&lt;/code&gt;. Source address 填入 &lt;code&gt;fd00:1::/112&lt;/code&gt; &lt;em&gt;(即为刚才填写的 ULA 地址段)&lt;/em&gt;, Action 选择 &lt;code&gt;MASQUERADE&lt;/code&gt;, 保存提交.
&lt;figure&gt;&lt;img src=&quot;/images/331-6.png&quot; alt=&quot;新建 IPv6 NAT 规则 nat6_ipip6Tunnel&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;新建 IPv6 NAT 规则 nat6_ipip6Tunnel&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至此, 防火墙配置完成&lt;/p&gt;
&lt;h3&gt;4. 验证&lt;a href=&quot;#4-验证&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;到了这里, 我们已经完成了所有配置. 现在我们来验证校园网网关是否可以 IPv6 上网.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv6 地址查询&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Debian:/etc/bird#&lt;/span&gt;&lt;span&gt; ip&lt;/span&gt;&lt;span&gt; a&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1:&lt;/span&gt;&lt;span&gt; lo:&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;LOOPBACK,UP,LOWER_U&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mtu&lt;/span&gt;&lt;span&gt; 65536&lt;/span&gt;&lt;span&gt; qdisc&lt;/span&gt;&lt;span&gt; noqueue&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt; UNKNOWN&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; qlen&lt;/span&gt;&lt;span&gt; 1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    link/loopback&lt;/span&gt;&lt;span&gt; 00:00:00:00:00:00&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; 00:00:00:00:00:00&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet&lt;/span&gt;&lt;span&gt; 127.0.0.1/8&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; host&lt;/span&gt;&lt;span&gt; lo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet6&lt;/span&gt;&lt;span&gt; ::1/128&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; host&lt;/span&gt;&lt;span&gt; noprefixroute&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2:&lt;/span&gt;&lt;span&gt; eth0:&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;BROADCAST,MULTICAST,UP,LOWER_U&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mtu&lt;/span&gt;&lt;span&gt; 1500&lt;/span&gt;&lt;span&gt; qdisc&lt;/span&gt;&lt;span&gt; fq_codel&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt; UP&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; qlen&lt;/span&gt;&lt;span&gt; 1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    link/ether&lt;/span&gt;&lt;span&gt; bc:24:11:41:d0:1c&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; ff:ff:ff:ff:ff:ff&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    altname&lt;/span&gt;&lt;span&gt; enp0s18&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    altname&lt;/span&gt;&lt;span&gt; enxbc241141d01c&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet&lt;/span&gt;&lt;span&gt; 192.168.1.21/24&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; 192.168.1.255&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt; eth0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;3:&lt;/span&gt;&lt;span&gt; tun0:&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;POINTOPOINT,UP,LOWER_U&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mtu&lt;/span&gt;&lt;span&gt; 1360&lt;/span&gt;&lt;span&gt; qdisc&lt;/span&gt;&lt;span&gt; fq_codel&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt; UNKNOWN&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; qlen&lt;/span&gt;&lt;span&gt; 500&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    link/none&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet&lt;/span&gt;&lt;span&gt; 10.0.64.21/24&lt;/span&gt;&lt;span&gt; brd&lt;/span&gt;&lt;span&gt; 10.0.64.255&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet6&lt;/span&gt;&lt;span&gt; fe80::617b:570b:ef5a:a679/64&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; stable-privacy&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel_ll&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;5:&lt;/span&gt;&lt;span&gt; tunnel_ipip6:&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;POINTOPOINT,NOARP,UP,LOWER_U&lt;/span&gt;&lt;span&gt;P&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; mtu&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;span&gt; qdisc&lt;/span&gt;&lt;span&gt; noqueue&lt;/span&gt;&lt;span&gt; state&lt;/span&gt;&lt;span&gt; UNKNOWN&lt;/span&gt;&lt;span&gt; group&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;span&gt; qlen&lt;/span&gt;&lt;span&gt; 1000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    link/none&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet6&lt;/span&gt;&lt;span&gt; fd00:1::2/112&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    inet6&lt;/span&gt;&lt;span&gt; fe80:1::2/112&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;       valid_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;span&gt; preferred_lft&lt;/span&gt;&lt;span&gt; forever&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到这里 &lt;code&gt;eth0&lt;/code&gt; 接口是没有公网 IPv6 地址的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;连通性测试&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Debian:/etc/bird#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; www.baidu.com&lt;/span&gt;&lt;span&gt; -6&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; www.baidu.com&lt;/span&gt;&lt;span&gt; (2409:8c20:6:123c:0:ff:b0f6:b2d) 56 data bytes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 2409:8c20:6:123c:0:ff:b0f6:b2d:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;14.3&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 2409:8c20:6:123c:0:ff:b0f6:b2d:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;13.8&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 2409:8c20:6:123c:0:ff:b0f6:b2d:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;13.7&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 2409:8c20:6:123c:0:ff:b0f6:b2d:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;14.0&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 2409:8c20:6:123c:0:ff:b0f6:b2d:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;52&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;14.0&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; www.baidu.com&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 4005ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 13.671/13.957/14.308/0.208&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到这里成功访问了百度的 IPv6 地址, 连通性正常!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;网络路径查询&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Debian:/etc/bird#&lt;/span&gt;&lt;span&gt; traceroute&lt;/span&gt;&lt;span&gt; www.baidu.com&lt;/span&gt;&lt;span&gt; -6&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;traceroute&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; www.baidu.com&lt;/span&gt;&lt;span&gt; (2409:8c20:6:123c:0:ff:b0f6:b2d), 30 hops max, 80 byte packets&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;  _gateway&lt;/span&gt;&lt;span&gt; (fd00:1::1)  0.873 ms  0.856 ms  0.825 ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;  ah-ipv6&lt;/span&gt;&lt;span&gt; (2409:***)  2.385 ms  2.360 ms  2.312 ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt;  *&lt;/span&gt;&lt;span&gt; ah-ipv6&lt;/span&gt;&lt;span&gt; (2409:***)  3.636 ms &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;  2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (2409:***)  5.922 ms &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt;  2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (2409:***)  12.053 ms &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;  12.465 ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt;  2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (2409:***)  14.650 ms &lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 7&lt;/span&gt;&lt;span&gt;  2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (2409:***)  10.908 ms 2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;2409:***&lt;/span&gt;&lt;span&gt;)  10.122 ms 2409:&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;2409:***&lt;/span&gt;&lt;span&gt;)  8.499 ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 这里的第一跳就是我们刚才通过 OSPF 配置的 Peer! 至此, 配置全部结束!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本文为整活性质想法, 如果你真的有类似需求, 你或许应该寻找更加体面的方法. 本人非专业人员, 如有错误或疏漏欢迎指出! 感谢阅读.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/216/&quot;&gt;OpenWrt 基于 BIRD 的 OSPF 组网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/324/&quot;&gt;IX 前置 + OSPF: IEPL 专线组网搭建&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/405/&quot;&gt;校园网 VLAN 接入 AP 与自动认证&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category></item><item><title>LACP 聚合双千兆网口实现 2Gbps</title><link>https://blog.nanami.tech/en/archives/326</link><guid isPermaLink="false">en:326</guid><description>前言
博主的 HomeLab 网络环境是支持全链路 10 Gbps 的. 但是博主的 SubSerer 的单个端口却只有 1 Gbps. 由于该服务器负责的是业务流量转发, 其中包含网络代理. 在入户带宽 2000 Mbps 的情况下, 1 Gbps 的单口带宽就显得有些差强人意.</description><pubDate>Tue, 21 Jul 2026 04:17:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主的 HomeLab 网络环境是支持全链路 10 Gbps 的. 但是博主的 SubSerer 的单个端口却只有 1 Gbps. 由于该服务器负责的是业务流量转发, 其中包含网络代理. 在入户带宽 2000 Mbps 的情况下, 1 Gbps 的单口带宽就显得有些差强人意. 但好在这台服务器有两个这样的 1 Gbps 端口, 博主所使用的交换机也原生支持 LACP. 所以这篇文章就记录了博主尝试通过 LACP 对两个 1 Gbps 接口做链路聚合的过程.&lt;/p&gt;
&lt;h2&gt;什么是链路聚合?&lt;a href=&quot;#什么是链路聚合&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;简单来说, 链路聚合就是&lt;strong&gt;把两台设备之间的多条物理链路聚合在一起, 当做一条逻辑链路来使用.&lt;/strong&gt; 通过这种技术, 我们不仅可以提升链路总带宽, 我们还可以增强业务 SLA, 随便坏其中任意一条链路都不影响业务可用性.&lt;/p&gt;
&lt;h2&gt;什么是 LACP?&lt;a href=&quot;#什么是-lacp&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;LACP 是一种&lt;strong&gt;基于 &lt;code&gt;IEEE 802.3ad&lt;/code&gt; 标准的实现链路动态聚合与解聚合的协议.&lt;/strong&gt; 通过这种协议, 我们可以很轻松的在终端和网络设备之间进行链路聚合, 且能够获得极高的稳定性. 但这种方法也有弊端: &lt;strong&gt;只有终端和网络设备均支持 &lt;code&gt;802.3ad&lt;/code&gt; 协议的情况下才可以使用&lt;/strong&gt;, 这就造成了某些使用廉价 Layer 2 交换机或非网管交换机的用户群体无法使用该协议. 在本篇文章中, 我们只在双方都支持 LACP 的情况下进行配置.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 配置交换机 LACP&lt;a href=&quot;#1-配置交换机-lacp&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;博主这里使用的是 &lt;code&gt;D-Link&lt;/code&gt; 品牌的交换机, 直接使用 WebUI 进行配置. 虽然配置过程可能不同, 但 LACP 协议的基础原理都是通用的. 使用其他品牌交换机的读者也可以进行参考.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;启动交换机 WebUI, 进入 &lt;code&gt;Link Arrangement&lt;/code&gt; 页面的 &lt;code&gt;Port Trunking Settings&lt;/code&gt; 子页面.
&lt;figure&gt;&lt;img src=&quot;/images/326-1.png&quot; alt=&quot;D-Link 交换机 Port Trunking 设置页面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;D-Link 交换机 Port Trunking 设置页面&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;我们这里使用 40 和 48 号端口连接服务器, 所以这里勾选 40, 48 号端口.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Group ID&lt;/code&gt; 填写的是该 LACP 会话的组 ID. 该参数的作用是标识不同的 LACP 会话, 从而达到一台交换机负责多个 LACP 连接的目的. 这里我们填写 &lt;code&gt;1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Type&lt;/code&gt; 标识的是该 Trunk 端口的类型. 有两种可供选择, 分别为 &lt;code&gt;Static&lt;/code&gt; 和 &lt;code&gt;LACP&lt;/code&gt;, 这里我们选择 &lt;code&gt;LACP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Master Port&lt;/code&gt; 标识的是该 LACP 会话的主要端口. 我们需要选择我们做聚合的其中一个端口, 这里我们选择 40 号端口.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;State&lt;/code&gt; 标识的是 LACP 会话的状态. 这里我们选择 &lt;code&gt;Enabled&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Trap&lt;/code&gt; 标识的是当前 LACP 会话是否开启 &lt;code&gt;SNMP Trap&lt;/code&gt; 监听. 如果您的网络环境中存在 SNMP 网关服务器, 且进行了相关配置, 您可以选择 &lt;code&gt;Enable&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后我们单击 &lt;code&gt;Add&lt;/code&gt;, 然后切换至 &lt;code&gt;LACP Port Settings&lt;/code&gt; 子页面.
在这里我们需要将 40 和 48 号端口的 &lt;code&gt;Activity&lt;/code&gt; 配置为 &lt;code&gt;Active&lt;/code&gt;, 即激活状态.
&lt;figure&gt;&lt;img src=&quot;/images/326-2.png&quot; alt=&quot;D-Link 交换机 LACP 端口设置页面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;D-Link 交换机 LACP 端口设置页面&lt;/figcaption&gt;&lt;/figure&gt;
配置完成后, 交换机侧的配置就彻底结束了.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 配置服务器 LACP&lt;a href=&quot;#2-配置服务器-lacp&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;博主这里使用的是基于 Debian 13 的 Proxmox 9.2.3 系统.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装管理绑定的工具 &lt;code&gt;ifenslave&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; ifenslave&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;加载指定内核模块, 让内核支持网卡绑定功能&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; modprobe&lt;/span&gt;&lt;span&gt; bonding&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;打开 &lt;code&gt;/etc/network/interfaces&lt;/code&gt; 文件并按照指示编辑
&lt;ul&gt;
&lt;li&gt;将你的物理网卡 (如 &lt;code&gt;eth0&lt;/code&gt;, &lt;code&gt;eth1&lt;/code&gt;) 设置为手动模式, 并指定它们属于哪个逻辑 bond 接口.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; eth0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; eth0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-master&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; eth1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; eth1&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-master&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;配置逻辑接口 &lt;code&gt;bond0&lt;/code&gt;, 包括 bonding 的各项参数.&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-slaves&lt;/span&gt;&lt;span&gt; eno1&lt;/span&gt;&lt;span&gt; eno2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-mode&lt;/span&gt;&lt;span&gt; 802.3ad&lt;/span&gt;&lt;span&gt;                 # 等价于 4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-miimon&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-xmit-hash-policy&lt;/span&gt;&lt;span&gt; layer3+4&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您使用的是常规 Linux 而非 Proxmox VE, 则这么配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    address&lt;/span&gt;&lt;span&gt; 192.168.1.100&lt;/span&gt;&lt;span&gt;           # 你的服务器IP&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    netmask&lt;/span&gt;&lt;span&gt; 255.255.255.0&lt;/span&gt;&lt;span&gt;           # 你的网络子网掩码&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    gateway&lt;/span&gt;&lt;span&gt; 192.168.1.1&lt;/span&gt;&lt;span&gt;             # 你的网关地址&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-slaves&lt;/span&gt;&lt;span&gt; eth0&lt;/span&gt;&lt;span&gt; eth1&lt;/span&gt;&lt;span&gt;           # 指定绑定的物理网卡&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-mode&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt;                     # 指定 bonding 模式&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-miimon&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt;                 # 链路检查间隔(毫秒)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-xmit-hash-policy&lt;/span&gt;&lt;span&gt; layer3+4&lt;/span&gt;&lt;span&gt;  # 负载均衡的哈希策略&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;关于 &lt;code&gt;bond-mode&lt;/code&gt;&lt;/p&gt;



































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;模式&lt;/th&gt;&lt;th&gt;名称&lt;/th&gt;&lt;th&gt;效果与说明&lt;/th&gt;&lt;th&gt;适用场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;mode=4&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;802.3ad (LACP)&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;专业级链路聚合&lt;/strong&gt;, 能够叠加速率并提供负载均衡和容错. &lt;strong&gt;需要交换机也支持 LACP&lt;/strong&gt;.&lt;/td&gt;&lt;td&gt;&lt;strong&gt;服务器与交换机均支持的理想生产环境&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;mode=0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;balance-rr&lt;/code&gt; (轮询)&lt;/td&gt;&lt;td&gt;简单负载均衡, 能叠加速率, 不依赖交换机. &lt;strong&gt;但可能导致数据包乱序.&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;希望无需调整交换机就能获得较好性能的场景. 理论上无需 LACP, 但通常仍建议交换机支持静态聚合, 否则兼容性有限&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;mode=6&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;balance-alb&lt;/code&gt; (自适应)&lt;/td&gt;&lt;td&gt;无需交换机支持, 即可实现发送和接收的负载均衡, 理论上能叠加速率&lt;/td&gt;&lt;td&gt;希望无需调整交换机就能获得较好性能的场景&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;mode=1&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;active-backup&lt;/code&gt; (主备)&lt;/td&gt;&lt;td&gt;&lt;strong&gt;仅提供冗余, 不叠加带宽.&lt;/strong&gt; 同一时间只有一个网卡工作.&lt;/td&gt;&lt;td&gt;只希望提高网络 SLA, 不追求提升速率&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置 &lt;code&gt;vmbr0&lt;/code&gt; 网卡&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您配置的是普通 Linux 而非 Proxmox VE, 则可以不用配置这一步&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    address&lt;/span&gt;&lt;span&gt; 192.168.1.100/24&lt;/span&gt;&lt;span&gt;   # 服务器 IP 地址&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    gateway&lt;/span&gt;&lt;span&gt; 192.168.1.1&lt;/span&gt;&lt;span&gt;        # 服务器网关&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bridge-ports&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;span&gt;         # 关键：网桥连接至 bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bridge-stp&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bridge-fd&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;完整配置示例&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# network interface settings; autogenerated&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# Please do NOT modify this file directly, unless you know what&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# you&apos;re doing.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# If you want to manage parts of the network configuration manually,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# please utilize the &apos;source&apos; or &apos;source-directory&apos; directives to do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# so.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# PVE will preserve these directives, but will NOT read its network&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# configuration from sourced files, so do not attempt to move any of&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# the PVE managed interfaces into external files!&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;source&lt;/span&gt;&lt;span&gt; /etc/network/interfaces.d/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; lo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; lo&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; loopback&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; eno1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; eno1&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-master&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; eno2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; eno2&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-master&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; manual&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-slaves&lt;/span&gt;&lt;span&gt; eno1&lt;/span&gt;&lt;span&gt; eno2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-mode&lt;/span&gt;&lt;span&gt; 802.3ad&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-miimon&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    bond-xmit-hash-policy&lt;/span&gt;&lt;span&gt; layer3+4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;auto&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;iface&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;span&gt; inet&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        address&lt;/span&gt;&lt;span&gt; 192.168.1.5/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        gateway&lt;/span&gt;&lt;span&gt; 192.168.1.1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        bridge-ports&lt;/span&gt;&lt;span&gt; bond0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        bridge-stp&lt;/span&gt;&lt;span&gt; off&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        bridge-fd&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后, 对网络进行热重载&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ifreload&lt;/span&gt;&lt;span&gt; -a&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您正在配置普通 Linux, 则使用该指令&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;span&gt; networking&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;重载完成后, 检查 WebUI 上的配置. 如果没问题, 则配置完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 测试&lt;a href=&quot;#3-测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;因为 LACP 是基于流量哈希计算的链路聚合, 所以在单线程下, 带宽仍然是单条链路的带宽. 因此我们这里使用多线程的 &lt;code&gt;iperf3&lt;/code&gt; 进行测试&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iperf3&lt;/span&gt;&lt;span&gt; -c&lt;/span&gt;&lt;span&gt; 192.168.1.5&lt;/span&gt;&lt;span&gt; -P&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/326-3.png&quot; alt=&quot;iperf3 双线程测速达到 2Gbps&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;iperf3 双线程测速达到 2Gbps&lt;/figcaption&gt;&lt;/figure&gt;
这里可以看到, 总带宽已经达到 2 Gbps 的标准. 由此可以得出, LACP 聚合的配置已经成功!&lt;p&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您使用的是企业交换机, 不要忘了保存配置&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业人员, 如有错误或疏漏请指出! 感谢您的阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/52/&quot;&gt;OpenWrt 双 WAN 聚合: 多宽带速率叠加&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/344/&quot;&gt;FakeMesh + 802.11kvr 全屋 WiFi 漫游&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/80/&quot;&gt;家庭数据中心设备与业务介绍&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category><category>tag:运维</category></item><item><title>IX 前置 + OSPF: IEPL 专线组网搭建</title><link>https://blog.nanami.tech/en/archives/324</link><guid isPermaLink="false">en:324</guid><description>前言
博主拥有自己的境外服务器, 用于完成自己的业务: Samba 文件备份恢复, 自建网站 CDN, DN42 路由等. 但在这之中, 某些 VPS 的线路并没有对国内有特殊优化, 这导致国内直连的体验非常的糟糕, 同时业务搭建的体验也非常的不好. 这使得博主打算通过购买 IEPL/IPLC</description><pubDate>Sun, 19 Jul 2026 15:39:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主拥有自己的境外服务器, 用于完成自己的业务: Samba 文件备份恢复, 自建网站 CDN, DN42 路由等. 但在这之中, 某些 VPS 的线路并没有对国内有特殊优化, 这导致国内直连的体验非常的糟糕, 同时业务搭建的体验也非常的不好. 这使得博主打算通过购买 IEPL/IPLC 之类的专线业务来提升自己的业务使用体验. 这篇文章将会描述博主搭建专线业务网络的整个过程, 来给各位打算购买专线服务的做一个参考.&lt;/p&gt;
&lt;h2&gt;配置需求&lt;a href=&quot;#配置需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可接入 IX 网络的国内前置服务器&lt;/li&gt;
&lt;li&gt;境外专线 VPS&lt;/li&gt;
&lt;li&gt;境外普通 VPS&lt;/li&gt;
&lt;li&gt;善于思考的大脑&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;专有名词解释&lt;a href=&quot;#专有名词解释&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;IEPL &lt;code&gt;(International Ethernet Private Line)&lt;/code&gt; / IPLC &lt;code&gt;(International Private Leased Circuit)&lt;/code&gt;&lt;a href=&quot;#iepl-international-ethernet-private-line--iplc-international-private-leased-circuit&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;国际以太网专线, 跨越国家或地区的端到端数字专有带宽连接的租用服务. 不同于普通线路的国际出口, IEPL 和 IPLC 通常拥有非常高的 SLA 保障, 可以做到&lt;strong&gt;无论网络是否处于高峰期, 都能够跑满线路的签约速率, 且丢包率通常极低&lt;/strong&gt;, 甚至在日常业务的使用中可以忽略不记. 这两类线路的延迟也可以做到非常低, 在我们比较熟悉的沪日专线中, 延迟可以做到 &lt;strong&gt;~30ms&lt;/strong&gt;; 广港因为物理距离近, 延迟更是低到只有 &lt;strong&gt;~3ms&lt;/strong&gt;. 同时, 由于这两类线路的特殊性质, 其网络通常不受长城防火墙 &lt;code&gt;(Great Fire Wall)&lt;/code&gt; 限制, 而是由监管更加严格的&lt;strong&gt;傲盾&lt;/strong&gt;来进行流量监控. 因此, 要想在这样的线路上搭建梯子等违法业务, 是一件很困难的事.
IEPL / IPLC 有两种接入方式, 一种为&lt;strong&gt;通过 IX 前置接入&lt;/strong&gt;, 一种为&lt;strong&gt;直接接入&lt;/strong&gt;. 前者无法直接被普通家用/商用宽带访问, 需要可以接入 IX 的云服务器作为跳板机使用. 后者则可以直接在任意网络环境中直接接入.&lt;/p&gt;
&lt;h3&gt;IX &lt;code&gt;(Internet Exchange Point)&lt;/code&gt;&lt;a href=&quot;#ix-internet-exchange-point&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;IX &lt;code&gt;(Internet Exchange Point)&lt;/code&gt;, 可以理解为一个大型的网络枢纽, 各大云厂商都接入其中, 彼此可以直接且高速地进行数据交换. 同时, 因为 IEPL/IPLC 线路的特殊性, 在国内通常不直接提供入口, 而是接入 IX, 仅由有资质的云厂商提供服务. 所以, 我们普通的家庭网络或者企业网络, 要想使用 IEPL/IPLC 提供的服务, 就必须需要 IX 前置来作为跳板机使用.&lt;/p&gt;
&lt;h2&gt;法律声明&lt;a href=&quot;#法律声明&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;本文仅作技术分享, 不教学任何违法违规的技术, 也请勿将本文中提到的技术用于违法违规业务的搭建与使用! 本文读者所造成的一切行为与本文, 本站以及博主无关!&lt;/strong&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 购买 IX 前置&lt;a href=&quot;#1-购买-ix-前置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;目前, 国内可以接入 IX 的云厂商总共有以下这些&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;阿里云 (Alibaba Cloud)&lt;/li&gt;
&lt;li&gt;腾讯云 (Tencent Cloud)&lt;/li&gt;
&lt;li&gt;华为云 (Huawei Cloud)&lt;/li&gt;
&lt;li&gt;火山引擎 (Volcano Engine)&lt;/li&gt;
&lt;li&gt;百度智能云 (Baidu Cloud)&lt;/li&gt;
&lt;li&gt;UCloud (UCloud)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是它们的优势与劣势&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;云厂商&lt;/th&gt;&lt;th&gt;核心优势&lt;/th&gt;&lt;th&gt;主要劣势 / 注意事项&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;火山引擎&lt;/td&gt;&lt;td&gt;延迟低&lt;/td&gt;&lt;td&gt;流量费用高昂&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;阿里云 / 腾讯云&lt;/td&gt;&lt;td&gt;成本低, 常有高性价比套餐&lt;/td&gt;&lt;td&gt;带宽可能受限, 存在稳定性风险, 且审查更为严格&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;华为云 / 百度云 / UCloud&lt;/td&gt;&lt;td&gt;作为备选方案, 可以覆盖更多场景&lt;/td&gt;&lt;td&gt;信息相对较少, 具体性能和特定 IX 节点的兼容性需要自行验证&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;数据仅供参考, 具体请以实际体验为准&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本篇文章选用阿里云的上海轻量服务器和 Debian 系统作为演示&lt;/p&gt;
&lt;h3&gt;2. 搭建 WireGuard VPN 网络&lt;a href=&quot;#2-搭建-wireguard-vpn-网络&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;这一步的目的是为了让我们自己的设备和境外 VPS 建立直接连接, 使得我们可以直接访问到境外 VPS.&lt;/p&gt;
&lt;h4&gt;2.1 安装 WireGuard&lt;a href=&quot;#21-安装-wireguard&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;我们需要安装 &lt;code&gt;wireguard-tools&lt;/code&gt; 软件包, 使用这条指令安装&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; wireguard&lt;/span&gt;&lt;span&gt; wireguard-tools&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;使用这条指令确认 WireGuard 是否安装成功&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;wg&lt;/span&gt;&lt;span&gt; --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;示例输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;wireguard-tools&lt;/span&gt;&lt;span&gt; v1.0.20210914&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;span&gt; https://git.zx2c4.com/wireguard-tools/&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后, 生成 WireGuard 密钥对&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wg&lt;/span&gt;&lt;span&gt; genkey&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; tee&lt;/span&gt;&lt;span&gt; privatekey&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; wg&lt;/span&gt;&lt;span&gt; pubkey&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; publickey&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;这样的操作需要在你的 IX 前置, 本地服务器, 境外 IEPL VPS 上都执行一遍&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;2.2 规划 VPN 网络&lt;a href=&quot;#22-规划-vpn-网络&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;在本文的使用环境中, 博主需要建立一共包含多台设备的 WireGuard VPN 网络. 主要设备分别为 &lt;strong&gt;IX 前置&lt;/strong&gt;, &lt;strong&gt;IEPL 服务器&lt;/strong&gt;, &lt;strong&gt;个人内网网关&lt;/strong&gt;, 此外还需要包含一些其他境外普通服务器. 所以这里我们直接给 &lt;code&gt;/24&lt;/code&gt; 的一整个段.
VPN 网络的地址段必须基于&lt;strong&gt;内网地址&lt;/strong&gt;, 且&lt;strong&gt;不应与系统路由表冲突&lt;/strong&gt;. 这里我们给与 &lt;code&gt;10.0.1.0/24&lt;/code&gt; 这一段的地址.
由于博主在建立这条 WireGuard VPN 网络前, 还早已建立了一条 EasyTier 骨干网. 所以这里 IP 地址的最后 8 bit 也按照 EasyTier 骨干网段的地址给. 因此, IEPL 的地址就是 &lt;code&gt;10.0.1.106&lt;/code&gt;, IX 前置的地址为 &lt;code&gt;10.0.1.1&lt;/code&gt;, 个人内网网关的地址为 &lt;code&gt;10.0.1.254&lt;/code&gt;.
设计完成后, 正式开始建立 Peer.&lt;/p&gt;
&lt;h4&gt;2.3 建立 WireGuard Peer&lt;a href=&quot;#23-建立-wireguard-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;h5&gt;2.3.1 建立专线 Peer&lt;a href=&quot;#231-建立专线-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;因为 IX 类型 IEPL / IPLC 的特殊性, 这里我们需要现在专线机器上创建 WireGuard 服务端, 来让 IX 前置作为客户端接入&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在专线设备上建立 WireGuard 接口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; infra-ixpeer.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;infra-ixpeer&lt;/code&gt; 作为 WireGuard 接口名称, 您可以自行定义, 但注意不要太长.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;在配置文件中按照这个模板进行创建&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;port&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;privKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ix_pubKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;vpn_net_CIDR&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ipAddr&lt;/code&gt; 专线服务器 VPN 内网地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt; 专线服务器监听端口. 注意: 专线服务器的 IX 入口通常是 NAT 类型, 且只有 ~1000 个端口可以直接连接. &lt;strong&gt;这里的监听端口一定要在这 ~1000 个可以直接连接的端口中选用&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;privKey&lt;/code&gt; 专线服务器 WireGuard 私钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ix_pubKey&lt;/code&gt; IX 前置的 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vpn_net_CIDR&lt;/code&gt; CIDR 格式的整个 VPN 内网地址段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.106/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 16601&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.0/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置开机自动启动并启动端口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; wg-quick@infra-ixpeer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;创建完成后可以输入 &lt;code&gt;wg&lt;/code&gt; 来查看接口是否生效&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@NB-JPIEPL01:/etc/wireguard#&lt;/span&gt;&lt;span&gt; wg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;interface:&lt;/span&gt;&lt;span&gt; infra-aliyun&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  private&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  listening&lt;/span&gt;&lt;span&gt; port:&lt;/span&gt;&lt;span&gt; 16601&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;peer:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  endpoint:&lt;/span&gt;&lt;span&gt; 172.16.1.2:51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  allowed&lt;/span&gt;&lt;span&gt; ips:&lt;/span&gt;&lt;span&gt; 10.0.1.0/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  latest&lt;/span&gt;&lt;span&gt; handshake:&lt;/span&gt;&lt;span&gt; 57&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;span&gt; ago&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  transfer:&lt;/span&gt;&lt;span&gt; 430.17&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 119.27&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; sent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  persistent&lt;/span&gt;&lt;span&gt; keepalive:&lt;/span&gt;&lt;span&gt; every&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果可以正常显示接口, 则证明已经生效. 至此, 专线服务器部分配置完成.&lt;/p&gt;
&lt;h5&gt;2.3.2 建立个人网关 Peer&lt;a href=&quot;#232-建立个人网关-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;我们自己的服务器也需要和 IX 前置进行 Peer. 但由于处于家庭宽带/普通企业宽带中的设备通常处于 NAT 环境, 因此这里作为客户端建立单向 WireGuard 连接&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在个人服务器上创建 WireGuard 端口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; infra-ixpeer.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;在配置文件中按照这个模板进行创建&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;privKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ix_pubKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ix_endpoint&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;allowedIPs&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;privKey&lt;/code&gt; 当前服务器 WireGuard 私钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ipAddr&lt;/code&gt; 当前服务器 VPN 内网地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ix_pubKey&lt;/code&gt; IX 前置 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ix_endpoint&lt;/code&gt; IX 前置 WireGuard 监听地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;allowedIPs&lt;/code&gt; 允许通过 WireGuard 接入的 IP 地址段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.254/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.64.1:51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.10.64.0/24, 10.0.1.0/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置开机自动启动并启动端口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; wg-quick@infra-ixpeer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;创建完成后可以输入 &lt;code&gt;wg&lt;/code&gt; 来查看接口是否生效&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-Home:/etc/wireguard#&lt;/span&gt;&lt;span&gt; wg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;interface:&lt;/span&gt;&lt;span&gt; jp_iepl01&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  private&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  listening&lt;/span&gt;&lt;span&gt; port:&lt;/span&gt;&lt;span&gt; 46997&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;peer:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  endpoint:&lt;/span&gt;&lt;span&gt; 8.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;:51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  allowed&lt;/span&gt;&lt;span&gt; ips:&lt;/span&gt;&lt;span&gt; 10.10.64.0/24,&lt;/span&gt;&lt;span&gt; 10.0.1.0/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  latest&lt;/span&gt;&lt;span&gt; handshake:&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; minute,&lt;/span&gt;&lt;span&gt; 14&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;span&gt; ago&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  transfer:&lt;/span&gt;&lt;span&gt; 402.16&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 149.66&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; sent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  persistent&lt;/span&gt;&lt;span&gt; keepalive:&lt;/span&gt;&lt;span&gt; every&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;至此, 个人网关 Peer 就配置完成了.&lt;/p&gt;
&lt;h5&gt;2.3.3 建立 IX Peer&lt;a href=&quot;#233-建立-ix-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;我们的目的是要让 IX 前置作为一跳 (hop) 去为我们自己的机器提供路由, 所以这里我们使用 IX 前置作为控制平面, 来与其他设备建立 Peer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 IX 前置中创建 WireGuard 接口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; infra-ixpeer.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;在配置文件中按照这个模板进行创建&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;privKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr&amp;gt;/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;port&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostUp&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -I FORWARD -i %i -j ACCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostUp&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -I FORWARD -o %i -j ACCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostDown&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -D FORWARD -i %i -j ACCEPT 2&amp;gt;/dev/null || true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostDown&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -D FORWARD -o %i -j ACCEPT 2&amp;gt;/dev/null || true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;iepl_pubKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;iepl_endpoint&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;iepl_allowedIPs&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;pubKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;allowedIPs&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;privkey&lt;/code&gt; 本机 WireGuard 私钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ipAddr&lt;/code&gt; 本机 WireGuard 私有地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt; 本机 WireGuard 流量监听地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iepl_pubkey&lt;/code&gt; IEPL 服务器 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iepl_endpoint&lt;/code&gt; IEPL 服务器的 WireGuard 监听地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iepl_allowedIPs&lt;/code&gt; 本机所允许的专线服务器输入 IP 地址段. 如果您只想和 IEPL 服务器做通信, 则填入专线服务器的 WireGuard 私有地址即可, 如果想让专线服务器作为路由设备, 则需要填写对应的网段. 所有 IP 地址都应符合 CIDR 格式. 本文对应的情况为后者.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pubkey&lt;/code&gt; 您的个人境内私有服务器/网关设备 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;allowedIPs&lt;/code&gt; 您的个人境内私有服务器/网关设备 WireGuard 地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.1/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1420&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostUp&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -I FORWARD -i %i -j ACCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostUp&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -I FORWARD -o %i -j ACCEPT&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostDown&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -D FORWARD -i %i -j ACCEPT 2&amp;gt;/dev/null || true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PostDown&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; iptables -D FORWARD -o %i -j ACCEPT 2&amp;gt;/dev/null || true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 114.***.***.***:16601&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.10.64.0/24, 192.168.0.0/16, 10.0.1.106/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ***&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.254/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置开机自动启动并启动端口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; wg-quick@infra-ixpeer&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;创建完成后可以输入 &lt;code&gt;wg&lt;/code&gt; 来查看接口是否生效&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Aliyun-SH:/etc/wireguard#&lt;/span&gt;&lt;span&gt; wg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;interface:&lt;/span&gt;&lt;span&gt; bridge_iepl&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  public&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  private&lt;/span&gt;&lt;span&gt; key:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  listening&lt;/span&gt;&lt;span&gt; port:&lt;/span&gt;&lt;span&gt; 51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;peer:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  endpoint:&lt;/span&gt;&lt;span&gt; 114.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;:16601&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  allowed&lt;/span&gt;&lt;span&gt; ips:&lt;/span&gt;&lt;span&gt; 10.10.64.0/24,&lt;/span&gt;&lt;span&gt; 192.168.0.0/16,&lt;/span&gt;&lt;span&gt; 10.0.1.106/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  latest&lt;/span&gt;&lt;span&gt; handshake:&lt;/span&gt;&lt;span&gt; 18&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;span&gt; ago&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  transfer:&lt;/span&gt;&lt;span&gt; 120.07&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 433.36&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; sent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  persistent&lt;/span&gt;&lt;span&gt; keepalive:&lt;/span&gt;&lt;span&gt; every&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;peer:&lt;/span&gt;&lt;span&gt; (hidden)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  endpoint:&lt;/span&gt;&lt;span&gt; 112.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;***&lt;/span&gt;&lt;span&gt;:40849&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  allowed&lt;/span&gt;&lt;span&gt; ips:&lt;/span&gt;&lt;span&gt; 10.0.1.254/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  latest&lt;/span&gt;&lt;span&gt; handshake:&lt;/span&gt;&lt;span&gt; 35&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;span&gt; ago&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  transfer:&lt;/span&gt;&lt;span&gt; 151.40&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 402.07&lt;/span&gt;&lt;span&gt; KiB&lt;/span&gt;&lt;span&gt; sent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  persistent&lt;/span&gt;&lt;span&gt; keepalive:&lt;/span&gt;&lt;span&gt; every&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;span&gt; seconds&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果两个接口的 &lt;code&gt;transfer&lt;/code&gt; 字段中 &lt;code&gt;received&lt;/code&gt; 前有流量, 则证明通信正常. 此时可以通过 &lt;code&gt;ping&lt;/code&gt; 命令验证通信&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@Aliyun-SH:/etc/wireguard#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 10.0.1.106&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 10.0.1.106&lt;/span&gt;&lt;span&gt; (10.0.1.106) 56(&lt;/span&gt;&lt;span&gt;84&lt;/span&gt;&lt;span&gt;) bytes of data.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.106:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;4.53&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.106:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;4.19&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.106:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;4.22&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.106:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;4.30&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 10.0.1.106&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 3003ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 4.190/4.309/4.527/0.131&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;root@Aliyun-SH:/etc/wireguard#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 10.0.1.4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 10.0.1.4&lt;/span&gt;&lt;span&gt; (10.0.1.4) 56(&lt;/span&gt;&lt;span&gt;84&lt;/span&gt;&lt;span&gt;) bytes of data.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;17.5&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;17.3&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;17.6&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;17.4&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 10.0.1.4&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 3005ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 17.339/17.471/17.647/0.120&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 两个 Peer 已经成功建立并正常通信. 因为博主这里是建立在网关上的, 所以可以直接使用下级设备尝试与专线服务器进行通信
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/324-1.png&quot; alt=&quot;两个 WireGuard Peer 建立后的 ping 测试结果&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;两个 WireGuard Peer 建立后的 ping 测试结果&lt;/figcaption&gt;&lt;/figure&gt;
一切正常!&lt;p&gt;&lt;/p&gt;
&lt;h5&gt;2.3.4 建立境外服务器间 WireGuard Peer&lt;a href=&quot;#234-建立境外服务器间-wireguard-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h5&gt;
&lt;p&gt;为了使境外服务器之间能够联通, 且不受系统路由表干扰, 这里我们需要将每个境外服务器都加入到当前的 WireGuard 网络中.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在境外其他普通服务器上创建接口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/wireguard&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; intra-iepl.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照该模板创建配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;privKey&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;port&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1450&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;pubKey_iepl&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;wgNet/CIDR&amp;gt;, &amp;lt;domesticNet/CIDR&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;privKey&lt;/code&gt; 当前设备的 WireGuard 私钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ipAddr&lt;/code&gt; 当前设备的 WireGuard 内网地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt; 当前设备的 WireGuard 监听端口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pubKey_iepl&lt;/code&gt; 专线服务器的 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;wgNet/CIDR&lt;/code&gt; CIDR 格式的 WireGuard 网段&lt;/li&gt;
&lt;li&gt;&lt;code&gt;domesticNet/CIDR&lt;/code&gt; CIDR 格式的境内代理网段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Interface&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PrivateKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Address&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ListenPort&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;MTU&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1450&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.0/24, 192.168.1.0/24&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;启动该端口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; --now&lt;/span&gt;&lt;span&gt; wg-quick@intra-iepl&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果没有报错则启动完成&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在专线服务器的 &lt;code&gt;intra-ixpeers.conf&lt;/code&gt; 中添加配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;pubKey_global&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr_global&amp;gt;:&amp;lt;port&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; &amp;lt;ipAddr_wg&amp;gt;/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pubKey_global&lt;/code&gt; 先前配置的境外服务器的 WireGuard 公钥&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ipAddr_global&lt;/code&gt; 先前配置的境外服务器的公网 IP 地址, 可以是域名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port&lt;/code&gt; 先前配置的境外服务器的 WireGuard 监听地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ipAddr_wg&lt;/code&gt; 先前配置的境外服务器的 WireGuard 内网地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Peer&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PublicKey&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Endpoint&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; v4.sb1.jp.nanami.tech:51132&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;AllowedIPs&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 10.0.1.103/32&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PersistentKeepalive&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 25&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;重启接口&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;span&gt; wg-quick@intra-ixpeers&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;重启后检查连通性&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@NB-JPIEPL01:/etc/wireguard#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;span&gt; (10.0.1.103) 56(&lt;/span&gt;&lt;span&gt;84&lt;/span&gt;&lt;span&gt;) bytes of data.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;29.0&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;28.8&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;28.9&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;28.8&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;29.1&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 4007ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 28.780/28.904/29.060/0.098&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;至此, 设备连接完成.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意: 这样的操作在添加的每一台设备添加时都需要执行.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;3. 建立 OSPF Peer&lt;a href=&quot;#3-建立-ospf-peer&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;3.1 安装 BIRD&lt;a href=&quot;#31-安装-bird&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;既然我们的目的是将专线服务器作为中转来连接我们境外的其他服务器, 那么我们就需要将这台专线服务器配置成一台路由器, 来帮我们转发业务流量. 这里我们使用 &lt;code&gt;BIRD v2&lt;/code&gt; 来将其配置为路由器.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;您需要在您的私人服务器/网关和专线服务器上安装 BIRD&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;使用这几条指令安装最新版本 BIRD v2&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; apt-transport-https&lt;/span&gt;&lt;span&gt; ca-certificates&lt;/span&gt;&lt;span&gt; wget&lt;/span&gt;&lt;span&gt; lsb-release&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; wget&lt;/span&gt;&lt;span&gt; -O&lt;/span&gt;&lt;span&gt; /usr/share/keyrings/cznic-labs-pkg.gpg&lt;/span&gt;&lt;span&gt; https://pkg.labs.nic.cz/gpg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;deb [signed-by=/usr/share/keyrings/cznic-labs-pkg.gpg] https://pkg.labs.nic.cz/bird2 &lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;lsb_release&lt;/span&gt;&lt;span&gt; -sc&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; main&quot;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; tee&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/cznic-labs-bird2.list&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; bird2&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;指令转载至 &lt;a href=&quot;https://blog.iyoroy.cn/archives/103/&quot;&gt;DN42 探究日记 - Ep.2 通过 OSPF 搭建内部网络并启用 iBGP - iYoRoy Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;输入这条指令验证安装&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;bird&lt;/span&gt;&lt;span&gt; --version&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;示例输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@NB-JPIEPL01:/etc/bird#&lt;/span&gt;&lt;span&gt; bird&lt;/span&gt;&lt;span&gt; --version&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; version&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果没有报错, 则安装结束&lt;/p&gt;
&lt;h4&gt;3.2 配置专线服务器&lt;a href=&quot;#32-配置专线服务器&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;备份核心配置文件并创建新配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/bird&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; bird.conf&lt;/span&gt;&lt;span&gt; bird.conf.bak&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; bird.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照如下示例创建配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;log syslog all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define ROUTER_ID                = &amp;lt;routerID&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNAS              = &amp;lt;ownAS&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNIP              = &amp;lt;ownIP&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNNET             = &amp;lt;ownNet/CIDR&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNSET             = &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt; &amp;lt;ownSet/CIDR+&amp;gt; &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol device &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    scan time 10;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol direct &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;kernel.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;ospf.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;routerID&lt;/code&gt; 该服务器运行在所有协议中的 Router ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ownAS&lt;/code&gt; 该服务器的 AS Number. 因为此处我们配置的是内网而非 IANA/DN42, 所以我们这里需要填写私有 ASN. 私有 ASN 的范围是 &lt;code&gt;64512&lt;/code&gt;-&lt;code&gt;65534&lt;/code&gt;, 在这里取用即可.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ownIP&lt;/code&gt; 该服务器在您想代理的网段中的 IP. 在本文的环境中, 我们填写这台服务器在境外 VPN 骨干网的 IP 地址.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ownNet/CIDR&lt;/code&gt; 您所填写的 IP 地址的整个网段. 在本文的环境中, 我们填写整个境外 VPN 骨干网的 IP 地址段.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ownSet/CIDR+&lt;/code&gt; 您所想引入的所有网段. 这里需要填写您未来会引入的所有地址段信息.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 BIRD 配置文件中, &lt;code&gt;define&lt;/code&gt; 用于声明全局变量, 故这里的 &lt;code&gt;INTRA_OWNAS&lt;/code&gt;, &lt;code&gt;INTRA_OWNIP&lt;/code&gt; 等字段均为全局变量, 在其他的配置文件中均可调用
&lt;code&gt;bird.conf&lt;/code&gt; 为 BIRD 主要配置文件, BIRD 启动时只会读取这里的配置信息. &lt;code&gt;include&lt;/code&gt; 则用于在该文件中引入其他配置文件. 因此 &lt;code&gt;kernel.conf&lt;/code&gt;, &lt;code&gt;ospf.conf&lt;/code&gt; 均为引入的文件.&lt;/p&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;log syslog all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define ROUTER_ID                = &lt;/span&gt;&lt;span&gt;10.10&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.106&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNAS              = &lt;/span&gt;&lt;span&gt;65534&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNIP              = &lt;/span&gt;&lt;span&gt;10.10&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.106&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNNET             = &lt;/span&gt;&lt;span&gt;10.10&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNSET             = &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt; 192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;20.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 10.0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 10.10&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+ &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol device &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    scan time 10;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol direct &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;defs.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;ospf.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;保存后, 在相同目录下创建 &lt;code&gt;defs.conf&lt;/code&gt;, 写入如下内容&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;function is_intra_net&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return net ~ INTRA_OWNSET;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;保存后, 在相同目录下创建 &lt;code&gt;ospf.conf&lt;/code&gt;, 写入如下内容&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;protocol ospf v&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ospf_intra &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    router id ROUTER_ID;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import where is_intra_net4();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export filter {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                if source = RTS_DEVICE &amp;amp;&amp;amp; net ~ &amp;lt;ipAddr/CIDR&amp;gt; then accept;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                reject;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    include &lt;/span&gt;&lt;span&gt;&quot;/etc/bird/ospf/*&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;ipAddr/CIDR&lt;/code&gt; 境内私人服务器/网关所代理的网段&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;创建 OSPF 配置文件夹和 Area 0 的配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; ospf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; ospf/0.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照以下模板写入配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;area &lt;/span&gt;&lt;span&gt;0.0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0.0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    interface &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;intra-ixpeers&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        type ptmp;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ttl security tx only;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        neighbors {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;lt;ipAddr_domestic&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;ipAddr_domestic&lt;/code&gt; 境内私人服务器/网关的 WireGuard 地址&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;应用配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果得到如下输出, 则应用成功&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reading&lt;/span&gt;&lt;span&gt; configuration&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; /etc/bird/bird.conf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reconfiguration&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;此时查看具体协议状态&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt; p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;得到如下输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;span&gt;       Proto&lt;/span&gt;&lt;span&gt;      Table&lt;/span&gt;&lt;span&gt;      State&lt;/span&gt;&lt;span&gt;  Since&lt;/span&gt;&lt;span&gt;         Info&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;device1&lt;/span&gt;&lt;span&gt;    Device&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;direct1&lt;/span&gt;&lt;span&gt;    Direct&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v4&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v6&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ospf_intra&lt;/span&gt;&lt;span&gt; OSPF&lt;/span&gt;&lt;span&gt;       master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-16&lt;/span&gt;&lt;span&gt;    Alone&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到此时 OSPF 的状态为 &lt;code&gt;Alone&lt;/code&gt;, 这是因为目前只有这一台设备在运行 OSPF, 还没有其他 Peer. 所以下一步我们来配置境内服务器/网关的 OSPF.&lt;/p&gt;
&lt;h4&gt;3.3 配置境内服务器/网关&lt;a href=&quot;#33-配置境内服务器网关&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;备份核心配置文件并创建新配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /etc/bird&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; bird.conf&lt;/span&gt;&lt;span&gt; bird.conf.bak&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; bird.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照如下示例创建配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;log syslog all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define ROUTER_ID                = &amp;lt;routerID&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNAS              = &amp;lt;ownAS&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNIP              = &amp;lt;ownIP&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNNET             = &amp;lt;ownNet/CIDR&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNSET             = &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt; &amp;lt;ownSet/CIDR+&amp;gt; &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol device &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    scan time 10;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol direct &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;kernel.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;ospf.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;示例配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;log syslog all;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define ROUTER_ID                = &lt;/span&gt;&lt;span&gt;10.0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.254&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNAS              = &lt;/span&gt;&lt;span&gt;65534&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNIP              = &lt;/span&gt;&lt;span&gt;192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1.1&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNNET             = &lt;/span&gt;&lt;span&gt;192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;define INTRA_OWNSET             = &lt;/span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt; 192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;1.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 192.168&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;20.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 10.0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; 10.10&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;64.0&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;24&lt;/span&gt;&lt;span&gt;+ &lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol device &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    scan time 10;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol direct &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv6;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;kernel.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;defs.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;include &lt;/span&gt;&lt;span&gt;&quot;ospf.conf&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;保存后, 在相同目录下创建 &lt;code&gt;defs.conf&lt;/code&gt;, 写入如下内容&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;function is_intra_net&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;() &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return net ~ INTRA_OWNSET;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;保存后, 在相同目录下创建 &lt;code&gt;ospf.conf&lt;/code&gt;, 写入如下内容&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;protocol ospf v&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ospf_intra &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    router id ROUTER_ID;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ipv4 {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        import where is_intra_net4();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        export filter {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                if source = RTS_DEVICE &amp;amp;&amp;amp; net ~ &amp;lt;ipAddr/CIDR&amp;gt; then accept;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;                reject;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    include &lt;/span&gt;&lt;span&gt;&quot;/etc/bird/ospf/*&quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;ipAddr/CIDR&lt;/code&gt; 境内私人服务器/网关所代理的网段&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;创建 OSPF 配置文件夹和 Area 0 的配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; ospf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; ospf/0.conf&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照以下模板写入配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;area &lt;/span&gt;&lt;span&gt;0.0&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;0.0&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    interface &lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt;intra-ixpeers&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        type ptmp;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ttl security tx only;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        neighbors {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            &amp;lt;ipAddr_domestic&amp;gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    };&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;ipAddr_domestic&lt;/code&gt; 境内私人服务器/网关的 WireGuard 地址&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;应用配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; c&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;如果得到如下输出, 则应用成功&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reading&lt;/span&gt;&lt;span&gt; configuration&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; /etc/bird/bird.conf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reconfiguration&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;此时查看具体协议状态&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;birdc&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt; p&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;得到如下输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.19.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;span&gt;       Proto&lt;/span&gt;&lt;span&gt;      Table&lt;/span&gt;&lt;span&gt;      State&lt;/span&gt;&lt;span&gt;  Since&lt;/span&gt;&lt;span&gt;         Info&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;device1&lt;/span&gt;&lt;span&gt;    Device&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;direct1&lt;/span&gt;&lt;span&gt;    Direct&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v4&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v6&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-07&lt;/span&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ospf_intra&lt;/span&gt;&lt;span&gt; OSPF&lt;/span&gt;&lt;span&gt;       master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     2026-07-16&lt;/span&gt;&lt;span&gt;    Running&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;可以看到, 此时 OSPF 协议状态为 &lt;code&gt;Running&lt;/code&gt;, 则表明成功与境外专线服务器建立 Peer. 此时双方的配置均已完成.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;4. 测试&lt;a href=&quot;#4-测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在境外专线服务器对境内设备进行联通测试&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@NB-JPIEPL01:~#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 192.168.1.4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 192.168.1.4&lt;/span&gt;&lt;span&gt; (192.168.1.4) 56(&lt;/span&gt;&lt;span&gt;84&lt;/span&gt;&lt;span&gt;) bytes of data.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;24.5&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;24.1&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;24.4&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;24.4&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; icmp_seq=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;24.7&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;^C&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 192.168.1.4&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss,&lt;/span&gt;&lt;span&gt; time&lt;/span&gt;&lt;span&gt; 4006ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rtt&lt;/span&gt;&lt;span&gt; min/avg/max/mdev&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 24.087/24.400/24.713/0.199&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;在境内服务器对境外设备进行联通测试&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-Home:/etc/wireguard#&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;PING&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;span&gt; (10.0.1.103): 56 data bytes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; seq=&lt;/span&gt;&lt;span&gt;0&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;53.015&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; seq=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;53.352&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; seq=&lt;/span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;53.052&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;64&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 10.0.1.103:&lt;/span&gt;&lt;span&gt; seq=&lt;/span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt; ttl=&lt;/span&gt;&lt;span&gt;62&lt;/span&gt;&lt;span&gt; time=&lt;/span&gt;&lt;span&gt;53.209&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;span&gt; 10.0.1.103&lt;/span&gt;&lt;span&gt; ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; ---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; transmitted,&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; packets&lt;/span&gt;&lt;span&gt; received,&lt;/span&gt;&lt;span&gt; 0%&lt;/span&gt;&lt;span&gt; packet&lt;/span&gt;&lt;span&gt; loss&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;round-trip&lt;/span&gt;&lt;span&gt; min/avg/max&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 53.015/53.157/53.352&lt;/span&gt;&lt;span&gt; ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 两边都成功联通并稳定. 至此, 配置全部结束&lt;/p&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业人员, 如有疏漏或错误请指出! 感谢您的阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/216/&quot;&gt;OpenWrt 基于 BIRD 的 OSPF 组网&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/331/&quot;&gt;OSPFv3 + WireGuard 借用 IPv6 出口&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/318/&quot;&gt;EasyTier 参数导致 iBGP 崩溃排查&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category><category>tag:运维</category></item><item><title>EasyTier 参数导致 iBGP 崩溃排查</title><link>https://blog.nanami.tech/en/archives/318</link><guid isPermaLink="false">en:318</guid><description>前言
博主某天在查看自己 DN42 的 Looking Glass 时, 发现几个用于 ASN 内传输路由的 iBGP 协议全部处于 Connection closed 状态, 导致了 ASN 内部无法正常传输路由. 在检查了各项配置且尝试重启无果之后, 意识到这貌似并不是什么简单的问题,</description><pubDate>Thu, 28 May 2026 11:43:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主某天在查看自己 &lt;a href=&quot;https://blog.nanami.tech/dn42.html&quot;&gt;DN42&lt;/a&gt; 的 &lt;a href=&quot;https://dn42-lg.nanami.tech/&quot;&gt;Looking Glass&lt;/a&gt; 时, 发现几个用于 ASN 内传输路由的 iBGP 协议全部处于 &lt;code&gt;Connection closed&lt;/code&gt; 状态, 导致了 ASN 内部无法正常传输路由. 在检查了各项配置且尝试重启无果之后, 意识到这貌似并不是什么简单的问题, 遂尝试解决.&lt;/p&gt;
&lt;h2&gt;网络状态&lt;a href=&quot;#网络状态&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;各节点 BIRD: 正常&lt;/li&gt;
&lt;li&gt;iBGP 节点间通信: 正常&lt;/li&gt;
&lt;li&gt;iBGP Peer 协商: &lt;strong&gt;不正常&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;网络架构描述&lt;a href=&quot;#网络架构描述&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;iBGP Peer 一共有五台设备, 一台设备处于境内, 与其他四台设备建立 Peer, 其他四台设备处于境外, 这四台设备之间互相不 Peer. 且每台设备都与若干 eBGP 节点进行了 Peer.&lt;/p&gt;
&lt;h3&gt;已确认的部分&lt;a href=&quot;#已确认的部分&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;iBGP 节点间 ASN 相同&lt;/li&gt;
&lt;li&gt;iBGP Peer 的 IP 地址配置无误&lt;/li&gt;
&lt;li&gt;节点间防火墙配置无误&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;问题分析&lt;a href=&quot;#问题分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;iBGP Peer 不成立通常可能是以下几个原因导致的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Router ID&lt;/code&gt; 冲突&lt;/li&gt;
&lt;li&gt;Peer IP 地址不匹配&lt;/li&gt;
&lt;li&gt;TCP MD5 密码不匹配&lt;/li&gt;
&lt;li&gt;使用 &lt;code&gt;LoopBack&lt;/code&gt; 建立连接时, BGP 多跳未配置&lt;/li&gt;
&lt;li&gt;监听地址与端口不匹配或配置错误&lt;/li&gt;
&lt;li&gt;某一方 BGP 会话未启动&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Hold Time&lt;/code&gt; 协商问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面我们一个一个进行分析&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由于这些 iBGP Peer 的情况都大致相同, 且配置也大致相同. 因此每一步的验证仅取其中一对 Peer 进行查看&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;Router ID&lt;/code&gt; 冲突&lt;a href=&quot;#router-id-冲突&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;对双方 Router ID 进行检查&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VM-Sub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@VM-Sub:/etc/bird/ibgp#&lt;/span&gt;&lt;span&gt; birdc&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; &quot;Router ID&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Router&lt;/span&gt;&lt;span&gt; ID&lt;/span&gt;&lt;span&gt; is&lt;/span&gt;&lt;span&gt; 172.23.66.97&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JPSB01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@JPSB01:~#&lt;/span&gt;&lt;span&gt; birdc&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; grep&lt;/span&gt;&lt;span&gt; &quot;Router ID&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Router&lt;/span&gt;&lt;span&gt; ID&lt;/span&gt;&lt;span&gt; is&lt;/span&gt;&lt;span&gt; 45.xxx.xxx.xxx&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以明显看出, 双方 &lt;code&gt;Router ID&lt;/code&gt; 不同, 故不是此问题&lt;/p&gt;
&lt;h3&gt;Peer IP 地址不匹配&lt;a href=&quot;#peer-ip-地址不匹配&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;现在对双方在配置文件中的 Peer IP 进行检查&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;VM-Sub&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@VM-Sub:/etc/bird/ibgp#&lt;/span&gt;&lt;span&gt; cat&lt;/span&gt;&lt;span&gt; sb1-jp.conf&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt; bgp&lt;/span&gt;&lt;span&gt; &apos;ibgp_sb1-jp&apos;&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; ibgpeers{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    neighbor&lt;/span&gt;&lt;span&gt; 10.0.64.103&lt;/span&gt;&lt;span&gt; as&lt;/span&gt;&lt;span&gt; DN42_OWNAS&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;JPSB01&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@ACCK-JPSB01:/etc/bird/ibgp#&lt;/span&gt;&lt;span&gt; cat&lt;/span&gt;&lt;span&gt; homelab-subserver.conf&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;protocol&lt;/span&gt;&lt;span&gt; bgp&lt;/span&gt;&lt;span&gt; &apos;ibgp_homelab-subserver&apos;&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; ibgpeers{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    neighbor&lt;/span&gt;&lt;span&gt; 10.0.64.4&lt;/span&gt;&lt;span&gt; as&lt;/span&gt;&lt;span&gt; DN42_OWNAS&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;双方的 IP 地址均为 WireGuard VPN 内网中的 IP 地址, 因此互相连接时, 源 IP 地址肯定是 VPN 网络中的 IP 地址, 因此不是这个问题.&lt;/p&gt;
&lt;h3&gt;TCP MD5 密码不匹配&lt;a href=&quot;#tcp-md5-密码不匹配&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;iBGP Peer 间未单独配置密码, 故不是该问题&lt;/p&gt;
&lt;h3&gt;使用 &lt;code&gt;LoopBack&lt;/code&gt; 建立连接时, BGP 多跳未配置&lt;a href=&quot;#使用-loopback-建立连接时-bgp-多跳未配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;iBGP 使用直连连接, 未使用 &lt;code&gt;LoopBack&lt;/code&gt; 接口, 连接只有一跳, 故不是该问题&lt;/p&gt;
&lt;h3&gt;监听地址与端口不匹配或配置错误&lt;a href=&quot;#监听地址与端口不匹配或配置错误&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;监听地址和端口均为进行修改, 所有配置为 BIRD 默认, 故不存在该问题&lt;/p&gt;
&lt;h3&gt;某一方 BGP 会话未启动&lt;a href=&quot;#某一方-bgp-会话未启动&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;双方 BGP 会话均启动, 故不是该问题&lt;/p&gt;
&lt;h2&gt;深入排查&lt;a href=&quot;#深入排查&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;现在, 所有可能的原因都排查完了, 但问题还未解决. 还剩怎么排查呢? 我们可以抓包查看具体通信报文是什么. 这里使用 &lt;code&gt;tcpdump&lt;/code&gt; 对 179 端口进行监听, 并输出 &lt;code&gt;pcap&lt;/code&gt; 文件&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tcpdump&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; any&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt; 179&lt;/span&gt;&lt;span&gt; -vvv&lt;/span&gt;&lt;span&gt; -s0&lt;/span&gt;&lt;span&gt; -w&lt;/span&gt;&lt;span&gt; bgp.pcap&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;等待一段时间后, 使用 Wireshark 打开该文件查看报文
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/318-1.png&quot; alt=&quot;Wireshark 中抓取的 BGP 179 端口报文&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Wireshark 中抓取的 BGP 179 端口报文&lt;/figcaption&gt;&lt;/figure&gt;
这就是具体抓到的数据包. 现在我们过滤所有 eBGP 报文, 仅查看需要检查的两个 iBGP Peer 之间的报文. 使用这个过滤器&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;ip.addr&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 10.0.64.4&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; ip.addr&lt;/span&gt;&lt;span&gt; ==&lt;/span&gt;&lt;span&gt; 10.0.64.103&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/318-2.png&quot; alt=&quot;过滤两个 iBGP Peer 之间的报文&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;过滤两个 iBGP Peer 之间的报文&lt;/figcaption&gt;&lt;/figure&gt;
在这份数据包中我们可以看到, &lt;code&gt;10.0.64.4&lt;/code&gt; 多次尝试向 &lt;code&gt;10.0.64.103&lt;/code&gt; 发送 &lt;code&gt;OPEN&lt;/code&gt; 报文, 但最终会被 &lt;code&gt;10.0.64.4&lt;/code&gt; 发送 &lt;code&gt;RST&lt;/code&gt; 报文, 整个连接被重置, 最终导致 BIRD 报错 &lt;code&gt;Connection closed&lt;/code&gt;.&lt;p&gt;&lt;/p&gt;
&lt;p&gt;现在, 我们重新在 &lt;code&gt;10.0.64.103&lt;/code&gt; 上进行抓包, 结果如下
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/318-3.png&quot; alt=&quot;在 10.0.64.103 上抓取到的 TCP 重置报文&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;在 10.0.64.103 上抓取到的 TCP 重置报文&lt;/figcaption&gt;&lt;/figure&gt;
可以看到, 无论是 &lt;code&gt;10.0.64.4&lt;/code&gt; 还是 &lt;code&gt;10.0.64.60&lt;/code&gt;, &lt;strong&gt;均只对对方的 TCP 报文进行了处理, 没有任何 BGP 层的处理.&lt;/strong&gt; 这很奇怪, 如果问题出现在 BGP 层, 那么应该由其中一方发送 &lt;code&gt;BGP Notification&lt;/code&gt; 报文来终止连接, 而不是 &lt;code&gt;TCP Reset&lt;/code&gt;.&lt;p&gt;&lt;/p&gt;
&lt;p&gt;鉴于这个问题是&lt;em&gt;突然出现&lt;/em&gt;的, 所以我们来审视一下问题出现的前后, 我都对网络做了什么改动. 回想了一下, 在这期间我对网络做的唯一改动就是 &lt;strong&gt;将 EasyTier VPN 的部署从 &lt;em&gt;直接在 &lt;code&gt;systemd&lt;/code&gt; 服务中将具体配置参数输入给 EasyTier 二进制程序&lt;/em&gt; 改为了 &lt;em&gt;通过将具体配置写进配置文件再送给 EasyTier 处理&lt;/em&gt;.&lt;/strong&gt; 在配置文件中, 我多加上了这么几条参数&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;flags&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;enable_kcp_proxy&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;enable_quic_proxy&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;latency_first&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;private_mode&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;我们逐个检查这些 flag 会实现什么功能&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;enable_kcp_proxy&lt;/code&gt; 启用 KCP 代理. 将 TCP 连接使用 KCP 协议进行代理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;该功能虽然会改变 TCP 流量的传输方式, 但不改变原始 TCP 报文, 所以不会造成影响.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;enable_quic_proxy&lt;/code&gt; 启用 QUIC 代理. 将 TCP 连接使用 QUIC 协议进行代理&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;该功能虽然会改变 TCP 流量的传输方式, 但不改变原始 TCP 报文, 所以不会造成影响.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;latency_first&lt;/code&gt; 延迟优先. 无视 TTL 跳数, 始终优先使用延迟最短的路径转发流量&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;该功能虽然达到了最小延迟的目的, &lt;strong&gt;但可能会增加 TTL 跳数.&lt;/strong&gt; 从上面的配置文件可以看出, 配置里并没有单独配置 &lt;code&gt;max-hop&lt;/code&gt;, 这可能造成连接失败.&lt;/p&gt;
&lt;p&gt;我们来测试一下双方互通的跳数&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;10.0.64.4&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;traceroute&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (10.0.64.60), 30 hops max, 60 byte packets&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;  10.0.64.60&lt;/span&gt;&lt;span&gt; (10.0.64.60)  14.478 ms  14.476 ms  14.463 ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;10.0.64.60&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;traceroute&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; 10.0.64.4&lt;/span&gt;&lt;span&gt; (10.0.64.4), 30 hops max, 60 byte packets&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;  10.0.64.4&lt;/span&gt;&lt;span&gt; (10.0.64.4)  13.845 ms  14.444 ms  14.378 ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;这里可以看到, 两台机器虽然均开启了 &lt;code&gt;latency_first&lt;/code&gt;, 但双方的跳数仍为 &lt;code&gt;1&lt;/code&gt;, 不会造成 iBGP 故障. 但保险起见, 我们还是把这项功能关掉.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;private_mode&lt;/code&gt; 隐私模式. 不允许任何非相同网络的节点使用该节点建立连接或转发流量&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;顾名思义, 这项功能是为了防止外部未知设备在未经允许的情况下借助这个节点进行 VPN 网络搭建或流量转发, 但在我查询 AI 后, 它告诉我&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Root&lt;/span&gt;&lt;span&gt; cause:&lt;/span&gt;&lt;span&gt; EasyTier&apos;s private_mode with KCP/QUIC proxy rewrites the source IP of incoming BGP connections to&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  10.0.64.60 (this machine&apos;s&lt;/span&gt;&lt;span&gt; own&lt;/span&gt;&lt;span&gt; tunnel&lt;/span&gt;&lt;span&gt; IP&lt;/span&gt;&lt;span&gt;). BIRD rejects these because it only knows about neighbor&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  10.0.64.4.&lt;/span&gt;&lt;span&gt; The&lt;/span&gt;&lt;span&gt; same&lt;/span&gt;&lt;span&gt; issue&lt;/span&gt;&lt;span&gt; likely&lt;/span&gt;&lt;span&gt; affects&lt;/span&gt;&lt;span&gt; 10.0.64.4&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; reverse,&lt;/span&gt;&lt;span&gt; so&lt;/span&gt;&lt;span&gt; both&lt;/span&gt;&lt;span&gt; directions&lt;/span&gt;&lt;span&gt; fail.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;底层原因: EasyTier 的 &lt;code&gt;private_mode&lt;/code&gt; 通过 &lt;code&gt;KCP&lt;/code&gt;/&lt;code&gt;QUIC&lt;/code&gt; 代理时会 &lt;strong&gt;重写连入 BGP 连接的源 IP 地址&lt;/strong&gt; 到 &lt;code&gt;10.0.64.60&lt;/code&gt; (这台机器的私有隧道 IP). BIRD 拒绝了这些连接, 因为它只知道邻居的地址 &lt;code&gt;10.0.64.4&lt;/code&gt;. 相同的问题也影响了 &lt;code&gt;10.0.64.4&lt;/code&gt;, 故两边均失败了.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;figure&gt;&lt;img src=&quot;/images/318-4.png&quot; alt=&quot;EasyTier 改写 BGP 连接源 IP 的示意&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;EasyTier 改写 BGP 连接源 IP 的示意&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;由此我们可以得知, 当某一方的 BGP 连接传入时, EasyTier 会先将 IP 数据包中的 &lt;strong&gt;源 IP 地址&lt;/strong&gt; 改为本机隧道地址, 然后再被 BIRD 接收.&lt;/p&gt;
&lt;p&gt;为了验证是不是为这个问题, 我们在 &lt;code&gt;10.0.64.60&lt;/code&gt; 中查看 BIRD 的日志&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@SchoolNode-Main:/home/nanami114/PersonalFiles/easytier/configs#&lt;/span&gt;&lt;span&gt; journalctl&lt;/span&gt;&lt;span&gt; -xeu&lt;/span&gt;&lt;span&gt; bird&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:50:58&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;39138&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:03&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;56654&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:07&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;56670&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:11&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;56676&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:15&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;44306&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:19&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;44320&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:23&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;38916&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:27&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;38924&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:31&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;38930&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:35&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;37640&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:40&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;37656&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:44&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;48124&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:49&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;48128&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:53&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;55374&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:51:58&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;55388&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:02&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;39252&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:07&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;39266&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:11&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;39270&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:15&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;33950&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:20&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;33964&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Jun&lt;/span&gt;&lt;span&gt; 04&lt;/span&gt;&lt;span&gt; 17:52:24&lt;/span&gt;&lt;span&gt; SchoolNode-Main&lt;/span&gt;&lt;span&gt; bird[2383741]:&lt;/span&gt;&lt;span&gt; BGP:&lt;/span&gt;&lt;span&gt; Unexpected&lt;/span&gt;&lt;span&gt; connect&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; unknown&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt; 10.0.64.60&lt;/span&gt;&lt;span&gt; (port &lt;/span&gt;&lt;span&gt;59404&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以从日志中看到, BIRD 对 &lt;code&gt;10.0.64.60&lt;/code&gt; 传入的连接进行了大量的报错, 由此我们得知, 问题就出在这里!&lt;/p&gt;
&lt;p&gt;现在我们将这项功能关掉, 然后再次查看连接状态&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@SchoolNode-Main:/home/nanami114/PersonalFiles/easytier/configs#&lt;/span&gt;&lt;span&gt; birdc&lt;/span&gt;&lt;span&gt; s&lt;/span&gt;&lt;span&gt; p&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BIRD&lt;/span&gt;&lt;span&gt; 2.18.1&lt;/span&gt;&lt;span&gt; ready.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Name&lt;/span&gt;&lt;span&gt;       Proto&lt;/span&gt;&lt;span&gt;      Table&lt;/span&gt;&lt;span&gt;      State&lt;/span&gt;&lt;span&gt;  Since&lt;/span&gt;&lt;span&gt;         Info&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;device1&lt;/span&gt;&lt;span&gt;    Device&lt;/span&gt;&lt;span&gt;     ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v4&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kernel_v6&lt;/span&gt;&lt;span&gt;  Kernel&lt;/span&gt;&lt;span&gt;     master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;dn42_static_v4&lt;/span&gt;&lt;span&gt; Static&lt;/span&gt;&lt;span&gt;     master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;dn42_static_v6&lt;/span&gt;&lt;span&gt; Static&lt;/span&gt;&lt;span&gt;     master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;dn42_rpki_akix&lt;/span&gt;&lt;span&gt; RPKI&lt;/span&gt;&lt;span&gt;       ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     17:15:39.962&lt;/span&gt;&lt;span&gt;  Established&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ospf_dn42&lt;/span&gt;&lt;span&gt;  OSPF&lt;/span&gt;&lt;span&gt;       master4&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  Alone&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ospf_dn42_v6&lt;/span&gt;&lt;span&gt; OSPF&lt;/span&gt;&lt;span&gt;       master6&lt;/span&gt;&lt;span&gt;    up&lt;/span&gt;&lt;span&gt;     17:15:38.915&lt;/span&gt;&lt;span&gt;  Alone&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ibgp_homelab-subserver&lt;/span&gt;&lt;span&gt; BGP&lt;/span&gt;&lt;span&gt;        ---&lt;/span&gt;&lt;span&gt;        up&lt;/span&gt;&lt;span&gt;     17:54:48.504&lt;/span&gt;&lt;span&gt;  Established&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 此时 iBGP 已经处于了 &lt;code&gt;Established&lt;/code&gt; 状态. 至此, 问题全部解决.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业网络运维, 如有错误或疏漏还请指出! 如果觉得文章不错, 还请分享给有需要的人, 感谢!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/310/&quot;&gt;EasyTier 与 mwan3: VPN 回程路由修复&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/72/&quot;&gt;EasyTier 异地组网 VPN 部署教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/324/&quot;&gt;IX 前置 + OSPF: IEPL 专线组网搭建&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category><category>tag:运维</category></item><item><title>EasyTier 与 mwan3: VPN 回程路由修复</title><link>https://blog.nanami.tech/en/archives/310</link><guid isPermaLink="false">en:310</guid><description>前言
博主使用了 EasyTier 在家, 学校, 境内外公网服务器之间通过 WireGuard 协议建立了一个三层 VPN 网络. 平日里在学校或出门在外都会通过这个 VPN 网络连接家里的设备, 访问家里搭建的业务. 在博主今天尝试在学校连接家里服务器上的 SMB 时, 发现全部连接失败,</description><pubDate>Wed, 27 May 2026 02:48:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主使用了 EasyTier 在家, 学校, 境内外公网服务器之间通过 &lt;code&gt;WireGuard&lt;/code&gt; 协议建立了一个三层 VPN 网络. 平日里在学校或出门在外都会通过这个 VPN 网络连接家里的设备, 访问家里搭建的业务. 在博主今天尝试在学校连接家里服务器上的 SMB 时, 发现全部连接失败, 故着手研究原因.&lt;/p&gt;
&lt;h2&gt;网络拓扑架构&lt;a href=&quot;#网络拓扑架构&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;&lt;img src=&quot;/images/310-1.png&quot; alt=&quot;Topology&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Topology&lt;/figcaption&gt;&lt;/figure&gt;
&lt;ul&gt;
&lt;li&gt;在 HomeLab 中, 有三台设备代理了 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 网段, 即其他设备可以走这三个节点访问该网段. 且对于该网段的访问没有专门的 ACL 限制, 所有设备均可访问&lt;/li&gt;
&lt;li&gt;在校园节点中, 网关代理了 &lt;code&gt;192.168.20.0/24&lt;/code&gt; 网段, 同样可以被所有设备访问&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;链路状态&lt;a href=&quot;#链路状态&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;相关节点状态: HomeLab (在线), Router-School (在线)&lt;/li&gt;
&lt;li&gt;链路通信状态&lt;/li&gt;
&lt;li&gt;校园节点在网关上与 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 段的设备通信正常, 但下游设备与该网段的通信时不正常&lt;/li&gt;
&lt;li&gt;HomeLab 中所有节点的网络通信状态与子网代理状态都是正常的&lt;/li&gt;
&lt;li&gt;疑点: 下游设备与 &lt;code&gt;192.168.1.14/32&lt;/code&gt; 通信时正常, 但与该网段中其他所有设备通信都不正常. 表现为 ICMP Ping 无回包, 业务数据访问不通&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;问题分析&lt;a href=&quot;#问题分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;造成该故障最常见的原因可能有以下几点&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;回程路由缺失&lt;/li&gt;
&lt;li&gt;反向路径过滤 &lt;code&gt;(rp_filter)&lt;/code&gt; 导致回包被丢弃&lt;/li&gt;
&lt;li&gt;IP 转发未开启&lt;/li&gt;
&lt;li&gt;EasyTier 的出口策略 / 策略路由冲突&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我们这边逐个来排查&lt;/p&gt;
&lt;h3&gt;1. 回程路由缺失&lt;a href=&quot;#1-回程路由缺失&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;请求: &lt;code&gt;192.168.20.0/24&lt;/code&gt; → 网关 → &lt;code&gt;tun0&lt;/code&gt; → VPN → &lt;code&gt;192.168.1.0/24&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;回包: &lt;code&gt;192.168.1.0/24&lt;/code&gt; → VPN → 网关 &lt;code&gt;tun0&lt;/code&gt; → ??? → &lt;code&gt;192.168.20.0/24&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;网关自身访问时, 源地址通常是 &lt;code&gt;tun0&lt;/code&gt; 的 IP &lt;code&gt;(10.0.64.253)&lt;/code&gt;, 这个地址天然在 VPN 路由域内, 对端可以直接回包.
而下游设备访问时, 源地址保留为 &lt;code&gt;192.168.20.x&lt;/code&gt;, 如果对端节点没有去往 &lt;code&gt;192.168.20.0/24&lt;/code&gt; 的路由, 回包就会丢失或走默认路由被丢弃.&lt;/p&gt;
&lt;p&gt;这里检查校园网关的路由表&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; ip&lt;/span&gt;&lt;span&gt; rou&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.131.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-wan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 40&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan01&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 41&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan02&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 42&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan03&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 43&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan04&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 44&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.0.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.0.64.253&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.0.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.10.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.131.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-wan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.131.15.37&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan02&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.141.102.228&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan03&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.141.40.183&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan01&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.151.10.205&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan04&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.151.32.226&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;169.254.0.0/16&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 169.254.254.254&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;172.17.0.0/16&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; docker0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 172.17.0.1&lt;/span&gt;&lt;span&gt; linkdown&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.1.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.3.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.20.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 192.168.20.1&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.20.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; bird&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 32&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.100.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, &lt;code&gt;192.168.1.0/24&lt;/code&gt; 正常从 &lt;code&gt;tun0&lt;/code&gt; 出口&lt;/p&gt;
&lt;p&gt;然后检查 HomeLab 节点中设备的路由表&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;nanami114@NanamiWork-Server:~$&lt;/span&gt;&lt;span&gt; ip&lt;/span&gt;&lt;span&gt; rou&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 192.168.1.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; onlink&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.0.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.10.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.1.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; vmbr0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 192.168.1.8&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.3.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.20.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.100.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到这里也是正常的, 因此该原因被排除&lt;/p&gt;
&lt;h3&gt;2. 反向路径过滤 &lt;code&gt;(rp_filter)&lt;/code&gt; 导致回包被丢弃&lt;a href=&quot;#2-反向路径过滤-rp_filter-导致回包被丢弃&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;这里直接检查校园网关的 &lt;code&gt;rp_filter&lt;/code&gt; 策略&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; sysctl&lt;/span&gt;&lt;span&gt; net.ipv4.conf.all.rp_filter&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;net.ipv4.conf.all.rp_filter&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; sysctl&lt;/span&gt;&lt;span&gt; net.ipv4.conf.tun0.rp_filter&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;net.ipv4.conf.tun0.rp_filter&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; sysctl&lt;/span&gt;&lt;span&gt; net.ipv4.conf.br-lan.rp_filter&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;net.ipv4.conf.br-lan.rp_filter&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 所有相关网络接口的 &lt;code&gt;rp_filter&lt;/code&gt; 均为 &lt;code&gt;0&lt;/code&gt;, 证明这里没有问题, 故排除该原因&lt;/p&gt;
&lt;h3&gt;3. IP 转发未开启&lt;a href=&quot;#3-ip-转发未开启&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;首先网关本身使用的系统为 OpenWrt, 该系统为专业的软路由系统, 因此可以直接排除该原因. 但为了严谨, 这里还是检查一下&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; sysctl&lt;/span&gt;&lt;span&gt; net.ipv4.ip_forward&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;net.ipv4.ip_forward&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;4. EasyTier 的出口策略 / 策略路由冲突&lt;a href=&quot;#4-easytier-的出口策略--策略路由冲突&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;在第一项检查中我们可以看到, 路由表中存在多个 &lt;code&gt;pppoe-wan&lt;/code&gt;, 说明这是一个多拨的网络环境. 因此可能造成下游流量在转发时被&lt;strong&gt;路由策略规则&lt;/strong&gt;劫持, 导致回包走到了错误的物理接口, 而非回到 &lt;code&gt;tun0&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; ip&lt;/span&gt;&lt;span&gt; rule&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;0:&lt;/span&gt;&lt;span&gt;      from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; local&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1001:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; iif&lt;/span&gt;&lt;span&gt; pppoe-wan&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1002:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; iif&lt;/span&gt;&lt;span&gt; pppoe-xwan01&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1003:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; iif&lt;/span&gt;&lt;span&gt; pppoe-xwan02&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1004:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; iif&lt;/span&gt;&lt;span&gt; pppoe-xwan03&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1005:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; iif&lt;/span&gt;&lt;span&gt; pppoe-xwan04&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2001:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x100/0x3f00&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2002:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x200/0x3f00&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2003:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x300/0x3f00&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2004:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x400/0x3f00&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2005:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x500/0x3f00&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2061:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x3d00/0x3f00&lt;/span&gt;&lt;span&gt; blackhole&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2062:&lt;/span&gt;&lt;span&gt;   from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; fwmark&lt;/span&gt;&lt;span&gt; 0x3e00/0x3f00&lt;/span&gt;&lt;span&gt; unreachable&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;32766:&lt;/span&gt;&lt;span&gt;  from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; main&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;32767:&lt;/span&gt;&lt;span&gt;  from&lt;/span&gt;&lt;span&gt; all&lt;/span&gt;&lt;span&gt; lookup&lt;/span&gt;&lt;span&gt; default&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;通过这条输出, 我们可以注意到:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下游设备 &lt;code&gt;192.168.20.x&lt;/code&gt; → 网关 → 匹配 &lt;code&gt;main&lt;/code&gt; 路由表走 &lt;code&gt;tun0&lt;/code&gt; → VPN → &lt;code&gt;192.168.1.y&lt;/code&gt; (正常发出)&lt;/li&gt;
&lt;li&gt;回包到达网关 &lt;code&gt;tun0&lt;/code&gt; 后, 内核会进行路由查找. 此时, 如果回包被打上了某个 &lt;code&gt;fwmark&lt;/code&gt; (例如 &lt;code&gt;0x100&lt;/code&gt;), 就会命中规则 &lt;code&gt;2001: from all fwmark 0x100/0x3f00 lookup 1&lt;/code&gt;, 从而使用路由表 &lt;code&gt;1&lt;/code&gt; 进行转发.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这里我们查看路由表 1 的具体路由信息&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; ip&lt;/span&gt;&lt;span&gt; route&lt;/span&gt;&lt;span&gt; show&lt;/span&gt;&lt;span&gt; table&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;default&lt;/span&gt;&lt;span&gt; via&lt;/span&gt;&lt;span&gt; 10.131.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-wan&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 40&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.0.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.0.64.253&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 256&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.0.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.10.64.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.131.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-wan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.131.15.37&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan02&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.141.102.228&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.141.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan03&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.141.40.183&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 4&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan01&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.151.10.205&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;10.151.0.1&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; pppoe-xwan04&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 10.151.32.226&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;169.254.0.0/16&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 169.254.254.254&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 256&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.1.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.3.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.20.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; bird&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 32&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.20.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; br-lan&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; kernel&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt; 192.168.20.1&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 256&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.100.0/24&lt;/span&gt;&lt;span&gt; dev&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; proto&lt;/span&gt;&lt;span&gt; static&lt;/span&gt;&lt;span&gt; scope&lt;/span&gt;&lt;span&gt; link&lt;/span&gt;&lt;span&gt; metric&lt;/span&gt;&lt;span&gt; 65535&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从输出的路由表信息来看, 已经存在去往 &lt;code&gt;192.168.20.0/24&lt;/code&gt; 的正确路由, 这说明单纯的回程缺失已经被排除. 但下游设备无法通信, 此时问题大概率出现在&lt;strong&gt;连接跟踪表记 &lt;code&gt;(conntrack)&lt;/code&gt; 与防火墙过滤&lt;/strong&gt;的联合作用上.&lt;/p&gt;
&lt;p&gt;首先我们查看 OpenWrt 的防火墙配置
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/310-2.png&quot; alt=&quot;OpenWrt 防火墙中 EasyTier 接口的出入站配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;OpenWrt 防火墙中 EasyTier 接口的出入站配置&lt;/figcaption&gt;&lt;/figure&gt;
可以看到, EasyTier 接口的出入配置都是正确且有效的, 那么接下来我们对问题进行深入分析与排查&lt;p&gt;&lt;/p&gt;
&lt;h2&gt;深入分析&lt;a href=&quot;#深入分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;mwan3&lt;/code&gt; 的标记机制&lt;a href=&quot;#mwan3-的标记机制&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;mwan3&lt;/code&gt; 会在 &lt;code&gt;mangle&lt;/code&gt; 表的 &lt;code&gt;PREROUTING&lt;/code&gt; 和 &lt;code&gt;OUTPUT&lt;/code&gt; 中挂载 &lt;code&gt;mwan3_hook&lt;/code&gt;. 核心逻辑如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;CONNMARK restore:&lt;/code&gt; 恢复连接上保存的标记 &lt;code&gt;(fwmark)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;如果恢复后标记为 &lt;code&gt;0&lt;/code&gt;, 则根据入接口 &lt;code&gt;(mwan3_ifaces_in)&lt;/code&gt; 或策略 &lt;code&gt;(mwan3_rules)&lt;/code&gt; 打上新标记, 最后 &lt;code&gt;CONNMARK save&lt;/code&gt;, 将标记保存到连接跟踪里.&lt;/li&gt;
&lt;li&gt;此后所有属于该连接的包都会自动被还原相同标记, 并通过 &lt;code&gt;ip rule&lt;/code&gt; 的 &lt;code&gt;fwmark&lt;/code&gt; 匹配, 强制走对应的路由表 &lt;em&gt;(如 &lt;code&gt;table 1~5&lt;/code&gt;)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;当前链路存在的问题&lt;a href=&quot;#当前链路存在的问题&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;当 &lt;code&gt;192.168.20.x&lt;/code&gt; 首次访问 &lt;code&gt;192.168.1.x&lt;/code&gt; 时&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出站 (&lt;code&gt;br-lan&lt;/code&gt; → 网关 → &lt;code&gt;tun0&lt;/code&gt;):
该包在 &lt;code&gt;PREROUTING&lt;/code&gt; 或 &lt;code&gt;OUTPUT&lt;/code&gt; 链被 &lt;code&gt;mwan3&lt;/code&gt; 打上某个标记 &lt;em&gt;(例如 &lt;code&gt;0x100&lt;/code&gt;)&lt;/em&gt;, 并 &lt;code&gt;CONNMARK save&lt;/code&gt; 保存.&lt;/li&gt;
&lt;li&gt;回包 (&lt;code&gt;tun0&lt;/code&gt; → 网关 → 应回到 &lt;code&gt;br-lan&lt;/code&gt;):
回包进入 &lt;code&gt;PREROUTING&lt;/code&gt; → &lt;code&gt;mwan3_hook&lt;/code&gt; → &lt;code&gt;CONNMARK restore&lt;/code&gt; 直接将标记恢复为 &lt;code&gt;0x100&lt;/code&gt;.
由于标记非零, 后续 &lt;code&gt;mwan3_ifaces_in&lt;/code&gt; 等链都被跳过 &lt;em&gt;(它们要求 &lt;code&gt;mark match 0x0/0x3f00&lt;/code&gt;)&lt;/em&gt;.
回包带着 &lt;code&gt;0x100&lt;/code&gt; 进入路由查找, 命中 &lt;code&gt;ip rule&lt;/code&gt; 中的 &lt;code&gt;2001: from all fwmark 0x100/0x3f00 lookup 1&lt;/code&gt;, 使用 &lt;code&gt;table 1&lt;/code&gt; 转发.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尽管 &lt;code&gt;table 1&lt;/code&gt; 有去往 &lt;code&gt;192.168.20.0/24&lt;/code&gt; 的直连路由, 理论上可以通, 但实际环境中常被以下两种隐形过滤阻断:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;filter&lt;/code&gt; 表 &lt;code&gt;FORWARD&lt;/code&gt; 链的状态跟踪丢弃
大多数 OpenWrt 默认防火墙 &lt;code&gt;FORWARD&lt;/code&gt; 链允许 &lt;code&gt;ESTABLISHED&lt;/code&gt; ,&lt;code&gt;RELATED&lt;/code&gt; 状态, 丢弃 &lt;code&gt;INVALID&lt;/code&gt;.
当回包带着被强制改变的路由标记走过路由后, 连接跟踪可能将其状态标记为 &lt;code&gt;INVALID&lt;/code&gt; (因为出方向走的是 &lt;code&gt;main&lt;/code&gt; 表或不同的路由表, 回包却走 &lt;code&gt;table 1&lt;/code&gt;, 属于&lt;strong&gt;非对称路由&lt;/strong&gt;, &lt;code&gt;conntrack&lt;/code&gt; 可能视其为无效), 随后被 &lt;code&gt;FORWARD&lt;/code&gt; 链丢弃.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;反向路径校验 &lt;em&gt;(即使 &lt;code&gt;rp_filter=0&lt;/code&gt; 仍有其他机制)&lt;/em&gt;
某些内核版本在策略路由下仍会做额外的路径校验, 或者 &lt;code&gt;secure_redirects&lt;/code&gt; 等参数造成丢弃. 但更常见的是第 1 点.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;因此, 即使路由存在, 包也可能在送到 &lt;code&gt;br-lan&lt;/code&gt; 之前就被 &lt;code&gt;filter&lt;/code&gt; 规则或 &lt;code&gt;conntrack&lt;/code&gt; 剔除.&lt;/p&gt;
&lt;h2&gt;故障修复&lt;a href=&quot;#故障修复&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;快速恢复&lt;a href=&quot;#快速恢复&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;最快且最可靠的办法是让回包不再经过 &lt;code&gt;FORWARD&lt;/code&gt; 转发路径, 而是直接进网关本机. 将下游设备的源地址伪装为网关 VPN 接口的地址即可.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iptables&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; nat&lt;/span&gt;&lt;span&gt; -A&lt;/span&gt;&lt;span&gt; POSTROUTING&lt;/span&gt;&lt;span&gt; -s&lt;/span&gt;&lt;span&gt; 192.168.20.0/24&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; -j&lt;/span&gt;&lt;span&gt; MASQUERADE&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;执行完后看效果:&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;C:\Users\Nanami114&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;ping&lt;/span&gt;&lt;span&gt; 192.168.1.4&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Pinging&lt;/span&gt;&lt;span&gt; 192.168.1.4&lt;/span&gt;&lt;span&gt; with&lt;/span&gt;&lt;span&gt; 32&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; data:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=11ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=11ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=11ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=12ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; 192.168.1.4:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Packets:&lt;/span&gt;&lt;span&gt; Sent&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 4,&lt;/span&gt;&lt;span&gt; Received&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 4,&lt;/span&gt;&lt;span&gt; Lost&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; (0% &lt;/span&gt;&lt;span&gt;loss&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Approximate&lt;/span&gt;&lt;span&gt; round&lt;/span&gt;&lt;span&gt; trip&lt;/span&gt;&lt;span&gt; times&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; milli-seconds:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Minimum&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 11ms,&lt;/span&gt;&lt;span&gt; Maximum&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 12ms,&lt;/span&gt;&lt;span&gt; Average&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 11ms&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;C:\Users\Nanami114&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;ping&lt;/span&gt;&lt;span&gt; 192.168.1.8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Pinging&lt;/span&gt;&lt;span&gt; 192.168.1.8&lt;/span&gt;&lt;span&gt; with&lt;/span&gt;&lt;span&gt; 32&lt;/span&gt;&lt;span&gt; bytes&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; data:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.8:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=7ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.8:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=7ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.8:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=7ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Reply&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.1.8:&lt;/span&gt;&lt;span&gt; bytes=&lt;/span&gt;&lt;span&gt;32&lt;/span&gt;&lt;span&gt; time=7ms&lt;/span&gt;&lt;span&gt; TTL=&lt;/span&gt;&lt;span&gt;63&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Ping&lt;/span&gt;&lt;span&gt; statistics&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; 192.168.1.8:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Packets:&lt;/span&gt;&lt;span&gt; Sent&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 4,&lt;/span&gt;&lt;span&gt; Received&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 4,&lt;/span&gt;&lt;span&gt; Lost&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;span&gt; (0% &lt;/span&gt;&lt;span&gt;loss&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Approximate&lt;/span&gt;&lt;span&gt; round&lt;/span&gt;&lt;span&gt; trip&lt;/span&gt;&lt;span&gt; times&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; milli-seconds:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Minimum&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 7ms,&lt;/span&gt;&lt;span&gt; Maximum&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 7ms,&lt;/span&gt;&lt;span&gt; Average&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 7ms&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 此时下游设备已经可以正常收到对端设备 ICMP Ping 的回包. 接下来查看业务流量状态:
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/310-3.png&quot; alt=&quot;SMB&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;SMB&lt;/figcaption&gt;&lt;/figure&gt;
这里可以看到, 此时 SMB 流量已经可以正常通讯, 说明整个网络链路已经恢复, 下游设备恢复了与 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 段的正常通讯.&lt;p&gt;&lt;/p&gt;
&lt;p&gt;当然, 这个方法虽然恢复快速但也存在不妥:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;所有下游设备去往 &lt;code&gt;192.168.1.0/24&lt;/code&gt; 的通讯, 都会被目标设备识别为 &lt;code&gt;10.0.64.253&lt;/code&gt; 在与其通信, 也就是校园网关在与其通信.&lt;/strong&gt; 为了解决这个问题, 下面我们进行深度修复.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;根因修复: &lt;strong&gt;调整 &lt;code&gt;mangle&lt;/code&gt; 规则, 避免 VPN 回程路由被标记&lt;/strong&gt;&lt;a href=&quot;#根因修复-调整-mangle-规则-避免-vpn-回程路由被标记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;精准修复命令
在 &lt;code&gt;mwan3_hook&lt;/code&gt; 中 &lt;code&gt;CONNMARK save&lt;/code&gt; 之前插入一条规则: 如果包是从 &lt;code&gt;tun0&lt;/code&gt; 进入且目标是 &lt;code&gt;192.168.20.0/24&lt;/code&gt;, 则将其标记清零, 并让 &lt;code&gt;conntrack&lt;/code&gt; 保存清零后的标记. 这样该连接后续流量将不再受多线策略影响.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;首先查看 &lt;code&gt;mwan3_hook&lt;/code&gt; 接口编号&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@X-wrt-School:~#&lt;/span&gt;&lt;span&gt; iptables&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; mangle&lt;/span&gt;&lt;span&gt; -L&lt;/span&gt;&lt;span&gt; mwan3_hook&lt;/span&gt;&lt;span&gt; --line-numbers&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Chain&lt;/span&gt;&lt;span&gt; mwan3_hook&lt;/span&gt;&lt;span&gt; (2 &lt;/span&gt;&lt;span&gt;references&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;num&lt;/span&gt;&lt;span&gt;  target&lt;/span&gt;&lt;span&gt;     prot&lt;/span&gt;&lt;span&gt; opt&lt;/span&gt;&lt;span&gt; source&lt;/span&gt;&lt;span&gt;               destination&lt;/span&gt;&lt;span&gt;         &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt;    CONNMARK&lt;/span&gt;&lt;span&gt;   all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;             mark&lt;/span&gt;&lt;span&gt; match&lt;/span&gt;&lt;span&gt; 0x0/0x3f00&lt;/span&gt;&lt;span&gt; CONNMARK&lt;/span&gt;&lt;span&gt; restore&lt;/span&gt;&lt;span&gt; mask&lt;/span&gt;&lt;span&gt; 0x3f00&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2&lt;/span&gt;&lt;span&gt;    mwan3_ifaces_in&lt;/span&gt;&lt;span&gt;  all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;             mark&lt;/span&gt;&lt;span&gt; match&lt;/span&gt;&lt;span&gt; 0x0/0x3f00&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;3&lt;/span&gt;&lt;span&gt;    mwan3_local&lt;/span&gt;&lt;span&gt;  all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;             mark&lt;/span&gt;&lt;span&gt; match&lt;/span&gt;&lt;span&gt; 0x0/0x3f00&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt;    mwan3_rules&lt;/span&gt;&lt;span&gt;  all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;             mark&lt;/span&gt;&lt;span&gt; match&lt;/span&gt;&lt;span&gt; 0x0/0x3f00&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;5&lt;/span&gt;&lt;span&gt;    mwan3_connected&lt;/span&gt;&lt;span&gt;  all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;            &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;6&lt;/span&gt;&lt;span&gt;    CONNMARK&lt;/span&gt;&lt;span&gt;   all&lt;/span&gt;&lt;span&gt;  --&lt;/span&gt;&lt;span&gt;  anywhere&lt;/span&gt;&lt;span&gt;             anywhere&lt;/span&gt;&lt;span&gt;             CONNMARK&lt;/span&gt;&lt;span&gt; save&lt;/span&gt;&lt;span&gt; mask&lt;/span&gt;&lt;span&gt; 0x3f00&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到 &lt;code&gt;mwan3_connected&lt;/code&gt; 是&lt;strong&gt;第五条&lt;/strong&gt;, &lt;code&gt;CONNMARK save&lt;/code&gt; 是&lt;strong&gt;第六条&lt;/strong&gt;. 我们需要在这两条之间插入标记清零的规则&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iptables&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; mangle&lt;/span&gt;&lt;span&gt; -I&lt;/span&gt;&lt;span&gt; mwan3_hook&lt;/span&gt;&lt;span&gt; 6&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; tun0&lt;/span&gt;&lt;span&gt; -d&lt;/span&gt;&lt;span&gt; 192.168.20.0/24&lt;/span&gt;&lt;span&gt; -j&lt;/span&gt;&lt;span&gt; MARK&lt;/span&gt;&lt;span&gt; --set-mark&lt;/span&gt;&lt;span&gt; 0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/310-4.png&quot; alt=&quot;mwan3_hook 链中插入的 mangle 规则&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;mwan3_hook 链中插入的 mangle 规则&lt;/figcaption&gt;&lt;/figure&gt;
这里可以看到, 刚才插入的规则已经生效. 此时看下游设备效果.
这里使用下游设备连接对端物理设备的 SSH, 连接两次即可在终端内看到上一次连接的 IP 地址.&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Linux&lt;/span&gt;&lt;span&gt; NanamiWork-Server&lt;/span&gt;&lt;span&gt; 7.0.0-3-pve&lt;/span&gt;&lt;span&gt; #1 SMP PREEMPT_DYNAMIC PMX 7.0.0-3 (2026-04-21T22:56Z) x86_64&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;The&lt;/span&gt;&lt;span&gt; programs&lt;/span&gt;&lt;span&gt; included&lt;/span&gt;&lt;span&gt; with&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; Debian&lt;/span&gt;&lt;span&gt; GNU/Linux&lt;/span&gt;&lt;span&gt; system&lt;/span&gt;&lt;span&gt; are&lt;/span&gt;&lt;span&gt; free&lt;/span&gt;&lt;span&gt; software&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;the&lt;/span&gt;&lt;span&gt; exact&lt;/span&gt;&lt;span&gt; distribution&lt;/span&gt;&lt;span&gt; terms&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; each&lt;/span&gt;&lt;span&gt; program&lt;/span&gt;&lt;span&gt; are&lt;/span&gt;&lt;span&gt; described&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;individual&lt;/span&gt;&lt;span&gt; files&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; /usr/share/doc/&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;/copyright.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Debian&lt;/span&gt;&lt;span&gt; GNU/Linux&lt;/span&gt;&lt;span&gt; comes&lt;/span&gt;&lt;span&gt; with&lt;/span&gt;&lt;span&gt; ABSOLUTELY&lt;/span&gt;&lt;span&gt; NO&lt;/span&gt;&lt;span&gt; WARRANTY,&lt;/span&gt;&lt;span&gt; to&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; extent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;permitted&lt;/span&gt;&lt;span&gt; by&lt;/span&gt;&lt;span&gt; applicable&lt;/span&gt;&lt;span&gt; law.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Last&lt;/span&gt;&lt;span&gt; login:&lt;/span&gt;&lt;span&gt; Wed&lt;/span&gt;&lt;span&gt; May&lt;/span&gt;&lt;span&gt; 27&lt;/span&gt;&lt;span&gt; 16:19:00&lt;/span&gt;&lt;span&gt; 2026&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; 192.168.20.2&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;nanami114@NanamiWork-Server:~$&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 这里显示 &lt;code&gt;Last login: Wed May 27 16:19:00 2026 from 192.168.20.2&lt;/code&gt;, 证明改动已经生效, 并已经恢复了与目标设备的连接. 至此, 整个 VPN 网络的修复就已完成.&lt;/p&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业网络运维, 如有疏漏或错误, 还请指出! 如果您觉得文章不错, 还请分享给有需要的&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/318/&quot;&gt;EasyTier 参数导致 iBGP 崩溃排查&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/72/&quot;&gt;EasyTier 异地组网 VPN 部署教程&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/331/&quot;&gt;OSPFv3 + WireGuard 借用 IPv6 出口&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:网络技术</category><category>tag:运维</category></item><item><title>journald 日志过多导致磁盘 I/O 爆炸排查</title><link>https://blog.nanami.tech/en/archives/304</link><guid isPermaLink="false">en:304</guid><description>前言
博主在使用自己开发的 super-frpc 项目时, 注意到每次程序启动的时候, 磁盘 I/O 都会被占满. 一开始博主以为是被攻击, 后面使用 htop 查询发现, 占用量最大的进程分别为 systemctl status superfrpc_* 和 journalctl -u</description><pubDate>Fri, 22 May 2026 08:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主在使用自己开发的 &lt;a href=&quot;https://blog.nanami.tech/archives/289/&quot;&gt;super-frpc&lt;/a&gt; 项目时, 注意到每次程序启动的时候, 磁盘 I/O 都会被占满. 一开始博主以为是被攻击, 后面使用 &lt;code&gt;htop&lt;/code&gt; 查询发现, 占用量最大的进程分别为 &lt;code&gt;systemctl status superfrpc_*&lt;/code&gt; 和 &lt;code&gt;journalctl -u  superfrpc_* -n 50 --no-pager&lt;/code&gt;. 这两者的相同点是&lt;strong&gt;都会读取最近日志&lt;/strong&gt;. 因此引出了本篇文章所需要解决的问题.&lt;/p&gt;
&lt;h2&gt;故障分析&lt;a href=&quot;#故障分析&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h4&gt;为什么 &lt;code&gt;systemctl status&lt;/code&gt; 也会造成大量 I/O 开销&lt;a href=&quot;#为什么-systemctl-status-也会造成大量-io-开销&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/304-1.png&quot; alt=&quot;systemctl status 造成大量磁盘 I/O 时的 htop 截图&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;systemctl status 造成大量磁盘 I/O 时的 htop 截图&lt;/figcaption&gt;&lt;/figure&gt;
首先, &lt;code&gt;systemctl status *&lt;/code&gt; 并不会直接造成大量磁盘 I/O, 但是它会执行下面这些隐藏动作:&lt;p&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查询 &lt;code&gt;unit&lt;/code&gt; 状态&lt;/li&gt;
&lt;li&gt;读取最近日志 &lt;code&gt;(journalctl)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;显示最近几十行 &lt;code&gt;stdout&lt;/code&gt; / &lt;code&gt;stderr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;解析 &lt;code&gt;cgroup&lt;/code&gt; / &lt;code&gt;PID&lt;/code&gt; / 状态信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说, 实际上 &lt;code&gt;systemctl status *&lt;/code&gt; 隐式执行了&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;journalctl&lt;/span&gt;&lt;span&gt; -u&lt;/span&gt;&lt;span&gt; superfrpc_&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;.service&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;为什么 &lt;code&gt;journalctl&lt;/code&gt; 查询日志会造成大量 I/O 开销&lt;a href=&quot;#为什么-journalctl-查询日志会造成大量-io-开销&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;众所周知, 正常情况下查询 &lt;code&gt;systemd&lt;/code&gt; 服务日志应当是一瞬间的事情. 但如果你的日志符合以下任意一条特征:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;该服务日志量巨大&lt;/li&gt;
&lt;li&gt;日志没有被 &lt;code&gt;rotate&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;journal&lt;/code&gt; 文件非常大&lt;/li&gt;
&lt;li&gt;&lt;code&gt;journal&lt;/code&gt; 已损坏&lt;/li&gt;
&lt;li&gt;日志开启了压缩&lt;/li&gt;
&lt;li&gt;日志存储在机械盘&lt;/li&gt;
&lt;li&gt;&lt;code&gt;btrfs&lt;/code&gt; / &lt;code&gt;zfs&lt;/code&gt; 上有校验/压缩&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那么, &lt;code&gt;journald&lt;/code&gt; 就会疯狂读磁盘, 造成巨大 I/O 开销.&lt;/p&gt;
&lt;h4&gt;super-frpc 本身出了什么问题&lt;a href=&quot;#super-frpc-本身出了什么问题&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;主进程行为
在 super-frpc 的执行框架中, 如果用户开启了 watchdog 监听, 那么当主进程启动时, 会一并拉起 watchdog 进程, 然后检测现在已经开启的所有隶属于 super-frpc 的 frpc 服务进程, 并将已经启动的服务进程托管至 watchdog 进行监听.&lt;/li&gt;
&lt;li&gt;watchdog 行为
watchdog 在收到来自主进程的监听任务时, 会启动一个 &lt;code&gt;runMonitor&lt;/code&gt; 的 goroutine. 在该函数中调用了一个 &lt;code&gt;checkServiceLogs&lt;/code&gt; 的函数, 负责监听程序日志中的报错行为. 以下为修改前的 &lt;code&gt;checkServiceLogs&lt;/code&gt; 函数代码&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; checkServiceLogs&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;serviceName&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;bool&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	cmd &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; exec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Command&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;journalctl&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-u&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; serviceName&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-n&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;50&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;--no-pager&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	output&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; cmd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Output&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to execute journalctl: %w&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	logContent &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;output&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	errorKeywords &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt;&quot;error&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;fatal&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;failed&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;critical&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;exception&quot;&lt;/span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	for&lt;/span&gt;&lt;span&gt; _&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; keyword &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; range&lt;/span&gt;&lt;span&gt; errorKeywords &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		if&lt;/span&gt;&lt;span&gt; strings&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Contains&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;strings&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;ToLower&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;logContent&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; keyword&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;			return&lt;/span&gt;&lt;span&gt; false&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	return&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看出, 这里调用了 &lt;code&gt;journalctl&lt;/code&gt; 对服务进行了日志的查询. 而这样的查询任务会在&lt;strong&gt;每一个新服务被添加到监听列表时都会执行一遍&lt;/strong&gt;, 且是持续监听. 这也就导致了磁盘 I/O 爆炸.&lt;/p&gt;
&lt;h2&gt;故障排查&lt;a href=&quot;#故障排查&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;查询整个 &lt;code&gt;journald&lt;/code&gt; 日志所占据的磁盘空间&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;nanami114@VM-Sub:~/PersonalFiles/super-frpc$&lt;/span&gt;&lt;span&gt; journalctl&lt;/span&gt;&lt;span&gt; --disk-usage&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Archived&lt;/span&gt;&lt;span&gt; and&lt;/span&gt;&lt;span&gt; active&lt;/span&gt;&lt;span&gt; journals&lt;/span&gt;&lt;span&gt; take&lt;/span&gt;&lt;span&gt; up&lt;/span&gt;&lt;span&gt; 4.0G&lt;/span&gt;&lt;span&gt; in&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; file&lt;/span&gt;&lt;span&gt; system.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 光是日志就已经占据了 &lt;strong&gt;&lt;code&gt;4.0G&lt;/code&gt;&lt;/strong&gt; 的巨大空间, 这也就导致了 &lt;code&gt;journald&lt;/code&gt; 读取日志时的大量磁盘开销. 同时也说明了本次博主所碰到的问题属于 &lt;strong&gt;服务日志量巨大&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;故障修复&lt;a href=&quot;#故障修复&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;临时删除不需要的日志&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;nanami114@VM-Sub:~/PersonalFiles/super-frpc$&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; journalctl&lt;/span&gt;&lt;span&gt; --vacuum-size=500M&lt;/span&gt;&lt;span&gt;      # 将除最新的 500MB 日志以外的日志全部删除&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000000f6d8ba-000650eb1f09e7db.journal&lt;/span&gt;&lt;span&gt; (77.7M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/user-1000@cda8f901ce914c2ba110f7e17205bc58-0000000000f6daa3-000650eb2316285c.journal&lt;/span&gt;&lt;span&gt; (3.6M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000000f94f56-000650f2434e1d58.journal&lt;/span&gt;&lt;span&gt; (80.5M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000000fbc5fb-000650fa9502ddda.journal&lt;/span&gt;&lt;span&gt; (78.6M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/user-1000@cda8f901ce914c2ba110f7e17205bc58-0000000000fdae6c-000650ff56ec6396.journal&lt;/span&gt;&lt;span&gt; (3.6M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000000fe3e79-00065100649d2f0e.journal&lt;/span&gt;&lt;span&gt; (79.3M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-000000000100af6d-00065109684030a0.journal&lt;/span&gt;&lt;span&gt; (78.8M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/user-1000@cda8f901ce914c2ba110f7e17205bc58-000000000100b5c6-000651097e126843.journal&lt;/span&gt;&lt;span&gt; (3.7M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000001032883-0006511015b880a5.journal&lt;/span&gt;&lt;span&gt; (81.9M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-000000000105a875-0006511658dceb30.journal&lt;/span&gt;&lt;span&gt; (78.1M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/system@cda8f901ce914c2ba110f7e17205bc58-0000000001081e15-0006511f823b08c7.journal&lt;/span&gt;&lt;span&gt; (83.9M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Deleted&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journal&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa/user-1000@cda8f901ce914c2ba110f7e17205bc58-000000000108b2c0-00065121421f3acb.journal&lt;/span&gt;&lt;span&gt; (3.6M).&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Vacuuming&lt;/span&gt;&lt;span&gt; done,&lt;/span&gt;&lt;span&gt; freed&lt;/span&gt;&lt;span&gt; 3.5G&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journals&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; /var/log/journal/e2bc53213dbb447bab4d9898e22776fa.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Vacuuming&lt;/span&gt;&lt;span&gt; done,&lt;/span&gt;&lt;span&gt; freed&lt;/span&gt;&lt;span&gt; 0B&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journals&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; /var/log/journal.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Vacuuming&lt;/span&gt;&lt;span&gt; done,&lt;/span&gt;&lt;span&gt; freed&lt;/span&gt;&lt;span&gt; 0B&lt;/span&gt;&lt;span&gt; of&lt;/span&gt;&lt;span&gt; archived&lt;/span&gt;&lt;span&gt; journals&lt;/span&gt;&lt;span&gt; from&lt;/span&gt;&lt;span&gt; /run/log/journal.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;限制 &lt;code&gt;journald&lt;/code&gt; 日志创建大小
编辑 &lt;code&gt;/etc/journal/journald.conf&lt;/code&gt;
将 &lt;code&gt;SystemMaxUse&lt;/code&gt;, &lt;code&gt;SystemMaxFileSize&lt;/code&gt;, &lt;code&gt;RuntimeMaxUse&lt;/code&gt; 这三条参数取消注释, 并按照自己的需求设置. 这里博主分别设置为 &lt;code&gt;500M&lt;/code&gt;, &lt;code&gt;50M&lt;/code&gt;, &lt;code&gt;100M&lt;/code&gt;. 完整的配置文件如下&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Journal&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#Storage=auto&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#Compress=yes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#Seal=yes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#SplitMode=uid&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#SyncIntervalSec=5m&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#RateLimitIntervalSec=30s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#RateLimitBurst=10000&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;SystemMaxUse&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;500M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#SystemKeepFree=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;SystemMaxFileSize&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;50M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#SystemMaxFiles=100&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RuntimeMaxUse&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;100M&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#RuntimeKeepFree=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#RuntimeMaxFileSize=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#RuntimeMaxFiles=100&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxRetentionSec=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxFileSec=1month&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#ForwardToSyslog=no&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#ForwardToKMsg=no&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#ForwardToConsole=no&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#ForwardToWall=yes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#TTYPath=/dev/console&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxLevelStore=debug&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxLevelSyslog=debug&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxLevelKMsg=notice&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxLevelConsole=info&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#MaxLevelWall=emerg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#LineMax=48K&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#ReadKMsg=yes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;#Audit=yes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;保存并重启 &lt;code&gt;journald&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;span&gt; systemd-journald&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;程序代码修复&lt;a href=&quot;#程序代码修复&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h4&gt;systemd 配置文件问题&lt;a href=&quot;#systemd-配置文件问题&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;造成问题的核心原因是, super-frpc 在创建 frpc 服务时, 并没有对日志方面做出任何配置. 在询问 AI 后, 得到的答复是
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/304-2.png&quot; alt=&quot;AI 关于 systemd 日志配置的答复&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;AI 关于 systemd 日志配置的答复&lt;/figcaption&gt;&lt;/figure&gt;
这里我们先来看一下原来的代码是怎么写的&lt;p&gt;&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; createSystemdService&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;instanceID&lt;/span&gt;&lt;span&gt; int&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; configPath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; runUser&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt; error&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	frpcPath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; GetFrpcPath&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	serviceName&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; database&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;instanceID&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	serviceContent &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`[Unit]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Description=superfrpc_%d&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;After=network.target&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[Service]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Type=simple&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ExecStart=%s -c %s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;User=%s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Restart=on-failure&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RestartSec=5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[Install]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;WantedBy=multi-user.target&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; instanceID&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; frpcPath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; configPath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; runUser&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	servicePath &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; filepath&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Join&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;/etc/systemd/system&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; serviceName&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;&quot;.service&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;WriteFile&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servicePath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span&gt;byte&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;serviceContent&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; 0644&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to create systemd service file: %w&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	cmd &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; exec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Command&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;systemctl&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;enable&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; serviceName&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; output&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; cmd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CombinedOutput&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Remove&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;servicePath&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to enable service: %s, output: %s&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; output&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	cmd &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; exec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Command&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;systemctl&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;daemon-reload&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; output&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; cmd&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CombinedOutput&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to reload daemon: %s, output: %s&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; output&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	return&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在这段代码中, systemd 服务的配置文件模板为&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Unit&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Description&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;superfrpc_%d&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;After&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;network.target&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Service&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Type&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;simple&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ExecStart&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;%s -c %s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;User&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;%s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Restart&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;on-failure&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;RestartSec&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;Install&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;WantedBy&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;multi-user.target&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;可以看到, 没有对日志做出任何配置. 这里我们添加上如下两条配置&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;StandardOutput&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;append:%s/superfrpc_%d.log&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;StandardError&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;append:%s/superfrpc_%d.log&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;并在程序配置文件中新增了 &lt;code&gt;logsPath&lt;/code&gt; 这条参数, 用于单独存放 frpc 产生的日志.&lt;/p&gt;
&lt;h4&gt;日志无限增长问题&lt;a href=&quot;#日志无限增长问题&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;将 frpc 日志重定向到文件输出之后, 还有一个问题需要解决: &lt;strong&gt;日志无限增长&lt;/strong&gt;.
systemd 自己并不会主动清理日志文件, 所以我们需要借助 &lt;code&gt;logrotate&lt;/code&gt; 工具来对日志进行约束. 详细解决流程如下&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在主进程创建首个 &lt;code&gt;systemd&lt;/code&gt; 服务后, 创建 &lt;code&gt;logrotate&lt;/code&gt; 配置&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/etc/logrotate.d/superfrpc_frpclog&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;在配置中填写以下字段&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;/path/to/logs/superfrpc_*.log &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    daily&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    rotate 7&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    compress&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    delaycompress&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    missingok&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    notifempty&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    copytruncate&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/path/to/logs/superfrpc_*.log&lt;/code&gt;: 匹配符合 &lt;code&gt;/path/to/logs/superfrpc_*.log&lt;/code&gt; 的所有文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;daily&lt;/code&gt;: 每天进行一次 rotate&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rotate 7&lt;/code&gt;: 保留 7 份历史日志&lt;/li&gt;
&lt;li&gt;&lt;code&gt;compress&lt;/code&gt;: 旧日志自动进行 &lt;code&gt;gzip&lt;/code&gt; 压缩&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delaycompress&lt;/code&gt;: 延迟一轮再压缩&lt;/li&gt;
&lt;li&gt;&lt;code&gt;missingok&lt;/code&gt;: 日志不存在也不报错&lt;/li&gt;
&lt;li&gt;&lt;code&gt;nofityempty&lt;/code&gt;: 空日志不归档&lt;/li&gt;
&lt;li&gt;&lt;code&gt;copytruncate&lt;/code&gt;: 将日志文件 &lt;code&gt;inode&lt;/code&gt; 属性进行迁移&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;进行了 &lt;code&gt;logrotate&lt;/code&gt; 配置后, 整个日志的 rotate 过程如下:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;假设当前日志文件 &lt;code&gt;superfrpc_8.log&lt;/code&gt; 的大小达到了 &lt;code&gt;500MB&lt;/code&gt;, 则执行 rotate:
Day 1:&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;superfrpc_8.log&lt;/span&gt;&lt;span&gt;       # 新日志文件&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;superfrpc_8.log.1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;到了第二天, 自动 rotate 一遍:
Day 2:&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;superfrpc_8.log&lt;/span&gt;&lt;span&gt;       # 新日志文件&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;superfrpc_8.log.1&lt;/span&gt;&lt;span&gt;     # 延迟一轮再压缩&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;superfrpc_8.log.2.gz&lt;/span&gt;&lt;span&gt;  # 被 gzip 压缩&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;到了第八天, 删除最开始的一条日志: &lt;code&gt;superfrpc_8.log.7.gz&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;修改后的代码如下&lt;/p&gt;
&lt;p&gt;创建 &lt;code&gt;CreateLogrotatePolicy&lt;/code&gt; 函数&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; CreateLogrotatePolicy&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;span&gt; error&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	logrotatePath &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; &quot;/etc/logrotate.d/superfrpc_frpclog&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	policyContent &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;`%s/superfrpc_*.log {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    daily&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    rotate 7&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    compress&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    delaycompress&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    missingok&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    notifempty&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;`&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CurrentConfig&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;LogsPath&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; os&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;WriteFile&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;logrotatePath&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; []&lt;/span&gt;&lt;span&gt;byte&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;policyContent&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;span&gt; 0644&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to create logrotate policy file: %w&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; exec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Command&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;logrotate&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;-f&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; logrotatePath&lt;/span&gt;&lt;span&gt;).&lt;/span&gt;&lt;span&gt;Run&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		return&lt;/span&gt;&lt;span&gt; fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Errorf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;failed to apply logrotate policy: %w&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	return&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后在程序初始化过程中调用该函数&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; global&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CurrentConfig&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;LogsPath &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &quot;&quot;&lt;/span&gt;&lt;span&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span&gt; !&lt;/span&gt;&lt;span&gt;global&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CurrentConfig&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Status&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;IsLogrotateConfigured &lt;/span&gt;&lt;span&gt;{&lt;/span&gt;&lt;span&gt; // Set up logrotate policy if LogsPath is configured&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	if&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;:=&lt;/span&gt;&lt;span&gt; sys&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CreateLogrotatePolicy&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;span&gt; err &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; nil&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		postLog&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Fatal&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;fmt&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Sprintf&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Failed to create logrotate policy: %v&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; err&lt;/span&gt;&lt;span&gt;))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		global&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;CurrentConfig&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Status&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;IsLogrotateConfigured &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;		config&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;SaveConfig&lt;/span&gt;&lt;span&gt;()&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        postLog&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Info&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Logrotate policy has been configured successfully.&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;测试修复效果&lt;a href=&quot;#测试修复效果&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@VM-Sub:/home/nanami114/PersonalFiles/super-frpc#&lt;/span&gt;&lt;span&gt; ./super-frpc&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2026/05/22&lt;/span&gt;&lt;span&gt; 17:15:16&lt;/span&gt;&lt;span&gt; [frpLogger] Init.d log streamer initialized&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;2026/05/22&lt;/span&gt;&lt;span&gt; 17:15:16&lt;/span&gt;&lt;span&gt; [frpLogger] Systemd log streamer initialized&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.541 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Super-frpc 0.0.1 (&lt;/span&gt;&lt;span&gt;Build&lt;/span&gt;&lt;span&gt; 1.pre-release&lt;/span&gt;&lt;span&gt;) by Madobi Nanami&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.549 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Logs database initialized successfully&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.558 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Database initialized successfully&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.565 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Routes setup successfully&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.588 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Watchdog process watchdog_systemd is not running, starting it...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.797 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 8, serviceName: superfrpc_8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.864 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;IsInstanceRunning&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Systemd service superfrpc_8 is running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.870 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 8, serviceName: superfrpc_8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.878 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Add service monitor: superfrpc_8&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.885 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 9, serviceName: superfrpc_9&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.903 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;IsInstanceRunning&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Systemd service superfrpc_9 is running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.909 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 9, serviceName: superfrpc_9&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.916 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Add service monitor: superfrpc_9&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.923 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 10, serviceName: superfrpc_10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.940 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;IsInstanceRunning&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Systemd service superfrpc_10 is running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.946 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 10, serviceName: superfrpc_10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.952 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Add service monitor: superfrpc_10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.959 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 11, serviceName: superfrpc_11&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.976 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;IsInstanceRunning&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Systemd service superfrpc_11 is running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.982 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 11, serviceName: superfrpc_11&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.988 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Add service monitor: superfrpc_11&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:16.995 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 12, serviceName: superfrpc_12&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.012 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;IsInstanceRunning&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Systemd service superfrpc_12 is running&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.018 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;GetServiceNameByInstanceID&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; instanceID: 12, serviceName: superfrpc_12&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.024 - DEBUG&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Add service monitor: superfrpc_12&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.031 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;watchdog&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; synced 5 running instance(&lt;/span&gt;&lt;span&gt;s&lt;/span&gt;&lt;span&gt;) to monitor list&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.037 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Connected to Watchdog successfully&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;[&lt;/span&gt;&lt;span&gt;2026-05-22 17:15:17.045 - INFO&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt; Server starting on 0.0.0.0:7000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;从日志中可以看出, 此时查询 &lt;code&gt;systemctl status&lt;/code&gt; 的速度已经很快了, 然后查询磁盘 I/O 占用
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/304-3.png&quot; alt=&quot;修复后 systemctl status 与磁盘 I/O 占用情况&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;修复后 systemctl status 与磁盘 I/O 占用情况&lt;/figcaption&gt;&lt;/figure&gt;
可以看到, 磁盘 I/O 几乎没有占用.
至此, 问题全部解决&lt;p&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;通过此次故障的发生, 我们需要加强对服务日志的管控以及对程序潜在 bug 的审查. 感谢您的阅读, 如果觉得不错, 还请分享给有需要的人, 感谢! 如有错误或疏漏, 还请指出, 感谢!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/134/&quot;&gt;Docker 下 umami prisma migrate 报错修复&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/310/&quot;&gt;EasyTier 与 mwan3: VPN 回程路由修复&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:编程开发</category></item><item><title>iVentoy 部署 PXE 网络启动服务器</title><link>https://blog.nanami.tech/en/archives/297</link><guid isPermaLink="false">en:297</guid><description>前言
在做网络运维的过程中, 常常会碰到需要给各种物理机或虚拟机安装系统的情况. 以往装系统都是通过 U 盘等物理存储介质进行安装. 这种安装方式不仅效率低, 还可能因为 U 盘速率不达标而导致安装过程缓慢. 本篇文章将会给大家介绍一种效率极高且速率极快的系统安装方式 - PXE 网络启动. 使用</description><pubDate>Wed, 20 May 2026 06:17:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在做网络运维的过程中, 常常会碰到需要给各种物理机或虚拟机安装系统的情况. 以往装系统都是通过 U 盘等物理存储介质进行安装. 这种安装方式不仅效率低, 还可能因为 U 盘速率不达标而导致安装过程缓慢. 本篇文章将会给大家介绍一种效率极高且速率极快的系统安装方式 - PXE 网络启动. 使用 PXE Server 安装系统不仅可以做到几百台设备同时安装, 还可以做到通过一个通道, 自由安装不同种类, 不同平台的操作系统.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;需要注意的是, PXE 技术不仅可以用于安装系统, 还可以托管操作系统, 使下游设备做到无盘启动. 本文只介绍前者的解决方案.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;配置需求&lt;a href=&quot;#配置需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;一台网络接口 1Gbps 及以上, 硬盘速率足够的物理机/虚拟机&lt;/li&gt;
&lt;li&gt;支持配置 &lt;code&gt;TFTP Server&lt;/code&gt; 的硬/软路由&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;本篇文章使用基于 &lt;code&gt;OpenWrt&lt;/code&gt; 的 &lt;code&gt;X-WRT&lt;/code&gt; 作为演示&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;安装 &lt;code&gt;iVentoy&lt;/code&gt;&lt;a href=&quot;#安装-iventoy&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在待配置为 &lt;code&gt;PXE Server&lt;/code&gt; 的设备上安装 &lt;code&gt;Debian&lt;/code&gt;/&lt;code&gt;Ubuntu&lt;/code&gt; 操作系统 (略).&lt;/li&gt;
&lt;li&gt;在&lt;a href=&quot;https://github.com/ventoy/PXE/releases&quot;&gt;官方发布页&lt;/a&gt; 中根据设备架构下载 &lt;code&gt;iVentoy&lt;/code&gt; 的软件包&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;截至本文编写时, 官方最新版本为 &lt;code&gt;1.0.30&lt;/code&gt;. 如果是 &lt;code&gt;x86_64&lt;/code&gt; 设备, 需要下载的文件为 &lt;code&gt;https://github.com/ventoy/PXE/releases/download/v1.0.30/iventoy-1.0.30-linux-x86_64-free.tar.gz&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;解压下载的软件包&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; -xzvf&lt;/span&gt;&lt;span&gt; https://github.com/ventoy/PXE/releases/download/v1.0.30/iventoy-1.0.30-linux-x86_64-free.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;启动 &lt;code&gt;iVentoy&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; iventoy-1.0.30&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; +x&lt;/span&gt;&lt;span&gt; ./iventoy.sh&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;./iventoy.sh&lt;/span&gt;&lt;span&gt; start&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;脚本运行后, 默认运行在 &lt;code&gt;26000&lt;/code&gt; 端口上. 以下是输出示例&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;iventoy&lt;/span&gt;&lt;span&gt; start&lt;/span&gt;&lt;span&gt; SUCCESS&lt;/span&gt;&lt;span&gt; PID=&lt;/span&gt;&lt;span&gt;2040&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Please&lt;/span&gt;&lt;span&gt; open&lt;/span&gt;&lt;span&gt; your&lt;/span&gt;&lt;span&gt; browser&lt;/span&gt;&lt;span&gt; and&lt;/span&gt;&lt;span&gt; visit&lt;/span&gt;&lt;span&gt; http://127.0.0.1:26000&lt;/span&gt;&lt;span&gt; or&lt;/span&gt;&lt;span&gt; http://x.x.x.x:26000&lt;/span&gt;&lt;span&gt; (x.x.x.x &lt;/span&gt;&lt;span&gt;is&lt;/span&gt;&lt;span&gt; any&lt;/span&gt;&lt;span&gt; valid&lt;/span&gt;&lt;span&gt; IP&lt;/span&gt;&lt;span&gt; address&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;使用浏览器输入 &lt;code&gt;http://&amp;lt;Server IP&amp;gt;:26000&lt;/code&gt;, 即可进入 &lt;code&gt;iVentoy&lt;/code&gt; 的配置页面.&lt;/li&gt;
&lt;li&gt;在主页中按照您的需求进行配置
&lt;figure&gt;&lt;img src=&quot;/images/297-1.png&quot; alt=&quot;参考配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;参考配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Select Server IP&lt;/code&gt; - 选择服务器 IP. 这里列出的是当前服务器的 IP 地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NIC Name&lt;/code&gt; - 服务器网卡名称.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Subnet Mask&lt;/code&gt; - 子网掩码.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Gateway&lt;/code&gt; - 网关.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IP Pool (begin)&lt;/code&gt; - PXE Boot IP 地址池起始. 注意: 免费版的 iVentoy 一次性支持 20 个客户端同时启动, 故此处设置 20 个 IP 即可&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IP Pool (end)&lt;/code&gt; - PXE Boot IP 地址池末尾.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DNS Server&lt;/code&gt; - DNS 服务器地址. 置空即可&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;进入 &lt;code&gt;Configuration&lt;/code&gt; 页面, 按照需求对 iVentoy 的启动方式进行配置
&lt;figure&gt;&lt;img src=&quot;/images/297-2.png&quot; alt=&quot;参考配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;参考配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;DHCP Server Mode&lt;/code&gt; - DHCP 服务器模式. 这里推荐保持不变&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Boot Background Mode&lt;/code&gt; - 启动时背景模式. 这里推荐选择 &lt;code&gt;GUI&lt;/code&gt;, 即图形化用户界面&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Boot Menu Resolution&lt;/code&gt; - 启动菜单分辨率. 可以不用设置太高, 合适即可&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EFI Boot File&lt;/code&gt; - EFI 引导文件. 按需选择, 如果没有特殊要求, 保持默认即可&lt;/li&gt;
&lt;li&gt;&lt;code&gt;System Boot Password&lt;/code&gt; - 系统引导密码. 选择 PXE 引导时是否需要输入密码, 如不需要置空即可&lt;/li&gt;
&lt;li&gt;&lt;code&gt;System Default Image&lt;/code&gt; - 系统默认映像. 选择 iVentoy 默认引导的系统映像, 如无特殊需求置空即可&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Page Default Language&lt;/code&gt; - 页面默认语言.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;导入 ISO 映像
在软件包解压后的目录中有一个 &lt;code&gt;iso&lt;/code&gt; 文件夹, 将您的所有 ISO 映像文件放入该文件夹即可.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 您也可以使用 &lt;code&gt;NFS&lt;/code&gt;/&lt;code&gt;SMB&lt;/code&gt; 将存有映像文件的网络目录挂载到 &lt;code&gt;iso&lt;/code&gt; 目录, 当然使用硬链接也是可以的&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;配置 &lt;code&gt;TFTP Server&lt;/code&gt;&lt;a href=&quot;#配置-tftp-server&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;本文使用基于 OpenWrt 的 X-Wrt 进行演示&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;进入设备 WebUI, 依次选择 &lt;code&gt;Network&lt;/code&gt; (网络) —&amp;gt; &lt;code&gt;DHCP&lt;/code&gt; —&amp;gt; &lt;code&gt;dnsmasq&lt;/code&gt; —&amp;gt; &lt;code&gt;PXE/TFTP&lt;/code&gt;
&lt;figure&gt;&lt;img src=&quot;/images/297-3.png&quot; alt=&quot;OpenWrt dnsmasq 的 PXE/TFTP 设置页面&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;OpenWrt dnsmasq 的 PXE/TFTP 设置页面&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;勾选 &lt;code&gt;Enable TFTP Server&lt;/code&gt; (启用 &lt;code&gt;TFTP&lt;/code&gt; 服务器)&lt;/li&gt;
&lt;li&gt;在下方的 &lt;code&gt;Special PXE boot options for Dnsmasq.&lt;/code&gt; 表格中点击 &lt;code&gt;Add&lt;/code&gt; (添加) 按钮&lt;/li&gt;
&lt;li&gt;在对话框中填入您的相关配置.
&lt;figure&gt;&lt;img src=&quot;/images/297-4.png&quot; alt=&quot;参考配置&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;参考配置&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filename&lt;/code&gt; - 引导文件文件名. 填入 iVentoy 设置中的 &lt;code&gt;EFI Boot File&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Server name&lt;/code&gt; - 引导服务器名称. 随意设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DHCP Options&lt;/code&gt; - DHCP 附加选项. 推荐置空&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Match this Tag&lt;/code&gt; - 仅携带该 Tag 的 DHCP 客户端才会被引导至 PXE Server. 如无特殊需求推荐置空&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Force&lt;/code&gt; - 总是发送选中的 DHCP 选项. 推荐置空&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Instance&lt;/code&gt; - &lt;code&gt;dnsmasq&lt;/code&gt; 实例. 如果网络环境为普通的单广播域家庭网络, 直接选择实例 0 即可. 其他情况请按需选择.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;配置完成后单击 &lt;code&gt;Save&lt;/code&gt; (保存)&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在当前页面的 &lt;code&gt;Network boot image&lt;/code&gt; (网络启动映像) 中填入刚才设置的 &lt;code&gt;Filename&lt;/code&gt;. 如果您添加了不止一个 Host, 那么请填入您需要的.&lt;/li&gt;
&lt;li&gt;全部修改完成后单击 &lt;code&gt;Save &amp;amp; Apply&lt;/code&gt; (保存并应用)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;测试&lt;a href=&quot;#测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;进入 iVentoy WebUI, 在主页中单击绿色三角按钮启动服务器&lt;/li&gt;
&lt;li&gt;将需要安装系统的设备接入 iVentoy 所在的内网&lt;/li&gt;
&lt;li&gt;启动设备&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;注: iVentoy 同时支持传统 MBR 启动和新型 UEFI 启动. 如果您选择 UEFI 启动, &lt;strong&gt;请务必关闭 &lt;code&gt;Secure Boot&lt;/code&gt;&lt;/strong&gt;, 否则可能启动失败&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果设备中显示了 iVentoy 的启动页面, 则配置成功
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/297-5.png&quot; alt=&quot;iVentoy Boot&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;iVentoy Boot&lt;/figcaption&gt;&lt;/figure&gt;
至此, iVentoy 的配置就完成了&lt;p&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业运维, 如有错误或疏漏还请指出! 如果觉得文章有用, 请分享给有需要的人, 感谢!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/382/&quot;&gt;自建 Debian 13 镜像源: ftpsync + Nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/263/&quot;&gt;物理机 P2V 全量迁移到 Proxmox VE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:Linux 运维</category></item><item><title>Super-frpc: frpc 集群可视化管理</title><link>https://blog.nanami.tech/en/archives/289</link><guid isPermaLink="false">en:289</guid><description>Super-frpc
让 frp 客户端集群管理变得可视化, 自动化, 可靠化.

项目简介
将您的所有 frp 客户端实例置于一个 WebUI 中进行管理. 集中化, 标准化, 自动化. 增强您的 frp 链路鲁棒性, 让您的 frp 实例管理更方便, 更快捷

该项目目前处于预发布阶段,</description><pubDate>Wed, 13 May 2026 05:28:00 GMT</pubDate><content:encoded>&lt;p&gt;Super-frpc&lt;/p&gt;
&lt;p&gt;让 frp 客户端集群管理变得可视化, 自动化, 可靠化.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;项目简介&lt;a href=&quot;#项目简介&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;将您的所有 frp 客户端实例置于一个 WebUI 中进行管理. 集中化, 标准化, 自动化. 增强您的 frp 链路鲁棒性, 让您的 frp 实例管理更方便, 更快捷&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;该项目目前处于预发布阶段, 可能会遇到各种不确定的 Bug 和有待完善的功能. 还请各路大佬高抬贵手, 有能力的帮忙完善项目&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;项目特色&lt;a href=&quot;#项目特色&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;集中管理:&lt;/strong&gt; 使用一个后端服务, 一个 WebUI, 就可以一次性对所有 frp 实例进行管理&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;跨平台:&lt;/strong&gt; 同时支持 &lt;code&gt;Windows&lt;/code&gt;, &lt;code&gt;GNU/Linux&lt;/code&gt; 平台 &lt;em&gt;(&lt;code&gt;GNU/Linux&lt;/code&gt; 平台目前支持 &lt;code&gt;systemd&lt;/code&gt;, &lt;code&gt;initd&lt;/code&gt;)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;基于角色的访问控制:&lt;/strong&gt; 系统内置三种用户角色 (&lt;code&gt;visitor&lt;/code&gt;, &lt;code&gt;admin&lt;/code&gt;, &lt;code&gt;superuser&lt;/code&gt;), 每个角色权限明确, 使得您可以安排您信任的人共同维护您的 frp 客户端集群&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;轻松部署:&lt;/strong&gt; 整个项目使用二进制方式部署, 方便快捷, 部署难度低&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;操作简单:&lt;/strong&gt; Web 面板内各个功能模块分区明确, 操作简单易上手&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自动化运维:&lt;/strong&gt; 内置 Watchdog 程序, 可以对您的 frp 客户端实例进行监控. &lt;strong&gt;一旦检测到程序报错, 会先自行尝试恢复, 如无法恢复, 可以通过您自行设定的通知渠道来通知您&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;技术栈&lt;a href=&quot;#技术栈&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;开发语言: &lt;code&gt;Go&lt;/code&gt;, &lt;code&gt;Vue3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;后端模块: &lt;code&gt;BurntSushi/toml&lt;/code&gt;, &lt;code&gt;gorilla/websocket&lt;/code&gt;, &lt;code&gt;modernc.org/sqlite&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;数据库: &lt;code&gt;SQLite&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;支持平台&lt;a href=&quot;#支持平台&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GNU/Linux (&lt;code&gt;systemd&lt;/code&gt;, &lt;code&gt;initd&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Windows 10 or Up&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;其中, 主程序的测试已在 Linux 中完成, 但 watchdog 在目前的版本中只支持 &lt;code&gt;systemd&lt;/code&gt; 管理器的 Linux 平台&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;项目地址&lt;a href=&quot;#项目地址&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://gitea.nanami.tech/Super-frpc&quot;&gt;Gitea&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;截图&lt;a href=&quot;#截图&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-1.png&quot; alt=&quot;Instance Management&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Instance Management&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-2.png&quot; alt=&quot;Instance Detail&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Instance Detail&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-3.png&quot; alt=&quot;Proxy List&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Proxy List&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-4.png&quot; alt=&quot;User Management&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;User Management&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-5.png&quot; alt=&quot;Session Management&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Session Management&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-6.png&quot; alt=&quot;Settings&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Settings&lt;/figcaption&gt;&lt;/figure&gt;
&lt;figure&gt;&lt;img src=&quot;/images/289-7.png&quot; alt=&quot;Webhook Settings&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Webhook Settings&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2&gt;部署&lt;a href=&quot;#部署&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;Linux 平台&lt;a href=&quot;#linux-平台&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;a href=&quot;https://gitea.nanami.tech/Super-frpc/backend/releases&quot;&gt;后端发布页面&lt;/a&gt; 中下载最新发行版的二进制程序, 并将其放入新建文件夹中&lt;/li&gt;
&lt;li&gt;给予可执行权限&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; +x&lt;/span&gt;&lt;span&gt; super-frpc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;在相同目录中新建 &lt;code&gt;watchdog&lt;/code&gt; 文件夹&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; watchdog&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;在 &lt;a href=&quot;https://gitea.nanami.tech/Super-frpc/WatchDog_Linux-systemd/releases&quot;&gt;Watchdog 发布页&lt;/a&gt; 中下载最新发行版的二进制程序, 并将其放入 &lt;code&gt;watchdog&lt;/code&gt; 文件夹中&lt;/li&gt;
&lt;li&gt;赋予可执行权限&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; +x&lt;/span&gt;&lt;span&gt; watchdog_systemd&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;退回上一级, 并以 &lt;code&gt;root&lt;/code&gt; 用户执行主程序&lt;/li&gt;
&lt;li&gt;如果程序执行没有报错, 则证明正常运行. 程序会默认监听 &lt;code&gt;7000&lt;/code&gt; 端口, 可以通过该端口进入内嵌的 WebUI&lt;/li&gt;
&lt;li&gt;进入 &lt;a href=&quot;https://github.com/fatedier/frp/releases&quot;&gt;frp 官方发布页&lt;/a&gt; 下载最新 frp 二进制文件发行压缩包&lt;/li&gt;
&lt;li&gt;解压到 super-frpc 目录&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; -xzvf&lt;/span&gt;&lt;span&gt; frp_0.69.0_darwin_amd64.tar.gz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;赋予 frpc 可执行权限&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;chmod&lt;/span&gt;&lt;span&gt; +x&lt;/span&gt;&lt;span&gt; frp_0.69.0_darwin_amd64/frpc&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;进入程序 WebUI, 按照初始化提示进入设置页面, 填入 frpc 二进制文件的&lt;strong&gt;绝对路径&lt;/strong&gt;, 并按照要求和需求完成剩余设置后应用并重启&lt;/li&gt;
&lt;li&gt;如果一切正常, 那么您已经成功部署了!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;在初次进入程序时, 程序会要求您进行初始化设置.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/304/&quot;&gt;journald 日志过多导致磁盘 I/O 爆炸排查&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:项目</category></item><item><title>K3s 专题 ep4: 部署 Rancher 管理平台</title><link>https://blog.nanami.tech/en/archives/283</link><guid isPermaLink="false">en:283</guid><description>前言
随着业务量的上涨与集群节点的增加, 我们使用 kubectl 命令行工具进行运维会逐渐变得困难, 并且也无法实时监测到每个节点的实时状态. 这时, 一套好用的图形化监控与运维工具就成为了我们的刚需. 这篇文章将会详细描述 Kubernetes 图形化运维工具 Rancher 的搭建与配置过程</description><pubDate>Mon, 20 Apr 2026 04:18:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;随着业务量的上涨与集群节点的增加, 我们使用 &lt;code&gt;kubectl&lt;/code&gt; 命令行工具进行运维会逐渐变得困难, 并且也无法实时监测到每个节点的实时状态. 这时, 一套好用的图形化监控与运维工具就成为了我们的刚需. 这篇文章将会详细描述 Kubernetes 图形化运维工具 &lt;code&gt;Rancher&lt;/code&gt; 的搭建与配置过程&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;本文章同样适用于 K8s&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;配置需求&lt;a href=&quot;#配置需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;可运行的 K3s/K8s Master 节点与至少一个 Worker 节点&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;安装 Helm&lt;a href=&quot;#安装-helm&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Helm 是一个为 Kubernetes 开发的包管理器, 它简化了应用的部署与管理. 它使用 &lt;code&gt;Helm charts&lt;/code&gt;, 这是一个定义了 Kubernetes 资源分配的 &lt;code&gt;YAML&lt;/code&gt; 文件, 为自动化的安装, 升级, 管理 Kubernetes 集群应用程序而生.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;个人翻译, 有错见谅, 原文如下:
Helm is a package manager for Kubernetes that simplifies the deployment and management of applications. It uses Helm charts, which are collections of YAML files that define Kubernetes resources, to automate the process of installing, upgrading, and managing applications in a Kubernetes cluster.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安装 Helm 软件源与 GPG Key&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt-get&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; curl&lt;/span&gt;&lt;span&gt; gpg&lt;/span&gt;&lt;span&gt; apt-transport-https&lt;/span&gt;&lt;span&gt; --yes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; -fsSL&lt;/span&gt;&lt;span&gt; https://packages.buildkite.com/helm-linux/helm-debian/gpgkey&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; gpg&lt;/span&gt;&lt;span&gt; --dearmor&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; tee&lt;/span&gt;&lt;span&gt; /usr/share/keyrings/helm.gpg&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; /dev/null&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;echo&lt;/span&gt;&lt;span&gt; &quot;deb [signed-by=/usr/share/keyrings/helm.gpg] https://packages.buildkite.com/helm-linux/helm-debian/any/ any main&quot;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; tee&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/helm-stable-debian.list&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;更新软件源并安装 Helm&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;可能需要科学上网&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; helm&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;安装 &lt;code&gt;cert-manager&lt;/code&gt;&lt;a href=&quot;#安装-cert-manager&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;可以在 &lt;a href=&quot;https://www.suse.com/en-us/suse-rancher/support-matrix/all-supported-versions&quot;&gt;这里&lt;/a&gt; 看到 Rancher 的支持平台与配置需求&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;添加 Rancher 软件源&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; repo&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; rancher-latest&lt;/span&gt;&lt;span&gt; https://releases.rancher.com/server-charts/latest&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;在 Kubernetes 中创建 Rancher 的 namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; namespace&lt;/span&gt;&lt;span&gt; cattle-system&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;添加 &lt;code&gt;cert-manager&lt;/code&gt; 清单文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; apply&lt;/span&gt;&lt;span&gt; -f&lt;/span&gt;&lt;span&gt; https://github.com/cert-manager/cert-manager/releases/download/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;VERSIO&lt;/span&gt;&lt;span&gt;N&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/cert-manager.crds.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;VERSION&lt;/code&gt; GitHub 上的版本 Tag, 需要您自己填写&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;添加 &lt;code&gt;jetstack&lt;/code&gt; 软件源&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; repo&lt;/span&gt;&lt;span&gt; add&lt;/span&gt;&lt;span&gt; jetstack&lt;/span&gt;&lt;span&gt; https://charts.jetstack.io&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;更新软件源&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; repo&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;安装 &lt;code&gt;cert-manager&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;span&gt; jetstack/cert-manager&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --namespace&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --create-namespace&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 如果您在安装过程中碰到报错 &lt;code&gt;Error: INSTALLATION FAILED: Kubernetes cluster unreachable: Get &quot;http://localhost:8080/version&quot;: dial tcp [::1]:8080: connect: connection refused&lt;/code&gt;, 则您需要按照如下步骤进行配置
Q. 为什么会报错?
A. &lt;code&gt;helm v3&lt;/code&gt; 版本不再需要 &lt;code&gt;Tiller&lt;/code&gt;, 而是直接访问 ApiServer 来与 k8s 交互，通过环境变量 &lt;code&gt;KUBECONFIG&lt;/code&gt; 来读取存有 apiserver 的地址与 token 的配置文件地址, 默认地址为 &lt;code&gt;~/.kube/config&lt;/code&gt; *转自 &lt;a href=&quot;https://blog.csdn.net/varyuan/article/details/112111547&quot;&gt;CSDN&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;修改 &lt;code&gt;/etc/profile&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/profile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;在开头处写入内容 &lt;code&gt;export KUBECONFIG=/etc/rancher/k3s/k3s.yaml&lt;/code&gt;
保存并执行&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;souce&lt;/span&gt;&lt;span&gt; /etc/profile&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;执行完成后, 再次尝试运行安装命令, 这次应当没有报错.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果先前有安装失败的记录, 那么重新安装可能会遇到报错 &lt;code&gt;Error: INSTALLATION FAILED: cannot re-use a name that is still in use&lt;/code&gt;, 此时删除对应的 Secret 即可&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; {namespace}&lt;/span&gt;&lt;span&gt; delete&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; delete&lt;/span&gt;&lt;span&gt; secrets&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;span&gt; -l&lt;/span&gt;&lt;span&gt; owner=helm,name=cert-manager&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果在安装时遇到了错误&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Error:&lt;/span&gt;&lt;span&gt; INSTALLATION&lt;/span&gt;&lt;span&gt; FAILED:&lt;/span&gt;&lt;span&gt; failed&lt;/span&gt;&lt;span&gt; post-install:&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt; error&lt;/span&gt;&lt;span&gt; occurred:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      *&lt;/span&gt;&lt;span&gt; timed&lt;/span&gt;&lt;span&gt; out&lt;/span&gt;&lt;span&gt; waiting&lt;/span&gt;&lt;span&gt; for&lt;/span&gt;&lt;span&gt; the&lt;/span&gt;&lt;span&gt; condition&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;则是因为 &lt;code&gt;cert-manager&lt;/code&gt; 在安装时会创建一个 &lt;code&gt;Job (startupapicheck)&lt;/code&gt; 来校验 &lt;code&gt;webhook&lt;/code&gt; 是否正常工作. 该校验会向 API Server 发送一个测试请求, 触发 webhook 调用, 但此时的 Webhook 配置中 &lt;code&gt;caBundle&lt;/code&gt; 还没有被 cert-manager 的 controller 及时填上 (或者使用的是旧的/无效的 CA), 导致 API Server 连接 webhook 时证书不信任, TLS 握手失败, Job 一直重试直至 Helm 超时.
修复方法如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取 CA 证书&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt; cert-manager-webhook-ca&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; jsonpath=&apos;{.data.ca\.crt}&apos;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; base64&lt;/span&gt;&lt;span&gt; -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;给两个 Webhook 注入证书&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;CA_BUNDLE&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;$(&lt;/span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; secret&lt;/span&gt;&lt;span&gt; cert-manager-webhook-ca&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; cert-manager&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; jsonpath=&apos;{.data.ca\.crt}&apos;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; patch&lt;/span&gt;&lt;span&gt; mutatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; cert-manager-webhook&lt;/span&gt;&lt;span&gt; --type=&apos;json&apos;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -p=&quot;[{&apos;op&apos;: &apos;replace&apos;, &apos;path&apos;: &apos;/webhooks/0/clientConfig/caBundle&apos;, &apos;value&apos;:&apos;&lt;/span&gt;&lt;span&gt;${CA_BUNDLE}&lt;/span&gt;&lt;span&gt;&apos;}]&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; patch&lt;/span&gt;&lt;span&gt; validatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; cert-manager-webhook&lt;/span&gt;&lt;span&gt; --type=&apos;json&apos;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -p=&quot;[{&apos;op&apos;: &apos;replace&apos;, &apos;path&apos;: &apos;/webhooks/0/clientConfig/caBundle&apos;, &apos;value&apos;:&apos;&lt;/span&gt;&lt;span&gt;${CA_BUNDLE}&lt;/span&gt;&lt;span&gt;&apos;}]&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果有多个 Webhook, 还可以使用循环来依次注入&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;for&lt;/span&gt;&lt;span&gt; wh &lt;/span&gt;&lt;span&gt;in&lt;/span&gt;&lt;span&gt; mutatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; cert-manager-webhook&lt;/span&gt;&lt;span&gt; validatingwebhookconfiguration&lt;/span&gt;&lt;span&gt; cert-manager-webhook&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;span&gt; do&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; $wh &lt;/span&gt;&lt;span&gt;-o&lt;/span&gt;&lt;span&gt; json&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; jq&lt;/span&gt;&lt;span&gt; &apos;.webhooks[].clientConfig.caBundle = &quot;&apos;&lt;/span&gt;&lt;span&gt;${CA_BUNDLE}&lt;/span&gt;&lt;span&gt;&apos;&quot;&apos;&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; kubectl&lt;/span&gt;&lt;span&gt; apply&lt;/span&gt;&lt;span&gt; -f&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;done&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;p&gt;此时再次进行安装, 就不会再次出现该问题了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;安装 Rancher&lt;a href=&quot;#安装-rancher&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;使用以下命令安装 Rancher&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; rancher&lt;/span&gt;&lt;span&gt; rancher-latest/rancher&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --namespace&lt;/span&gt;&lt;span&gt; cattle-system&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --set&lt;/span&gt;&lt;span&gt; hostname=&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;hostnam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --set&lt;/span&gt;&lt;span&gt; replicas=&lt;/span&gt;&lt;span&gt;1&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  --set&lt;/span&gt;&lt;span&gt; bootstrapPassword=&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;PASSWORD_FOR_RANCHER_ADMI&lt;/span&gt;&lt;span&gt;N&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hostname&lt;/code&gt; 是 Ingress 监听的目标地址. 这条配置对应的是 Ingress 配置中的 &lt;code&gt;host&lt;/code&gt; &lt;strong&gt;如果这是部署在生产环境中的, 请务必将其设置为服务器域名或反向代理的目标域名.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PASSWORD_FOR_RANCHER_ADMIN&lt;/code&gt; 是 Rancher 管理员的密码, 需要您自行设置, 长度至少为 12 个字符&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您的 Pod 状态处于 &lt;code&gt;ImagePullBackOff&lt;/code&gt;, 则很可能是镜像拉取失败了. 您可以按照以下操作为 Rancher 配置镜像&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Master:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; /etc/rancher/k3s/registries.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mirrors:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  docker.io:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   endpoint:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &quot;https://docker.m.daocloud.io&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  quay.io:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    endpoint:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &quot;https://quay.m.daocloud.io&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;span&gt; k3s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Worker:&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /etc/rancher/k3s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; /etc/rancher/k3s/registries.yaml&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mirrors:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  docker.io:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   endpoint:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &quot;https://docker.m.daocloud.io&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  quay.io:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    endpoint:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      - &quot;https://quay.m.daocloud.io&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;systemctl&lt;/span&gt;&lt;span&gt; restart&lt;/span&gt;&lt;span&gt; k3s-agent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;执行完成后, 镜像拉取应该会正常&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果没有报错, 并且使用绑定的域名可以访问到 Rancher 控制台, 那么配置到此结束.&lt;/p&gt;
&lt;p&gt;如果您不想让 Ingress 去管理反向代理, 而想使用外部的反向代理工具 (Nginx, openresty 等) 去负责反代和负载均衡, 或者您想直接使用 IP 地址: 端口的形式去进行访问, 则可以接着看下去.&lt;/p&gt;
&lt;h3&gt;暴露相关端口&lt;a href=&quot;#暴露相关端口&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Rancher 安装后默认的策略是 &lt;code&gt;ClusterIP&lt;/code&gt;, 这种策略是无法被外部所访问的, 只能在集群内访问. 如果想使用外部的反向代理工具, 则需要将策略改为 &lt;code&gt;NodePort&lt;/code&gt;, 并配置持久化&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;导出配置清单&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; values&lt;/span&gt;&lt;span&gt; rancher&lt;/span&gt;&lt;span&gt; -n&lt;/span&gt;&lt;span&gt; cattle-system&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; yaml&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; rancher-values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;进入清单文件, 在文件末尾添加这些参数&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;service&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; NodePort&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ports&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    https&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      nodePort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;lt;httpsPort&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    http&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      nodePort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &amp;lt;httpPort&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;httpsPort&lt;/code&gt; https 服务器对外暴露的端口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;httpPort&lt;/code&gt; http 服务器对外暴露的端口&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;保存后, 升级 Rancher, 应用新配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;helm&lt;/span&gt;&lt;span&gt; upgrade&lt;/span&gt;&lt;span&gt; rancher&lt;/span&gt;&lt;span&gt; rancher-latest/rancher&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -n&lt;/span&gt;&lt;span&gt; cattle-system&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -f&lt;/span&gt;&lt;span&gt; rancher-values.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;配置完成后, 使用您设置的地址在浏览器中访问, 如果能顺利进入到 Rancher 的初始化页面, 并输入您设置的默认密码进入主页, 则配置完成
&lt;figure&gt;&lt;img src=&quot;/images/283-1.png&quot; alt=&quot;Rancher&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Rancher&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本人非专业 Kubernetes 运维人员, 如有疏漏或错误, 还请指出!&lt;/li&gt;
&lt;li&gt;如果觉得文章有帮助, 还请分享给有需要的人, 感谢!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/269/&quot;&gt;K3s 专题 ep1: 搭建 Master 与 Worker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/276/&quot;&gt;K3s 专题 ep2: 部署 Harbor 私有仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/281/&quot;&gt;K3s 专题 ep3: 快速部署 Docker 镜像&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:K3s</category></item><item><title>Kubernetes: K8s Deployment 清单详解</title><link>https://blog.nanami.tech/en/archives/282</link><guid isPermaLink="false">en:282</guid><description>前言
在接触 Kubernetes 运维后, 我们需要将我们编写的程序交付给 Kubernetes 进行集群化部署. 这么做的前提需要您充分的理解 Kubernetes Deployment 清单文件的含义及各个配置的作用. 本文将会带你进行了解

清单文件的四大结构
每个 Kubernetes</description><pubDate>Sat, 11 Apr 2026 03:18:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在接触 Kubernetes 运维后, 我们需要将我们编写的程序交付给 Kubernetes 进行集群化部署. 这么做的前提需要您充分的理解 Kubernetes Deployment 清单文件的含义及各个配置的作用. 本文将会带你进行了解&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;清单文件的四大结构&lt;a href=&quot;#清单文件的四大结构&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;每个 Kubernetes 清单文件都有四个必填的顶层字段:&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ...&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ...&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;它们的含义分别为:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apiVersion&lt;/code&gt; 使用的 Kubernetes API 版本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind&lt;/code&gt; 要创建的资源类型&lt;/li&gt;
&lt;li&gt;&lt;code&gt;metadata&lt;/code&gt; 资源的元数据&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec&lt;/code&gt; 资源的期望状态 (规约)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这是一个具体的清单文件示例&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; apps/v1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  replicas&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  selector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    matchLabels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  template&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      containers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      -&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-container&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        image&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp:v1.0.0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ports&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        -&lt;/span&gt;&lt;span&gt; containerPort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;h3&gt;&lt;code&gt;apiVersion&lt;/code&gt; 与 &lt;code&gt;kind&lt;/code&gt;: 资源的唯一标识&lt;a href=&quot;#apiversion-与-kind-资源的唯一标识&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;apiVersion&lt;/code&gt; 指定了要使用的 Kubernetes API 的版本和 API 组.&lt;/li&gt;
&lt;li&gt;核心组 &lt;code&gt;(Core Group)&lt;/code&gt; : 如 &lt;code&gt;v1&lt;/code&gt; (用于 &lt;code&gt;Pod&lt;/code&gt;, &lt;code&gt;Service&lt;/code&gt; 等), 它们是最基础的资源, 路径是 &lt;code&gt;/api/v1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;命名组 &lt;code&gt;(Named Groups)&lt;/code&gt; : 如 &lt;code&gt;apps/v1&lt;/code&gt; (用于 &lt;code&gt;Deployment&lt;/code&gt;, &lt;code&gt;StatefulSet&lt;/code&gt;), 它们的路径是 &lt;code&gt;/apis/apps/v1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;架构知识: 这反映了 &lt;code&gt;kube-apiserver&lt;/code&gt; 的 API 分组和版本演进策略 - &lt;code&gt;apiserver&lt;/code&gt; 负责暴露这些 RESTful API endpoint, 并提供不同版本之间的转换.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kind&lt;/code&gt; 明确指定你要创建的资源对象类型，例如 &lt;code&gt;Pod&lt;/code&gt;, &lt;code&gt;Service&lt;/code&gt;, &lt;code&gt;Deployment&lt;/code&gt;, &lt;code&gt;ConfigMap&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;架构知识: 每个 kind 在 Kubernetes 内部都对应一个资源类型定义 &lt;code&gt;(Resource Definition)&lt;/code&gt;. 当 &lt;code&gt;kubectl apply -f&lt;/code&gt; 时, 客户端会将 YAML 序列化为 JSON 并发送到对应的 API 端点.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;metadata&lt;/code&gt;: 为资源附加的身份信息与 Tag&lt;a href=&quot;#metadata-为资源附加的身份信息与-tag&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    version&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; v1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  annotations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    build-number&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;123&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code&gt;metadata&lt;/code&gt; 资源的身份信息与标签&lt;a href=&quot;#metadata-资源的身份信息与标签&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    version&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; v1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  annotations&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    build-number&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;123&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;metadata.name&lt;/code&gt; 唯一标识符, 在同一个 namespace 下必须唯一&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labels&lt;/code&gt; 键值对标签, 用于组织和筛选资源&lt;/li&gt;
&lt;li&gt;&lt;code&gt;annotations&lt;/code&gt; 用于存储非标识性信息, 例如构建信息, 开发者联系方式等&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;架构知识:&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt; 和 &lt;code&gt;namespace&lt;/code&gt; 共同构成了资源在集群中的唯一键. &lt;code&gt;apiserver&lt;/code&gt; 将资源数据最终存储在 &lt;code&gt;etcd&lt;/code&gt; 中, 键类似于 &lt;code&gt;/registry/deployments/default/myapp-deployment&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;labels&lt;/code&gt; 是 Kubernetes 中核心的&lt;strong&gt;组织与选择机制&lt;/strong&gt;. &lt;strong&gt;Service&lt;/strong&gt; 和 &lt;strong&gt;Deployment&lt;/strong&gt; 通过 &lt;strong&gt;Label Selector (标签选择器)&lt;/strong&gt; 来发现并管理一组 Pod. &lt;code&gt;kube-scheduler&lt;/code&gt; 也是用标签来将 Pod 调度到具有特定标签的 Node 上.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;spec&lt;/code&gt; 定义期望状态的规约&lt;a href=&quot;#spec-定义期望状态的规约&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;spec&lt;/code&gt; 的内容完全由 &lt;code&gt;kind&lt;/code&gt; 决定. 我们这里详细拆解 &lt;code&gt;Deployment&lt;/code&gt; 的 &lt;code&gt;spec&lt;/code&gt;.&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  replicas&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  selector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    matchLabels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  template&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      containers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      -&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-container&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        image&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp:v1.0.0&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ports&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        -&lt;/span&gt;&lt;span&gt; containerPort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;spec.replicas&lt;/code&gt; 期望的 Pod 副本数量&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.selector&lt;/code&gt; 定义如何找到该 Deployment 管理的 Pod&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.matchLabels&lt;/code&gt; 必须与 template 中的 labels 匹配&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.template&lt;/code&gt; Pod 模板, 定义了如何创建新的 Pod&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.template.labels&lt;/code&gt; Pod 的标签, 必须被上面的 selector 选中&lt;/li&gt;
&lt;li&gt;&lt;code&gt;spec.spec&lt;/code&gt; Pod 的 spec&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h4&gt;控制器如何工作&lt;a href=&quot;#控制器如何工作&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;这是理解 Kubernetes 运行机制的关键&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用于提交清单 -&amp;gt; &lt;code&gt;kubectl&lt;/code&gt; 将 YAML 发送给 &lt;code&gt;api-server&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;apisever&lt;/code&gt; 验证并存储 -&amp;gt; 验证格式和字段合法性, 然后作为期望状态存入 &lt;code&gt;etcd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment Controller&lt;/code&gt; 监听到变化 -&amp;gt; 它是 &lt;code&gt;kube-controller-manager&lt;/code&gt; 的一部分. 它发现期望的 &lt;code&gt;replicas&lt;/code&gt; 是 3, 但是当前没有任何 Pod.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Deployment Controller&lt;/code&gt; 创建 &lt;code&gt;ReplicaSet&lt;/code&gt; -&amp;gt; 它会创建一个中间资源 &lt;code&gt;ReplicaSet&lt;/code&gt;, 其 &lt;code&gt;spec&lt;/code&gt; 中包含了 Pod 模板和 &lt;code&gt;replicas: 3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ReplicaSet Controller&lt;/code&gt; 创建 &lt;code&gt;Pod&lt;/code&gt; -&amp;gt; 它发现 Pod 的期望数量为 3, 实际是 0, 于是会创建 3 个 &lt;code&gt;Pod&lt;/code&gt; 对象, 这些对象的定义完全来自 &lt;code&gt;template&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Scheduler&lt;/code&gt; 介入 -&amp;gt; 新建的 Pod 对象此时处于 &lt;code&gt;Pending&lt;/code&gt; 状态. &lt;code&gt;kube-scheduler&lt;/code&gt; 会持续监听 &lt;code&gt;api-server&lt;/code&gt;, 发现这些未被调度的 Pod, 然后根据资源请求与亲和性规则等, 为它们选择一个最优的 Worker Node&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Scheduler&lt;/code&gt; 更新 &lt;code&gt;Pod&lt;/code&gt; 对象 -&amp;gt; 将选定的节点名称写入 Pod 的 &lt;code&gt;spec.nodeName&lt;/code&gt; 字段&lt;/li&gt;
&lt;li&gt;目标节点上的 &lt;code&gt;kubelet&lt;/code&gt; 监听到 -&amp;gt; 每个节点上的 &lt;code&gt;kubelet&lt;/code&gt; 只关注 &lt;code&gt;spec.nodeName&lt;/code&gt; 等于自己主机名的 Pod. 它发现有一个 Pod 分配给了自己&lt;/li&gt;
&lt;li&gt;&lt;code&gt;kubelet&lt;/code&gt; 创建容器 -&amp;gt; &lt;code&gt;kubelet&lt;/code&gt; 调用容器 runtime (在 K3s 中为 &lt;code&gt;containerd&lt;/code&gt;), 拉取 &lt;code&gt;myapp:v1.0.0&lt;/code&gt; 镜像并启动容器&lt;/li&gt;
&lt;li&gt;状态上报 -&amp;gt; &lt;code&gt;kubelet&lt;/code&gt; 不断将 Pod 的运行状态 (如 &lt;code&gt;Running&lt;/code&gt;) 上报给 &lt;code&gt;apiserver&lt;/code&gt;, 更新到 &lt;code&gt;etcd&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;整个流程是&lt;strong&gt;异步且最终一致&lt;/strong&gt;的, 各个组件通过 &lt;code&gt;apiserver&lt;/code&gt; 进行协作, 共同推进集群状态向期望状态收敛&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此, Kubernetes 的部署清单已经完全介绍完成. 如果你已经了解了 Kubernetes 的控制器如何工作, 且明白了其中的一些核心概念, 那么就可以去尝试手写配置文件, 启动你的第一个集群了!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业 Kubernetes 运维人员, 如有错误或疏漏欢迎指正. 如果觉得文章不错, 请将其分享给有需要的人, 感谢阅读!&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/281/&quot;&gt;K3s 专题 ep3: 快速部署 Docker 镜像&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/283/&quot;&gt;K3s 专题 ep4: 部署 Rancher 管理平台&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:K3s</category></item><item><title>K3s 专题 ep3: 快速部署 Docker 镜像</title><link>https://blog.nanami.tech/en/archives/281</link><guid isPermaLink="false">en:281</guid><description>前言
在搭建好 K3s Master, Worker 与私有 Docker 镜像站后, 我们就该将自己开发的程序交付给 K3s 进行集群化部署. 这篇文章就记录了博主将程序交付 K3s 部署运行的全过程


本教程也同样适用于 Kubernetes, 即 K8s
由于博主刚开始研究 K3s,</description><pubDate>Sat, 11 Apr 2026 03:02:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在搭建好 K3s Master, Worker 与私有 Docker 镜像站后, 我们就该将自己开发的程序交付给 K3s 进行集群化部署. 这篇文章就记录了博主将程序交付 K3s 部署运行的全过程&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;本教程也同样适用于 Kubernetes, 即 K8s&lt;/li&gt;
&lt;li&gt;由于博主刚开始研究 K3s, 故本文可能会出现的问题包括但不限于&lt;strong&gt;各种低级错误&lt;/strong&gt;, &lt;strong&gt;十分不严谨的专业用语&lt;/strong&gt;, 还请各路大佬轻喷&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h2&gt;搭建需求&lt;a href=&quot;#搭建需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;已部署的 K3s Master 与至少一个 Worker 节点&lt;/li&gt;
&lt;li&gt;私有 Harbor 站点&lt;/li&gt;
&lt;li&gt;已编译并上传至 Harbor 的 Docker 镜像&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 编写 Kubernetes 部署清单&lt;a href=&quot;#1-编写-kubernetes-部署清单&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;与 Docker 类似, 每一份 Kubernetes 程序都需要一份清单文件来描述你想创建的&lt;strong&gt;资源对象&lt;/strong&gt;, 让 Kubernetes 的控制平面 &lt;code&gt;(Control Panel)&lt;/code&gt; 来负责让集群的实际状态不断地接近并维持这个期望状态&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您不了解如何编写部署清单, 可以看看 &lt;a href=&quot;https://blog.nanami.tech/archives/282/&quot;&gt;这篇文章&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;参照这份示例文件, 编写您的 Kubernetes 部署清单&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; apps/v1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-deployment&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  replicas&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 2&lt;/span&gt;&lt;span&gt;   # 运行2个副本&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  selector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    matchLabels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  template&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      labels&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      containers&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      -&lt;/span&gt;&lt;span&gt; name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        image&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp:v1.0.0&lt;/span&gt;&lt;span&gt;   # 根据你实际使用的镜像名调整&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        imagePullPolicy&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; IfNotPresent&lt;/span&gt;&lt;span&gt;   # 如果本地已有镜像就不拉取&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ports&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        -&lt;/span&gt;&lt;span&gt; containerPort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; http&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        # 健康检查（如果你的程序实现了 /health endpoint）&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        livenessProbe&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          httpGet&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            path&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; /health&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            port&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          initialDelaySeconds&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          periodSeconds&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 10&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        readinessProbe&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          httpGet&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            path&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; /ready&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            port&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          initialDelaySeconds&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          periodSeconds&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;---&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apiVersion&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; v1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;kind&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Service&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;metadata&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  name&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp-service&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;spec&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  selector&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    app&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; myapp&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ports&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  -&lt;/span&gt;&lt;span&gt; port&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 80&lt;/span&gt;&lt;span&gt;          # 集群内访问的端口&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    targetPort&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 8080&lt;/span&gt;&lt;span&gt;  # 容器的端口&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    protocol&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; TCP&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  type&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; ClusterIP&lt;/span&gt;&lt;span&gt;     # 集群内部访问，如改为 NodePort 可对外暴露&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 在给出的这份示例配置文件中并没有给出挂载点等配置, 您需要继续进行编写, 而不是直接使用这份不完整的示例文件&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;2. 推送至 K3s&lt;a href=&quot;#2-推送至-k3s&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在 Master 中应用该 YAML 文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; apply&lt;/span&gt;&lt;span&gt; -f&lt;/span&gt;&lt;span&gt; myapp-deployment.yaml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您的控制台有类似于这样的输出, 则证明应用成功&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;deployment.apps/myapp&lt;/span&gt;&lt;span&gt; created&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;service/myapp-service&lt;/span&gt;&lt;span&gt; created&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;configmap/myapp-config&lt;/span&gt;&lt;span&gt; created&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Warning:&lt;/span&gt;&lt;span&gt; annotation&lt;/span&gt;&lt;span&gt; &quot;kubernetes.io/ingress.class&quot;&lt;/span&gt;&lt;span&gt; is&lt;/span&gt;&lt;span&gt; deprecated,&lt;/span&gt;&lt;span&gt; please&lt;/span&gt;&lt;span&gt; use&lt;/span&gt;&lt;span&gt; &apos;spec.ingressClassName&apos;&lt;/span&gt;&lt;span&gt; instead&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ingress.networking.k8s.io/myapp-ingress&lt;/span&gt;&lt;span&gt; created&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;检查 Pod 状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; pods&lt;/span&gt;&lt;span&gt; -o&lt;/span&gt;&lt;span&gt; wide&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;您应当看到如下所示的输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;NAME&lt;/span&gt;&lt;span&gt;                            READY&lt;/span&gt;&lt;span&gt;   STATUS&lt;/span&gt;&lt;span&gt;             RESTARTS&lt;/span&gt;&lt;span&gt;   AGE&lt;/span&gt;&lt;span&gt;    IP&lt;/span&gt;&lt;span&gt;          NODE&lt;/span&gt;&lt;span&gt;          NOMINATED&lt;/span&gt;&lt;span&gt; NODE&lt;/span&gt;&lt;span&gt;   READINESS&lt;/span&gt;&lt;span&gt; GATES&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;myapp-8667bb46f9-mzxf8&lt;/span&gt;&lt;span&gt;          0/1&lt;/span&gt;&lt;span&gt;     ImagePullBackOff&lt;/span&gt;&lt;span&gt;   0&lt;/span&gt;&lt;span&gt;          111s&lt;/span&gt;&lt;span&gt;   10.42.1.5&lt;/span&gt;&lt;span&gt;   k3s-worker1&lt;/span&gt;&lt;span&gt;   &amp;lt;&lt;/span&gt;&lt;span&gt;non&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;           &amp;lt;&lt;/span&gt;&lt;span&gt;non&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;检查 Service&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; svc&lt;/span&gt;&lt;span&gt; myapp-service&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;您应当看到如下所示的输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;NAME&lt;/span&gt;&lt;span&gt;                   TYPE&lt;/span&gt;&lt;span&gt;        CLUSTER-IP&lt;/span&gt;&lt;span&gt;    EXTERNAL-IP&lt;/span&gt;&lt;span&gt;   PORT&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;S&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;   AGEvice&lt;/span&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;heart-mirror-service&lt;/span&gt;&lt;span&gt;   ClusterIP&lt;/span&gt;&lt;span&gt;   10.43.42.37&lt;/span&gt;&lt;span&gt;   &amp;lt;&lt;/span&gt;&lt;span&gt;non&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;        8080:80/TCP&lt;/span&gt;&lt;span&gt;    4m19s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;检查 Pod 状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; pods&lt;/span&gt;&lt;span&gt; -l&lt;/span&gt;&lt;span&gt; app=myapp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;您应当看到如下所示的输出&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;NAME&lt;/span&gt;&lt;span&gt;                            READY&lt;/span&gt;&lt;span&gt;   STATUS&lt;/span&gt;&lt;span&gt;    RESTARTS&lt;/span&gt;&lt;span&gt;   AGE&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;myapp-674b9fdf7b-7d669&lt;/span&gt;&lt;span&gt;   1/1&lt;/span&gt;&lt;span&gt;     Running&lt;/span&gt;&lt;span&gt;   0&lt;/span&gt;&lt;span&gt;          28s&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;查看 Pod 日志&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;kubectl&lt;/span&gt;&lt;span&gt; logs&lt;/span&gt;&lt;span&gt; myapp-674b9fdf7b-7d669&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您的 Pod 状态不是 &lt;code&gt;Running&lt;/code&gt;, 您应当在 &lt;code&gt;kubectl logs&lt;/code&gt; 后添加 &lt;code&gt;--previous&lt;/code&gt; 参数来检查历史日志, 或使用 &lt;code&gt;kubectl describe pod myapp-674b9fdf7b-7d669&lt;/code&gt; 来查看具体错误原因&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;&amp;lt;WorkerIP&amp;gt;:80&lt;/code&gt; 访问后端, 如果正常, 则搭建阶段到此结束&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至此, 您的 Kubernetes 集群就启动完成了&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业 Kubernetes 运维人员, 如有疏漏或错误, 请指出! 如果觉得文章写得不错, 请分享给有需要的人, 感谢阅读.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/276/&quot;&gt;K3s 专题 ep2: 部署 Harbor 私有仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/283/&quot;&gt;K3s 专题 ep4: 部署 Rancher 管理平台&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:K3s</category></item><item><title>K3s 专题 ep2: 部署 Harbor 私有仓库</title><link>https://blog.nanami.tech/en/archives/276</link><guid isPermaLink="false">en:276</guid><description>前言
在上一篇文章搭建完 K3s Master 和 Worker 节点之后, 我们就需要将我们的程序推送到 K3s 内部, 来实现集群化的部署. 在开发环境, 我们可以直接将打包好的 Docker 镜像推送到 K3s 内部. 但在实际生产环境, 更推荐搭建本地 Docker 私有仓库.</description><pubDate>Thu, 09 Apr 2026 07:59:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;在上一篇文章搭建完 K3s Master 和 Worker 节点之后, 我们就需要将我们的程序推送到 K3s 内部, 来实现集群化的部署. 在开发环境, 我们可以直接将打包好的 Docker 镜像推送到 K3s 内部. 但在实际生产环境, 更推荐搭建本地 Docker 私有仓库. 这样不仅方便我们管理 Docker 镜像, 同时也可以更快捷的将程序集群化部署.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由于博主刚开始研究 K3s, 故本文可能会出现的问题包括但不限于&lt;strong&gt;各种低级错误&lt;/strong&gt;, &lt;strong&gt;十分不严谨的专业用语&lt;/strong&gt;, 还请各路大佬轻喷&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;搭建需求&lt;a href=&quot;#搭建需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;任意 Linux 发行版&lt;/li&gt;
&lt;li&gt;已安装 Docker &amp;amp;&amp;amp; Docker-compose&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;注意&lt;a href=&quot;#注意&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;安装 Harbor 会创建很多 Docker 容器, 请确保这些容器和您现有业务不产生冲突. 如果产生冲突, 建议在一个单独的虚拟机中安装
&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;/images/276-1.png&quot; alt=&quot;Harbor Containers&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Harbor Containers&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 安装 Harbor&lt;a href=&quot;#1-安装-harbor&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;1.1 下载安装程序&lt;a href=&quot;#11-下载安装程序&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;前往 &lt;a href=&quot;https://github.com/goharbor/harbor/releases&quot;&gt;Harbor GitHub Release Page&lt;/a&gt; 下载 Offline 版本的安装包&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;wget&lt;/span&gt;&lt;span&gt; https://github.com/goharbor/harbor/releases/download/v2.15.0/harbor-offline-installer-v2.15.0.tgz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;解压压缩包&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;tar&lt;/span&gt;&lt;span&gt; -xzvf&lt;/span&gt;&lt;span&gt; harbor-offline-installer-v2.15.0.tgz&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;1.2 修改配置文件&lt;a href=&quot;#12-修改配置文件&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入解压后的目录, 可以看到目录中存在 &lt;code&gt;harbor.yml.tmpl&lt;/code&gt;. 我们需要使用该模板创建配置文件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cp&lt;/span&gt;&lt;span&gt; harbor.yml.tmpl&lt;/span&gt;&lt;span&gt; harbor.yml&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;按照个人需求对该文件进行编辑, 这里对几个必要的键做了批注&lt;/li&gt;
&lt;/ul&gt;

































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Key&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;th&gt;Recommendation&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;hostname&lt;/code&gt;&lt;/td&gt;&lt;td&gt;本机 hostname, 这里不能设置为 &lt;code&gt;localhost&lt;/code&gt; 或 &lt;code&gt;127.0.0.1&lt;/code&gt;, 否则外部设备无法连接至该仓库&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;http&lt;/code&gt;-&amp;gt; &lt;code&gt;port&lt;/code&gt;&lt;/td&gt;&lt;td&gt;HTTP 服务器端口, 根据自己需求设置即可&lt;/td&gt;&lt;td&gt;80&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;https&lt;/code&gt; -&amp;gt; &lt;code&gt;port&lt;/code&gt;&lt;/td&gt;&lt;td&gt;HTTPS 服务器端口, 根据需求配置. 如果启用了 HTTPS, 将无法使用 HTTP 端口连接/登录后台. 这里推荐使用 Openresty 等反向代理工具来启用 TLS 加密, 而不是在这里启用&lt;/td&gt;&lt;td&gt;443&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;https&lt;/code&gt; -&amp;gt; &lt;code&gt;certificate&lt;/code&gt;&lt;/td&gt;&lt;td&gt;HTTPS 服务器证书路径, 建议设置为绝对路径&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;https&lt;/code&gt; -&amp;gt; &lt;code&gt;private_key&lt;/code&gt;&lt;/td&gt;&lt;td&gt;HTTPS 服务器私钥, 建议设置为绝对路径&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;external_url&lt;/code&gt;&lt;/td&gt;&lt;td&gt;如果该仓库对公网公开, 那么这里填写该仓库对应的公网地址 &lt;strong&gt;(注意: 如果需要使用 HTTP 登录后台, 请不要在此处使用 HTTPS)&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;harbor_admin_password&lt;/code&gt;&lt;/td&gt;&lt;td&gt;默认后台登录密码, 这里可以根据自己需求修改&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;database&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Harbor DB 的数据库相关配置, 除去 &lt;code&gt;password&lt;/code&gt; 以外均不建议修改&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;data_volume&lt;/code&gt;&lt;/td&gt;&lt;td&gt;所有 Harbor 数据的存储目录, 设置为绝对路径&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;log&lt;/code&gt; -&amp;gt; &lt;code&gt;location&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Harbor 产生的日志存储目录, 设置为绝对路径&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;proxy&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Harbor 代理相关设置. 如果您处于中国大陆地区, 建议配置代理服务器&lt;/td&gt;&lt;td&gt;-&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;配置修改完成后保存退出, 运行 &lt;code&gt;./install.sh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;如果脚本运行无报错, 则安装成功&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1.3 测试&lt;a href=&quot;#13-测试&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;浏览器进入 &lt;code&gt;http(s)://&amp;lt;IPAddr&amp;gt;:&amp;lt;Port&amp;gt;&lt;/code&gt;, 使用默认用户名 &lt;code&gt;admin&lt;/code&gt; 登录后台. 如果您看到如下页面, 则安装成功
&lt;figure&gt;&lt;img src=&quot;/images/276-2.png&quot; alt=&quot;Harbor&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Harbor&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您先前未修改默认用户密码, 则建议您立即修改&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此, Harbor 的安装就完成了&lt;/p&gt;
&lt;h3&gt;2. 上传 Docker 镜像&lt;a href=&quot;#2-上传-docker-镜像&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;2.1 新建项目&lt;a href=&quot;#21-新建项目&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;登录 Harbor, 进入管理面板&lt;/li&gt;
&lt;li&gt;点击 &lt;code&gt;+ New Project&lt;/code&gt;, 添加新项目. 在弹出的对话框内填入项目名称, 是否公开, 项目配额限制以及镜像代理&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 这里的 “项目” 并非指代单个程序的项目名称, 而是整个仓库分支的名称. 例如, 你可以将其设置为 &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;public&lt;/code&gt; 或 &lt;code&gt;release&lt;/code&gt; 等&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;2.2 创建 Docker 推送用户&lt;a href=&quot;#22-创建-docker-推送用户&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入管理面板的 &lt;code&gt;Administration (管理)&lt;/code&gt; —&amp;gt; &lt;code&gt;Users (用户)&lt;/code&gt; 页面, 单击 &lt;code&gt;+ NEW USER&lt;/code&gt;, 并填写新用户相关信息
&lt;figure&gt;&lt;img src=&quot;/images/276-3.png&quot; alt=&quot;Create new user&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Create new user&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2.3 上传 Docker 镜像&lt;a href=&quot;#23-上传-docker-镜像&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;在您的开发机上启动 Docker, 并 cd 进程序代码根目录&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;请确保您的程序拥有完整有效的 Dockerfile&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;运行以下指令编译当前项目&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;span&gt; -t&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;ProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;:v&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Versio&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; .&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ProjectName&lt;/code&gt; 项目名称&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Version&lt;/code&gt; 版本标签&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例: &lt;code&gt;docker build -t myapp:v1.0.0 .&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;将当前镜像打上仓库 Tag&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; tag&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;ProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Versio&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;DockerhubUR&lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;HarborProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;ProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Versio&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HarborProjectName&lt;/code&gt; 在 Harbor WebUI 内创建的项目名&lt;/li&gt;
&lt;li&gt;&lt;code&gt;DockerhubURL&lt;/code&gt; 您的私有镜像仓库 URL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例: &lt;code&gt;docker tag myapp:v1.0.0 myregistry.com/dev/myapp:v1.0.0&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;登录仓库并推送&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; login&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;DockerhubUR&lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;DockerhubUR&lt;/span&gt;&lt;span&gt;L&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;HarborProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;ProjectNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;:v&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Versio&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;示例&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; login&lt;/span&gt;&lt;span&gt; myregistry.com&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;docker&lt;/span&gt;&lt;span&gt; push&lt;/span&gt;&lt;span&gt; myregistry.com/dev/myapp:v1.0.0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 如果您配置了反向代理和 TLS 加密, 并在 &lt;code&gt;docker login&lt;/code&gt; 过程中遇到了 404 报错, 请将 &lt;code&gt;harbor.yml&lt;/code&gt; 中 &lt;code&gt;external_url&lt;/code&gt; 的协议改为 &lt;code&gt;https&lt;/code&gt;, 然后再次执行 &lt;code&gt;install.sh&lt;/code&gt; 脚本. 您不会丢失任何数据&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;当上传完成后, 您应当可以在管理面板中看到您上传的镜像
&lt;figure&gt;&lt;img src=&quot;/images/276-4.png&quot; alt=&quot;Projects&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Projects&lt;/figcaption&gt;&lt;/figure&gt;
至此, Docker 镜像的上传也完成了&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业相关从业人员, 如有错误或疏漏请指出! 如果觉得有用请分享给需要的人, 感谢阅读&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/269/&quot;&gt;K3s 专题 ep1: 搭建 Master 与 Worker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/281/&quot;&gt;K3s 专题 ep3: 快速部署 Docker 镜像&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:K3s</category></item><item><title>K3s 专题 ep1: 搭建 Master 与 Worker</title><link>https://blog.nanami.tech/en/archives/269</link><guid isPermaLink="false">en:269</guid><description>前言
由于项目的业务需要, 负载上来之后单个 Docker 容器撑不住, 遂决定开始研究 Kubernetes, 对容器进行一个集群化. 在询问 AI 相关建议后, AI 建议我从轻量级的 Kubernetes 发行版 K3s 入手. 于是这篇文章将会记录博主在 Proxmox VE 9.1.6</description><pubDate>Thu, 09 Apr 2026 03:22:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;由于项目的业务需要, 负载上来之后单个 Docker 容器撑不住, 遂决定开始研究 Kubernetes, 对容器进行一个集群化. 在询问 AI 相关建议后, AI 建议我从轻量级的 Kubernetes 发行版 &lt;code&gt;K3s&lt;/code&gt; 入手. 于是这篇文章将会记录博主在 Proxmox VE 9.1.6 服务器上从零开始搭建 K3s 节点.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;由于博主刚开始研究 K3s, 故本文可能会出现的问题包括但不限于&lt;strong&gt;各种低级错误&lt;/strong&gt;, &lt;strong&gt;十分不严谨的专业用语&lt;/strong&gt;, 还请各路大佬轻喷&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;最低搭建需求&lt;a href=&quot;#最低搭建需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;OS: &lt;code&gt;Proxmox VE&lt;/code&gt;, &lt;code&gt;VMware ESXi&lt;/code&gt; 等虚拟化系统&lt;/li&gt;
&lt;li&gt;CPU: 核心数 &amp;gt;= &lt;code&gt;8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Mem: &amp;gt;= &lt;code&gt;12GB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Storage: &amp;gt;= &lt;code&gt;50GB&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 创建 K3s 虚拟机模板&lt;a href=&quot;#1-创建-k3s-虚拟机模板&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;1.1 创建 &lt;code&gt;Cloud-Init&lt;/code&gt; 虚拟机&lt;a href=&quot;#11-创建-cloud-init-虚拟机&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入 &lt;a href=&quot;https://cloud.debian.org/images/cloud/&quot;&gt;Debian Official Cloud Images&lt;/a&gt; 下载 Debian 官方 Cloud-Init 镜像&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;这里推荐使用 &lt;a href=&quot;https://cloud.debian.org/images/cloud/trixie/latest/&quot;&gt;Debian 13 (trixie)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;根据需求和 CPU 架构选定发行版后, 登录服务器 SSH 进行下载&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;wget&lt;/span&gt;&lt;span&gt; https://cloud.debian.org/images/cloud/trixie/latest/debian-13-generic-amd64.qcow2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;下载完成后, 使用 qm 工具创建虚拟机&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMI&lt;/span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --name&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMNam&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --memory&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;VMMe&lt;/span&gt;&lt;span&gt;m&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --net0&lt;/span&gt;&lt;span&gt; virtio,bridge=&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;TargetBridg&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    --cores&lt;/span&gt;&lt;span&gt; &quot;&amp;lt;CPUCores&amp;gt;&quot;&lt;/span&gt;&lt;span&gt; --cpu&lt;/span&gt;&lt;span&gt; host&lt;/span&gt;&lt;span&gt; --ostype&lt;/span&gt;&lt;span&gt; l26&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    --scsihw&lt;/span&gt;&lt;span&gt; virtio-scsi-pci&lt;/span&gt;&lt;span&gt; --serial0&lt;/span&gt;&lt;span&gt; socket&lt;/span&gt;&lt;span&gt; --vga&lt;/span&gt;&lt;span&gt; serial0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;NewVMID&amp;gt;&lt;/code&gt; 模板虚拟机 ID&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;NewVMName&amp;gt;&lt;/code&gt; 模板虚拟机名称&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;VMMem&amp;gt;&lt;/code&gt; 模板虚拟机内存大小 (单位: MB)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;TargetBridge&amp;gt;&lt;/code&gt; 目标桥接网卡&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;CPUCores&amp;gt;&lt;/code&gt; 模板虚拟机分配的核心数量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;示例:&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; create&lt;/span&gt;&lt;span&gt; 300&lt;/span&gt;&lt;span&gt; --name&lt;/span&gt;&lt;span&gt; K3s-Templete&lt;/span&gt;&lt;span&gt; --memory&lt;/span&gt;&lt;span&gt; 2048&lt;/span&gt;&lt;span&gt; --net0&lt;/span&gt;&lt;span&gt; virtio,bridge=vmbr0&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    --cores&lt;/span&gt;&lt;span&gt; &quot;8&quot;&lt;/span&gt;&lt;span&gt; --cpu&lt;/span&gt;&lt;span&gt; host&lt;/span&gt;&lt;span&gt; --ostype&lt;/span&gt;&lt;span&gt; l26&lt;/span&gt;&lt;span&gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    --scsihw&lt;/span&gt;&lt;span&gt; virtio-scsi-pci&lt;/span&gt;&lt;span&gt; --serial0&lt;/span&gt;&lt;span&gt; socket&lt;/span&gt;&lt;span&gt; --vga&lt;/span&gt;&lt;span&gt; serial0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;将下载好的镜像导入该 VM&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; importdisk&lt;/span&gt;&lt;span&gt; $VM_ID &lt;/span&gt;&lt;span&gt;&quot;&amp;lt;/path/to/image.qcow2&amp;gt;&quot;&lt;/span&gt;&lt;span&gt; &quot;&amp;lt;StoragePool&amp;gt;&quot;&lt;/span&gt;&lt;span&gt; --format&lt;/span&gt;&lt;span&gt; qcow2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;/path/to/image.qcow2&amp;gt;&lt;/code&gt; 先前下载的 qcow2 镜像路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;StoragePool&amp;gt;&lt;/code&gt; 导入的目标存储池&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意记录导入后的卷 ID&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;挂载磁盘与 Cloud-Init 驱动器&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMI&lt;/span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --scsi0&lt;/span&gt;&lt;span&gt; &quot;&amp;lt;VolumeID&amp;gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;VolumeID&amp;gt;&lt;/code&gt; 先前导入的卷 ID&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;添加 Cloud-Init 驱动器&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMI&lt;/span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --ide2&lt;/span&gt;&lt;span&gt; &quot;&amp;lt;StoragePool&amp;gt;:cloudinit&quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;设置引导顺序与显示配置&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMI&lt;/span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --boot&lt;/span&gt;&lt;span&gt; order=scsi0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;配置基础 Cloud-Init 模板&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; &amp;lt;&lt;/span&gt;&lt;span&gt;NewVMI&lt;/span&gt;&lt;span&gt;D&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; --ipconfig0&lt;/span&gt;&lt;span&gt; ip=dhcp&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;如果到此为止都没有任何错误, 那么 Cloud-Init 虚拟机创建完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;1.2 基础虚拟机配置&lt;a href=&quot;#12-基础虚拟机配置&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;进入虚拟机 Cloud-Init 配置, 填写默认登录用户名与密码, SSH, 网络设置等等
&lt;figure&gt;&lt;img src=&quot;/images/269-1.png&quot; alt=&quot;Cloud-Init Config&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Cloud-Init Config&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;启动该虚拟机, 在 Proxmox VE 网页端选择 &lt;code&gt;xterm.js&lt;/code&gt; 终端
&lt;figure&gt;&lt;img src=&quot;/images/269-2.png&quot; alt=&quot;xterm.js&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;xterm.js&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;等待启动完成后登录, 先对虚拟机软件包进行换源&amp;amp;&amp;amp;更新&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;此处选择中科大源&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; sed&lt;/span&gt;&lt;span&gt; -i&lt;/span&gt;&lt;span&gt; &apos;s/deb.debian.org/mirrors.ustc.edu.cn/g&apos;&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/debian.sources&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; upgrade&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;注: 如果该指令无法换源, 您还可以手动换源&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mv&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/debian.sources&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/debian.sources.bak&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;vim&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/debian.sources&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;然后输入&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Types: deb&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;URIs: http://mirrors.ustc.edu.cn/debian&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Suites: trixie trixie-updates trixie-backports&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Components: main contrib non-free non-free-firmware&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Types: deb&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;URIs: http://mirrors.ustc.edu.cn/debian-security&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Suites: trixie-security&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Components: main contrib non-free non-free-firmware&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;执行完成后关闭虚拟机, 右键该虚拟机, 将其转换为模板
&lt;figure&gt;&lt;img src=&quot;/images/269-3.png&quot; alt=&quot;Convert to template&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Convert to template&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;转换完成后, K3s 虚拟机模板就创建完成了&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 搭建 K3s 虚拟机&lt;a href=&quot;#2-搭建-k3s-虚拟机&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;2.1 搭建 K3s Master&lt;a href=&quot;#21-搭建-k3s-master&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;右键刚刚创建好的模板, 选择 &lt;code&gt;Clone&lt;/code&gt;
&lt;figure&gt;&lt;img src=&quot;/images/269-4.png&quot; alt=&quot;Clone&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Clone&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;在新弹出的对话框中输入虚拟机基本信息, 然后将 Mode 改为 &lt;code&gt;Full Clone&lt;/code&gt;
&lt;figure&gt;&lt;img src=&quot;/images/269-5.png&quot; alt=&quot;Clone VM Template&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Clone VM Template&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;输入完成后单击 &lt;code&gt;Clone&lt;/code&gt;, 等待克隆完成
由于 Cloud-Init 磁盘默认大小为 3GB, 因此我们这里需要根据不同需求来增加磁盘大小&lt;/li&gt;
&lt;li&gt;进入虚拟机的 Hardware 选项卡, 找到 &lt;code&gt;Hard Disk (scsi0)&lt;/code&gt;, 选定并单击 &lt;code&gt;Disk Action&lt;/code&gt; —&amp;gt; &lt;code&gt;Resize&lt;/code&gt;. 在这里输入你想要 &lt;strong&gt;增加&lt;/strong&gt; 的磁盘空间.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;同时你可以根据你的需求来更改 CPU/内存 等配置, 这里给出一张表格供参考&lt;/p&gt;

























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;集群规模 (节点数)&lt;/th&gt;&lt;th&gt;推荐的 Master 节点配置 (vCPU/内存/磁盘)&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;0 -100&lt;/td&gt;&lt;td&gt;4 Cores / 8 GB / 50 GB SSD or up&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;100 - 300&lt;/td&gt;&lt;td&gt;8 Cores / 16 GB / 50 GB SSD or up&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;300 - 500&lt;/td&gt;&lt;td&gt;16 Cores / 32 GB / 100 GB SSD or up&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;500 - 1000&lt;/td&gt;&lt;td&gt;32 Cores / 64 GB / 100 GB SSD or up&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;更改完配置后, 启动虚拟机并打开终端, 安装 K3s Master 相关组件&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;# 使用官方脚本一键安装，并指定节点名为master&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; -sfL&lt;/span&gt;&lt;span&gt; https://get.k3s.io&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; INSTALL_K3S_EXEC&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;--node-name k3s-master&quot;&lt;/span&gt;&lt;span&gt; sh&lt;/span&gt;&lt;span&gt; -s&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 等待安装完成，检查服务状态&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; systemctl&lt;/span&gt;&lt;span&gt; status&lt;/span&gt;&lt;span&gt; k3s&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# 获取用于添加 Worker 节点 token&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; cat&lt;/span&gt;&lt;span&gt; /var/lib/rancher/k3s/server/node-token&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您启用了防火墙, 请务必确保 &lt;code&gt;6443/TCP&lt;/code&gt;, &lt;code&gt;8472/UDP&lt;/code&gt;, &lt;code&gt;10250/TCP&lt;/code&gt; 端口保持开放&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此, Master 节点配置完成&lt;/p&gt;
&lt;h4&gt;2.2 搭建 K3s Worker&lt;a href=&quot;#22-搭建-k3s-worker&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;再次 Clone 一份刚才创建好的模板, 修改配置信息并启动虚拟机, 进入控制台
&lt;figure&gt;&lt;img src=&quot;/images/269-6.png&quot; alt=&quot;Clone VM Template&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Clone VM Template&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;输入以下指令部署 K3s Worker&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;curl&lt;/span&gt;&lt;span&gt; -sfL&lt;/span&gt;&lt;span&gt; https://get.k3s.io&lt;/span&gt;&lt;span&gt; |&lt;/span&gt;&lt;span&gt; K3S_URL&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;https://&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;MasterIP&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;:6443&lt;/span&gt;&lt;span&gt; K3S_TOKEN&lt;/span&gt;&lt;span&gt;=&amp;lt;&lt;/span&gt;&lt;span&gt;MasterToken&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; INSTALL_K3S_EXEC&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;--node-name k3s-worker1&quot;&lt;/span&gt;&lt;span&gt; sh&lt;/span&gt;&lt;span&gt; -s&lt;/span&gt;&lt;span&gt; -&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;MasterIP&amp;gt;&lt;/code&gt; Master 虚拟机的 IP 地址&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;MasterToken&amp;gt;&lt;/code&gt; 先前安装时获取的 Token&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安装如果未报错, 则证明成功&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 验证&lt;a href=&quot;#3-验证&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;返回 Master 节点的控制台, 输入指令查看节点状态&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; nodes&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果节点状态为 &lt;code&gt;Ready&lt;/code&gt;, 则节点添加成功并且就绪&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;root@K3s-Master:~#&lt;/span&gt;&lt;span&gt; sudo&lt;/span&gt;&lt;span&gt; kubectl&lt;/span&gt;&lt;span&gt; get&lt;/span&gt;&lt;span&gt; nodes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;NAME&lt;/span&gt;&lt;span&gt;          STATUS&lt;/span&gt;&lt;span&gt;   ROLES&lt;/span&gt;&lt;span&gt;           AGE&lt;/span&gt;&lt;span&gt;   VERSION&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;k3s-master&lt;/span&gt;&lt;span&gt;    Ready&lt;/span&gt;&lt;span&gt;    control-plane&lt;/span&gt;&lt;span&gt;   20h&lt;/span&gt;&lt;span&gt;   v1.34.6+k3s1&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;k3s-worker1&lt;/span&gt;&lt;span&gt;   Ready&lt;/span&gt;&lt;span&gt;    &amp;lt;&lt;/span&gt;&lt;span&gt;non&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;          20h&lt;/span&gt;&lt;span&gt;   v1.34.6+k3s1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;至此, K3s 的 Master 与 Worker 均部署完成&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;后记&lt;a href=&quot;#后记&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;本人非专业 Kubernetes 运维, 如有错误和疏漏, 欢迎各位大佬指出. 如果觉得文章不错, 请分享给有需要的人. 感谢阅读.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/276/&quot;&gt;K3s 专题 ep2: 部署 Harbor 私有仓库&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/283/&quot;&gt;K3s 专题 ep4: 部署 Rancher 管理平台&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/263/&quot;&gt;物理机 P2V 全量迁移到 Proxmox VE&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:K3s</category></item><item><title>物理机 P2V 全量迁移到 Proxmox VE</title><link>https://blog.nanami.tech/en/archives/263</link><guid isPermaLink="false">en:263</guid><description>前言
博主家里现在有两条入网宽带, 如果只在一个系统上部署网络出口相关业务, 那么只能同时使用一条宽带的上行, 没法做到充分利用两条宽带的上行. 因此, 博主决定将自己的网络出入口子服务器也换成 Proxmox VE, 这样既能通过防火墙规则和负载均衡同时使用两条宽带的上行作为网络出口,</description><pubDate>Fri, 27 Mar 2026 14:35:00 GMT</pubDate><content:encoded>&lt;h2&gt;前言&lt;a href=&quot;#前言&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;博主家里现在有两条入网宽带, 如果只在一个系统上部署网络出口相关业务, 那么只能同时使用一条宽带的上行, 没法做到充分利用两条宽带的上行. 因此, 博主决定将自己的网络出入口子服务器也换成 Proxmox VE, 这样既能通过防火墙规则和负载均衡同时使用两条宽带的上行作为网络出口, 也可以更加方便的管理服务器. 但是, 如果想在迁移的同时, 不丢失原有服务器上安装的操作系统和环境, 该怎么操作呢? 本篇文章将会为你带来全量迁移的最佳方案&lt;/p&gt;
&lt;h2&gt;需求&lt;a href=&quot;#需求&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;移动存储器 &amp;gt;= 服务器系统盘数据区&lt;/li&gt;
&lt;li&gt;服务器硬盘 &amp;gt;= 64GB&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;开整&lt;a href=&quot;#开整&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;1. 全量备份硬盘数据&lt;a href=&quot;#1-全量备份硬盘数据&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在移动存储器上安装任意 Linux Live CD, 这里推荐使用 &lt;a href=&quot;https://www.system-rescue.org/Download/&quot;&gt;SystemRescue&lt;/a&gt;, 或者使用 &lt;a href=&quot;https://www.ventoy.net/cn/download.html&quot;&gt;Ventoy&lt;/a&gt; 将多个 ISO 整合&lt;/li&gt;
&lt;li&gt;进入 Live 环境后, 列出所有磁盘&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;lsblk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;找到你的移动存储器, 将其挂在至 &lt;code&gt;/mnt/usbdisk&lt;/code&gt; 目录&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /mnt/usbdisk&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mount&lt;/span&gt;&lt;span&gt; /dev/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;devic&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; /mnt/usbdisk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;dd&lt;/code&gt; 工具创建完整镜像&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;dd&lt;/span&gt;&lt;span&gt; if=/dev/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;devic&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; of=/mnt/usbdisk/backup.img&lt;/span&gt;&lt;span&gt; bs=1M&lt;/span&gt;&lt;span&gt; status=progress&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：此过程耗时较长 (约每 100GB 数据耗时 30-60 分钟), 注意防止服务器断电以免数据损坏&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;使用 &lt;code&gt;qemu-img&lt;/code&gt; 工具将镜像转换至 &lt;code&gt;qcow2&lt;/code&gt; 格式&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qemu-img&lt;/span&gt;&lt;span&gt; convert&lt;/span&gt;&lt;span&gt; -f&lt;/span&gt;&lt;span&gt; raw&lt;/span&gt;&lt;span&gt; -O&lt;/span&gt;&lt;span&gt; qcow2&lt;/span&gt;&lt;span&gt; -c&lt;/span&gt;&lt;span&gt; /mnt/usbdisk/backup.img&lt;/span&gt;&lt;span&gt; /mnt/usbdisk/backup.qcow2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意&lt;/strong&gt;：此过程耗时依旧较长, 注意防止服务器断电以免数据损坏&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;待转换完成后, 备份阶段结束&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 安装 Proxmox VE&lt;a href=&quot;#2-安装-proxmox-ve&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;这里我们采用手动安装的方式, 以免官方安装器使用非预期的磁盘数据格式&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;引用: &lt;a href=&quot;https://www.iyoroy.cn/archives/233/&quot;&gt;记一次手动安装 Proxmox VE, 配置多路 iSCSI 与 NAT 转发的经历 » 悠笙の开发日记&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;配置 &lt;code&gt;Hostname&lt;/code&gt;
Proxmox VE 要求为当前的主机名配置一个指向非回环地址的 Hosts:&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;The hostname of your machine must be resolvable to an IP address. This IP address must not be a loopback one like 127.0.0.1 but one that you and other hosts can connect to.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;例如, 我的服务器内网地址为 &lt;code&gt;192.168.1.5&lt;/code&gt;, 公网地址为 &lt;code&gt;112.32.***.***&lt;/code&gt;, 则 &lt;code&gt;/etc/hosts&lt;/code&gt; 配置文件应该如下:&lt;/p&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;127.0.0.1       NanamiWork-SubServer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;127.0.1.1       NanamiWork-SubServer.lan        NanamiWork-SubServer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;192.168.1.5     NanamiWork-SubServer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;112.32.***.***  NanamiWork-SubServer&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;# The following lines are desirable for IPv6 capable hosts&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;::1     NanamiWork-SubServer ip6-NanamiWork-SubServer ip6-loopback&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ff02::1 ip6-allnodes&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;ff02::2 ip6-allrouters&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;如果您不想让您的服务器可以在公网被直接访问, 也可以不添加公网信息&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安装 Proxmox VE 软件源&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Debian 13 使用了 &lt;code&gt;Deb822&lt;/code&gt; 格式, 因此直接参考 &lt;a href=&quot;https://mirrors.ustc.edu.cn/help/proxmox.html&quot;&gt;USTC 的 Proxmox 镜像站&lt;/a&gt; 即可:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cat&lt;/span&gt;&lt;span&gt; &amp;gt;&lt;/span&gt;&lt;span&gt; /etc/apt/sources.list.d/pve-no-subscription.sources&lt;/span&gt;&lt;span&gt; &amp;lt;&amp;lt;&lt;/span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Types: deb&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;URIs: https://mirrors.ustc.edu.cn/proxmox/debian/pve&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Suites: trixie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Components: pve-no-subscription&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;Signed-By: /usr/share/keyrings/proxmox-archive-keyring.gpg&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;EOF&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;将 keyring 安装至 &lt;code&gt;/usr/share/keyrings&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cd&lt;/span&gt;&lt;span&gt; /usr/share/keyrings&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;wget&lt;/span&gt;&lt;span&gt; https://www.iyoroy.cn/usr/uploads/2025/11/4102711242.zip&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; unzip&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;unzip&lt;/span&gt;&lt;span&gt; 4102711242.zip&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;rm&lt;/span&gt;&lt;span&gt; 4102711242.zip&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;更新软件包&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; update&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; upgrade&lt;/span&gt;&lt;span&gt; -y&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;安装 Proxmox VE 内核&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; proxmox-default-kernel&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;reboot&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;使用 &lt;code&gt;uname -a&lt;/code&gt; 查看系统信息, 如果内核版本以 &lt;code&gt;-pve&lt;/code&gt; 或类似结尾, 则安装成功&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安装 Proxmox VE 相关软件包&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; proxmox-ve&lt;/span&gt;&lt;span&gt; postfix&lt;/span&gt;&lt;span&gt; open-iscsi&lt;/span&gt;&lt;span&gt; chrony&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;配置过程中会需要设置 &lt;code&gt;postfix&lt;/code&gt; 邮件服务器, 官方解释:
如果您的网络中有邮件服务器, 则应将 postfix 配置为 &lt;code&gt;Satellite system&lt;/code&gt; . 然后, 您现有的邮件服务器将成为中继主机, 将 Proxmox VE 发送的电子邮件路由到其最终收件人. 如果您不知道在此处输入什么, 请仅选择 &lt;code&gt;Local only&lt;/code&gt; , 并保持系统 &lt;code&gt;hostname&lt;/code&gt; 不变.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;安装完成后应该可以使用 &lt;code&gt;https://&amp;lt;IP Addr&amp;gt;:8006&lt;/code&gt; 访问 WebUI. 如果成功访问, 则安装成功.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;用户名: &lt;code&gt;root&lt;/code&gt;, 密码: 您的 root 用户密码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;删除旧的 Debian 内核与 &lt;code&gt;os-prober&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; remove&lt;/span&gt;&lt;span&gt; linux-image-amd64&lt;/span&gt;&lt;span&gt; &apos;linux-image-6.1*&apos;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;update-grub&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;apt&lt;/span&gt;&lt;span&gt; remove&lt;/span&gt;&lt;span&gt; os-prober&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;移除 &lt;code&gt;os-prober&lt;/code&gt; 不是必须的, 但是官方建议这么做, 因为它可能会误将虚拟机的引导文件认成多系统的引导文件, 导致将不该加的一些东西加到引导列表中.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;至此, Proxmox VE 安装完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 创建虚拟桥接网卡&lt;a href=&quot;#3-创建虚拟桥接网卡&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;登录 Proxmox VE WebUI, 定位至 &lt;code&gt;Datacenter&lt;/code&gt; —&amp;gt; &lt;code&gt;&amp;lt;Hostname&amp;gt;&lt;/code&gt; —&amp;gt; &lt;code&gt;System&lt;/code&gt; —&amp;gt; &lt;code&gt;Network&lt;/code&gt; 选项卡
&lt;figure&gt;&lt;img src=&quot;/images/263-1.png&quot; alt=&quot;Network&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Network&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;单击 &lt;code&gt;Create&lt;/code&gt;, 选择 &lt;code&gt;Linux Bridge&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在弹出的对话框中输入你需要的 &lt;code&gt;Name&lt;/code&gt;, 然后在 &lt;code&gt;Bridge ports&lt;/code&gt; 中输入该虚拟网卡桥接的物理网卡&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注意:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;如果你想将该物理网卡作为 Debian 物理机系统的接入网卡, 则你需要在该对话框中配置 &lt;code&gt;IPv4/CIDR&lt;/code&gt;, &lt;code&gt;Gateway(IPv4)&lt;/code&gt;, &lt;code&gt;IPv6/CIDR&lt;/code&gt;(可选), &lt;code&gt;Gateway(IPv6)&lt;/code&gt;(可选)
&lt;figure&gt;&lt;img src=&quot;/images/263-2.png&quot; alt=&quot;Example&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;Example&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一定不要在物理网卡上配置服务器的固定 IP 地址, 否则可能会导致虚拟机无法联网等一系列问题!!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;单击 &lt;code&gt;OK&lt;/code&gt; 创建网卡&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 恢复原始服务器系统&lt;a href=&quot;#4-恢复原始服务器系统&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;h4&gt;4.1 创建虚拟机&lt;a href=&quot;#41-创建虚拟机&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;登录 Proxmox VE WebUI, 单击右上角 &lt;code&gt;Create VM&lt;/code&gt;, 按照需求配置虚拟机名称, 是否开机启动等, 随后点击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;OS&lt;/code&gt; 选项卡, 选择 &lt;code&gt;Do not use any media&lt;/code&gt;, 然后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;System&lt;/code&gt; 选项卡, 启用 &lt;code&gt;Qemu Agent&lt;/code&gt;, 按照需求选择是否将 BIOS 改为 &lt;code&gt;OVMF (UEFI)&lt;/code&gt;, 然后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Disks&lt;/code&gt; 选项卡, 单击左侧 &lt;code&gt;scsi0&lt;/code&gt; 右边的垃圾桶图标, 删除默认创建的磁盘, 然后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;CPU&lt;/code&gt; 选项卡, 将 &lt;code&gt;Type&lt;/code&gt; 改为 &lt;code&gt;host&lt;/code&gt;, 然后根据需求分配核心数 (&lt;code&gt;Cores&lt;/code&gt;). 如果核心数较多, 可以启用 &lt;code&gt;NUMA&lt;/code&gt;, 配置完成后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;Memory&lt;/code&gt; 选项卡, 根据需求分配内存, 然后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 内存分配不应超过物理内存的 &lt;strong&gt;80%&lt;/strong&gt;, 否则会有内存溢出的风险&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;Network&lt;/code&gt; 选项卡, 根据需求选择刚刚创建的虚拟网卡, 然后单击 &lt;code&gt;Next&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 如果您的原始系统为 Windows, 您可能需要将网卡型号变更为 &lt;code&gt;Intel E1000&lt;/code&gt; 或 &lt;code&gt;Intel E1000E&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;到了最后的 &lt;code&gt;Confirm&lt;/code&gt; 选项卡, 确认配置无误后直接创建. 等待底部 &lt;code&gt;Tasks&lt;/code&gt; 中的 &lt;code&gt;VM 100 - Create&lt;/code&gt; 的状态变为 &lt;code&gt;OK&lt;/code&gt; 后, 虚拟机创建完成&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;4.2 恢复原始物理机磁盘镜像&lt;a href=&quot;#42-恢复原始物理机磁盘镜像&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;登录服务器 SSH, 使用该命令列出所有磁盘&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;lsblk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;找到你的移动存储器, 并将其挂载到 &lt;code&gt;/mnt/usbdisk&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;mkdir&lt;/span&gt;&lt;span&gt; /mnt/usbdisk&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;mount&lt;/span&gt;&lt;span&gt; /dev/&lt;/span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;devic&lt;/span&gt;&lt;span&gt;e&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;span&gt; /mnt/usbdisk&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;将先前创建的 &lt;code&gt;qcow2&lt;/code&gt; 镜像文件复制到服务器&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;cp&lt;/span&gt;&lt;span&gt; /mnt/usbdisk/backup.qcow2&lt;/span&gt;&lt;span&gt; /var/lib/vz/images/100/vm-100-disk-1.qcow2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;注意: 此过程持续时间可能较长, 请保证服务器不断电, 以免造成数据损坏&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;复制完成后, 使用该命令将磁盘导入至对应虚拟机中&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt; --scsi0&lt;/span&gt;&lt;span&gt; /var/lib/vz/images/100/vm-100-disk-1.qcow2&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;使用该命令设置启动顺序&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;qm&lt;/span&gt;&lt;span&gt; set&lt;/span&gt;&lt;span&gt; 100&lt;/span&gt;&lt;span&gt; --boot&lt;/span&gt;&lt;span&gt; order=scsi0&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;执行完成后在 WebUI 中选中对应的虚拟机并启动该虚拟机&lt;/li&gt;
&lt;li&gt;如果虚拟机正常启动到了宿主机之前的系统, 则恢复完成!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. 安装 &lt;code&gt;Qemu-Agent&lt;/code&gt;&lt;a href=&quot;#5-安装-qemu-agent&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;登录虚拟机 SSH, 安装 &lt;code&gt;qemu-agemt&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; apt&lt;/span&gt;&lt;span&gt; install&lt;/span&gt;&lt;span&gt; qemu-guest-agent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;启动并配置开机启动&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;&lt;div&gt;&lt;/div&gt;&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; systemctl&lt;/span&gt;&lt;span&gt; enable&lt;/span&gt;&lt;span&gt; qemu-guest-agent&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;sudo&lt;/span&gt;&lt;span&gt; systemctl&lt;/span&gt;&lt;span&gt; start&lt;/span&gt;&lt;span&gt; qemu-guest-agent&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;返回 WebUI 虚拟机的 Summary 页面, 如果看到正确显示了 IP 地址, 则安装成功
&lt;figure&gt;&lt;img src=&quot;/images/263-3.png&quot; alt=&quot;IPs&quot; loading=&quot;lazy&quot; /&gt;&lt;figcaption&gt;IPs&lt;/figcaption&gt;&lt;/figure&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至此, 整个 P2V 迁移就结束了&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;结语&lt;a href=&quot;#结语&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;本人非专业 Linux 运维, 如有错误或疏漏, 请直接指出, 谢谢!&lt;/li&gt;
&lt;li&gt;如果觉得该文章有帮助, 请将其分享给身边有需要的人, 感谢!&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;相关阅读&lt;a href=&quot;#相关阅读&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/200/&quot;&gt;Proxmox VE 共享存储: VirtIO-FS 配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/21/&quot;&gt;Hyper-V 虚拟机桥接网络配置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.nanami.tech/archives/269/&quot;&gt;K3s 专题 ep1: 搭建 Master 与 Worker&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded><category>category:虚拟化</category><category>tag:运维</category></item></channel></rss>